QFontEngine: fix GCC 12 -Werror=array-bounds

Says GCC 12 with -sanitize address -sanitize undefined:

    qfontengine.cpp: In member function ‘bool QFontEngine::processHheaTable() const’:
    qfontengine.cpp:386:65: error: array subscript 4 is outside array bounds of ‘const char [1]’ [-Werror=array-bounds]
      386 |         qint16 ascent = qFromBigEndian<qint16>(hhea.constData() + 4);
          |                                                ~~~~~~~~~~~~~~~~~^~~
    qbytearray.h:56:23: note: at offset 4 into object ‘QByteArray::_empty’ of size 1
       56 |     static const char _empty;
          |                       ^~~~~~

(repeats several times)

The compiler apparently assumes that data() and size() are independent
of each other, and so finds that that constData() may return &_empty,
which is a const char[1].

For some reason, storing the result of constData() in a temporary and
indexing off of that fixes the issue.

Potentially adding Q_ASSUME(d.data()[d.size] == '\0'); in some
strategic place would fix it, too, but would incur runtime overhead.

See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105348

Task-number: QTBUG-103923
Change-Id: Ia6e24e01d1c2a6bd9d91d4d082df9fba0d5c668f
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
Reviewed-by: Konstantin Ritt <ritt.ks@gmail.com>
(cherry picked from commit 7908b0cea6116f7ba4aaa1b86b7c3a15510ffd49)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
Marc Mutz 2022-05-31 17:41:32 +02:00 committed by Qt Cherry-pick Bot
parent 6c95114b6d
commit 9494d8d441

View File

@ -432,9 +432,10 @@ bool QFontEngine::processHheaTable() const
{
QByteArray hhea = getSfntTable(MAKE_TAG('h', 'h', 'e', 'a'));
if (hhea.size() >= 10) {
qint16 ascent = qFromBigEndian<qint16>(hhea.constData() + 4);
qint16 descent = qFromBigEndian<qint16>(hhea.constData() + 6);
qint16 leading = qFromBigEndian<qint16>(hhea.constData() + 8);
auto ptr = hhea.constData();
qint16 ascent = qFromBigEndian<qint16>(ptr + 4);
qint16 descent = qFromBigEndian<qint16>(ptr + 6);
qint16 leading = qFromBigEndian<qint16>(ptr + 8);
// Some fonts may have invalid HHEA data. We detect this and bail out.
if (ascent == 0 && descent == 0)
@ -473,12 +474,13 @@ bool QFontEngine::processOS2Table() const
{
QByteArray os2 = getSfntTable(MAKE_TAG('O', 'S', '/', '2'));
if (os2.size() >= 78) {
quint16 fsSelection = qFromBigEndian<quint16>(os2.constData() + 62);
qint16 typoAscent = qFromBigEndian<qint16>(os2.constData() + 68);
qint16 typoDescent = qFromBigEndian<qint16>(os2.constData() + 70);
qint16 typoLineGap = qFromBigEndian<qint16>(os2.constData() + 72);
quint16 winAscent = qFromBigEndian<quint16>(os2.constData() + 74);
quint16 winDescent = qFromBigEndian<quint16>(os2.constData() + 76);
auto ptr = os2.constData();
quint16 fsSelection = qFromBigEndian<quint16>(ptr + 62);
qint16 typoAscent = qFromBigEndian<qint16>(ptr + 68);
qint16 typoDescent = qFromBigEndian<qint16>(ptr + 70);
qint16 typoLineGap = qFromBigEndian<qint16>(ptr + 72);
quint16 winAscent = qFromBigEndian<quint16>(ptr + 74);
quint16 winDescent = qFromBigEndian<quint16>(ptr + 76);
enum { USE_TYPO_METRICS = 0x80 };
QFixed unitsPerEm = emSquareSize();