diff --git a/src/gui/text/windows/qwindowsfontdatabase.cpp b/src/gui/text/windows/qwindowsfontdatabase.cpp
index 44cc7fe63e..e44d85a3cb 100644
--- a/src/gui/text/windows/qwindowsfontdatabase.cpp
+++ b/src/gui/text/windows/qwindowsfontdatabase.cpp
@@ -873,36 +873,70 @@ QT_WARNING_POP
     return fontEngine;
 }
 
-static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData)
+static QList<quint32> getTrueTypeFontOffsets(const uchar *fontData, const uchar *fileEndSentinel)
 {
     QList<quint32> offsets;
-    const quint32 headerTag = *reinterpret_cast<const quint32 *>(fontData);
+    if (fileEndSentinel - fontData < 12) {
+        qCWarning(lcQpaFonts) << "Corrupted font data detected";
+        return offsets;
+    }
+
+    const quint32 headerTag = qFromUnaligned<quint32>(fontData);
     if (headerTag != MAKE_TAG('t', 't', 'c', 'f')) {
         if (headerTag != MAKE_TAG(0, 1, 0, 0)
             && headerTag != MAKE_TAG('O', 'T', 'T', 'O')
             && headerTag != MAKE_TAG('t', 'r', 'u', 'e')
-            && headerTag != MAKE_TAG('t', 'y', 'p', '1'))
+            && headerTag != MAKE_TAG('t', 'y', 'p', '1')) {
             return offsets;
+        }
         offsets << 0;
         return offsets;
     }
+
+    const quint32 maximumNumFonts = 0xffff;
     const quint32 numFonts = qFromBigEndian<quint32>(fontData + 8);
-    for (uint i = 0; i < numFonts; ++i) {
-        offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
+    if (numFonts > maximumNumFonts) {
+        qCWarning(lcQpaFonts) << "Font collection of" << numFonts << "fonts is too large. Aborting.";
+        return offsets;
+    }
+
+    if (quintptr(fileEndSentinel - fontData) > 12 + (numFonts - 1) * 4) {
+        for (quint32 i = 0; i < numFonts; ++i)
+            offsets << qFromBigEndian<quint32>(fontData + 12 + i * 4);
+    } else {
+        qCWarning(lcQpaFonts) << "Corrupted font data detected";
     }
+
     return offsets;
 }
 
-static void getFontTable(const uchar *fileBegin, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
+static void getFontTable(const uchar *fileBegin, const uchar *fileEndSentinel, const uchar *data, quint32 tag, const uchar **table, quint32 *length)
 {
-    const quint16 numTables = qFromBigEndian<quint16>(data + 4);
-    for (uint i = 0; i < numTables; ++i) {
-        const quint32 offset = 12 + 16 * i;
-        if (*reinterpret_cast<const quint32 *>(data + offset) == tag) {
-            *table = fileBegin + qFromBigEndian<quint32>(data + offset + 8);
-            *length = qFromBigEndian<quint32>(data + offset + 12);
-            return;
+    if (fileEndSentinel - data >= 6) {
+        const quint16 numTables = qFromBigEndian<quint16>(data + 4);
+        if (fileEndSentinel - data >= 28 + 16 * (numTables - 1)) {
+            for (quint32 i = 0; i < numTables; ++i) {
+                const quint32 offset = 12 + 16 * i;
+                if (qFromUnaligned<quint32>(data + offset) == tag) {
+                    const quint32 tableOffset = qFromBigEndian<quint32>(data + offset + 8);
+                    if (quintptr(fileEndSentinel - fileBegin) <= tableOffset) {
+                        qCWarning(lcQpaFonts) << "Corrupted font data detected";
+                        break;
+                    }
+                    *table = fileBegin + tableOffset;
+                    *length = qFromBigEndian<quint32>(data + offset + 12);
+                    if (quintptr(fileEndSentinel - *table) < *length) {
+                        qCWarning(lcQpaFonts) << "Corrupted font data detected";
+                        break;
+                    }
+                    return;
+                }
+            }
+        } else {
+            qCWarning(lcQpaFonts) << "Corrupted font data detected";
         }
+    } else {
+        qCWarning(lcQpaFonts) << "Corrupted font data detected";
     }
     *table = 0;
     *length = 0;
@@ -915,8 +949,9 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
                                      QList<QFontValues> *values)
 {
     const uchar *data = reinterpret_cast<const uchar *>(fontData.constData());
+    const uchar *dataEndSentinel = data + fontData.size();
 
-    QList<quint32> offsets = getTrueTypeFontOffsets(data);
+    QList<quint32> offsets = getTrueTypeFontOffsets(data, dataEndSentinel);
     if (offsets.isEmpty())
         return;
 
@@ -924,7 +959,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
         const uchar *font = data + offsets.at(i);
         const uchar *table;
         quint32 length;
-        getFontTable(data, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
+        getFontTable(data, dataEndSentinel, font, MAKE_TAG('n', 'a', 'm', 'e'), &table, &length);
         if (!table)
             continue;
         QFontNames names = qt_getCanonicalFontNames(table, length);
@@ -934,7 +969,7 @@ static void getFamiliesAndSignatures(const QByteArray &fontData,
         families->append(std::move(names));
 
         if (values || signatures)
-            getFontTable(data, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
+            getFontTable(data, dataEndSentinel, font, MAKE_TAG('O', 'S', '/', '2'), &table, &length);
 
         if (values) {
             QFontValues fontValues;
-- 
2.27.0.windows.1

