vcl/inc/font/TTFReader.hxx |   21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

New commits:
commit 0b62b122cfed6b864f9dd613bd238474ad99dafe
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Tue May 27 13:05:02 2025 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue May 27 17:13:01 2025 +0200

    sanity check NameRecords
    
    may also fix cid#1646781 Untrusted loop bound
    
    Change-Id: I3ddb44de3ba45a3654400014bf19a4b202a68325
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/185909
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Tested-by: Jenkins

diff --git a/vcl/inc/font/TTFReader.hxx b/vcl/inc/font/TTFReader.hxx
index 67973290b2bd..3caae10ce13e 100644
--- a/vcl/inc/font/TTFReader.hxx
+++ b/vcl/inc/font/TTFReader.hxx
@@ -25,6 +25,7 @@ private:
     const TableDirectoryEntry* mpTableDirectoryEntry;
     const char* mpNameTablePointer;
     const NameTable* mpNameTable;
+    sal_uInt16 mnNumberOfRecords;
 
     const char* getTablePointer(const TableDirectoryEntry* pEntry, size_t 
nEntrySize)
     {
@@ -49,7 +50,25 @@ public:
         , mpTableDirectoryEntry(pTableDirectoryEntry)
         , mpNameTablePointer(getTablePointer(mpTableDirectoryEntry, 
sizeof(NameTable)))
         , mpNameTable(reinterpret_cast<const NameTable*>(mpNameTablePointer))
+        , mnNumberOfRecords(0)
     {
+        if (mpNameTable)
+        {
+            mnNumberOfRecords = mpNameTable->nCount;
+
+            const char* pEnd = mrFontDataContainer.getPointer() + 
mrFontDataContainer.size();
+            const char* pStart = mpNameTablePointer + sizeof(NameTable);
+            size_t nAvailableData = pEnd - pStart;
+            size_t nMaxRecordsPossible = nAvailableData / sizeof(NameRecord);
+            if (mnNumberOfRecords > nMaxRecordsPossible)
+            {
+                SAL_WARN("vcl.fonts", "Font claimed to have "
+                                          << mnNumberOfRecords
+                                          << " name records, but only space 
for "
+                                          << nMaxRecordsPossible);
+                mnNumberOfRecords = nMaxRecordsPossible;
+            }
+        }
     }
 
     sal_uInt32 getTableOffset() { return mpTableDirectoryEntry->offset; }
@@ -57,7 +76,7 @@ public:
     const NameTable* getNameTable() { return mpNameTable; }
 
     /** Number of tables */
-    sal_uInt16 getNumberOfRecords() { return mpNameTable ? mpNameTable->nCount 
: 0; }
+    sal_uInt16 getNumberOfRecords() { return mnNumberOfRecords; }
 
     /** Get a name table record for index */
     const NameRecord* getNameRecord(sal_uInt32 index)

Reply via email to