|
| 1 | +diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp |
| 2 | +index 44cc7fe63e..e44d85a3cb 100644 |
| 3 | +--- a/src/gui/text/windows/qwindowsfontdatabase.cpp |
| 4 | ++++ b/src/gui/text/windows/qwindowsfontdatabase.cpp |
| 5 | +@@ -873,36 +873,70 @@ QT_WARNING_POP |
| 6 | + return fontEngine; |
| 7 | + } |
| 8 | + |
| 9 | +-static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData) |
| 10 | ++static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData, const uchar *fileEndSentinel) |
| 11 | + { |
| 12 | + QList<quint32> offsets; |
| 13 | +- const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData); |
| 14 | ++ if (fileEndSentinel - fontData < 12) { |
| 15 | ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; |
| 16 | ++ return offsets; |
| 17 | ++ } |
| 18 | ++ |
| 19 | ++ const quint32 headerTag = qFromUnaligned<quint32>(fontData); |
| 20 | + if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) { |
| 21 | + if (headerTag != MAKE_TAG(0, 1, 0, 0) |
| 22 | + && headerTag != MAKE_TAG('O', 'T', 'T', 'O') |
| 23 | + && headerTag != MAKE_TAG('t', 'r', 'u', 'e') |
| 24 | +- && headerTag != MAKE_TAG('t', 'y', 'p', '1')) |
| 25 | ++ && headerTag != MAKE_TAG('t', 'y', 'p', '1')) { |
| 26 | + return offsets; |
| 27 | ++ } |
| 28 | + offsets << 0; |
| 29 | + return offsets; |
| 30 | + } |
| 31 | ++ |
| 32 | ++ const quint32 maximumNumFonts = 0xffff; |
| 33 | + const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8); |
| 34 | +- for (uint i = 0; i < numFonts; ++i) { |
| 35 | +- offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4); |
| 36 | ++ if (numFonts > maximumNumFonts) { |
| 37 | ++ qCWarning(lcQpaFonts) << "Font collection of" << numFonts << "fonts is too large. Aborting."; |
| 38 | ++ return offsets; |
| 39 | ++ } |
| 40 | ++ |
| 41 | ++ if (quintptr(fileEndSentinel - fontData) > 12 + (numFonts - 1) * 4) { |
| 42 | ++ for (quint32 i = 0; i < numFonts; ++i) |
| 43 | ++ offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4); |
| 44 | ++ } else { |
| 45 | ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; |
| 46 | + } |
| 47 | ++ |
| 48 | + return offsets; |
| 49 | + } |
| 50 | + |
| 51 | +-static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length) |
| 52 | ++static void getFontTable(const uchar *fileBegin, const uchar *fileEndSentinel, const uchar *data, quint32 tag, const uchar **table, quint32 *length) |
| 53 | + { |
| 54 | +- const quint16 numTables = qFromBigEndian<quint16>(data + 4); |
| 55 | +- for (uint i = 0; i < numTables; ++i) { |
| 56 | +- const quint32 offset = 12 + 16 * i; |
| 57 | +- if (*reinterpret_cast<const quint32 *>(data + offset) == tag) { |
| 58 | +- *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8); |
| 59 | +- *length = qFromBigEndian<quint32>(data + offset + 12); |
| 60 | +- return; |
| 61 | ++ if (fileEndSentinel - data >= 6) { |
| 62 | ++ const quint16 numTables = qFromBigEndian<quint16>(data + 4); |
| 63 | ++ if (fileEndSentinel - data >= 28 + 16 * (numTables - 1)) { |
| 64 | ++ for (quint32 i = 0; i < numTables; ++i) { |
| 65 | ++ const quint32 offset = 12 + 16 * i; |
| 66 | ++ if (qFromUnaligned<quint32>(data + offset) == tag) { |
| 67 | ++ const quint32 tableOffset = qFromBigEndian<quint32>(data + offset + 8); |
| 68 | ++ if (quintptr(fileEndSentinel - fileBegin) <= tableOffset) { |
| 69 | ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; |
| 70 | ++ break; |
| 71 | ++ } |
| 72 | ++ *table = fileBegin + tableOffset; |
| 73 | ++ *length = qFromBigEndian<quint32>(data + offset + 12); |
| 74 | ++ if (quintptr(fileEndSentinel - *table) < *length) { |
| 75 | ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; |
| 76 | ++ break; |
| 77 | ++ } |
| 78 | ++ return; |
| 79 | ++ } |
| 80 | ++ } |
| 81 | ++ } else { |
| 82 | ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; |
| 83 | + } |
| 84 | ++ } else { |
| 85 | ++ qCWarning(lcQpaFonts) << "Corrupted font data detected"; |
| 86 | + } |
| 87 | + *table = 0; |
| 88 | + *length = 0; |
| 89 | +@@ -915,8 +949,9 @@ static void getFamiliesAndSignatures(const QByteArray &fontData, |
| 90 | + QList<QFontValues> *values) |
| 91 | + { |
| 92 | + const uchar *data = reinterpret_cast<const uchar *>(fontData.constData()); |
| 93 | ++ const uchar *dataEndSentinel = data + fontData.size(); |
| 94 | + |
| 95 | +- QList<quint32> offsets = getTrueTypeFontOffsets(data); |
| 96 | ++ QList<quint32> offsets = getTrueTypeFontOffsets(data, dataEndSentinel); |
| 97 | + if (offsets.isEmpty()) |
| 98 | + return; |
| 99 | + |
| 100 | +@@ -924,7 +959,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData, |
| 101 | + const uchar *font = data + offsets.at(i); |
| 102 | + const uchar *table; |
| 103 | + quint32 length; |
| 104 | +- getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length); |
| 105 | ++ getFontTable(data, dataEndSentinel, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length); |
| 106 | + if (!table) |
| 107 | + continue; |
| 108 | + QFontNames names = qt_getCanonicalFontNames(table, length); |
| 109 | +@@ -934,7 +969,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData, |
| 110 | + families->append(std::move(names)); |
| 111 | + |
| 112 | + if (values || signatures) |
| 113 | +- getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); |
| 114 | ++ getFontTable(data, dataEndSentinel, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length); |
| 115 | + |
| 116 | + if (values) { |
| 117 | + QFontValues fontValues; |
| 118 | +-- |
| 119 | +2.27.0.windows.1 |
0 commit comments