freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] master 32f13c1: [truetype] Quietly reject out-of-spec `hdmx`


From: Werner Lemberg
Subject: [freetype2] master 32f13c1: [truetype] Quietly reject out-of-spec `hdmx` tables.
Date: Thu, 25 Nov 2021 22:51:50 -0500 (EST)

branch: master
commit 32f13c11a4edb2c22d5fad5dca7eb9bcdf2bcdad
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>

    [truetype] Quietly reject out-of-spec `hdmx` tables.
    
    The `hdmx` table is optional and can be safely rejected without
    an error if it does not follow specifications. The record size
    must be equal to the number of glyphs + 2 + 32-bit padding.
    
    * src/truetype/ttpload.c (tt_face_load_hdmx): Thoroughly check
    the record size and improve tracing.
---
 src/truetype/ttpload.c | 26 +++++++++++++++-----------
 1 file changed, 15 insertions(+), 11 deletions(-)

diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index 55a2238..c1ce0d6 100644
--- a/src/truetype/ttpload.c
+++ b/src/truetype/ttpload.c
@@ -547,12 +547,6 @@
     num_records = FT_NEXT_USHORT( p );
     record_size = FT_NEXT_ULONG( p );
 
-    /* The maximum number of bytes in an hdmx device record is the */
-    /* maximum number of glyphs + 2 + 32-bit padding, or 0x10004,  */
-    /* that is why `record_size' is a long (which we read as       */
-    /* unsigned long for convenience).  In practice, two bytes are */
-    /* sufficient to hold the size value.                          */
-    /*                                                             */
     /* There are at least two fonts, HANNOM-A and HANNOM-B version */
     /* 2.0 (2005), which get this wrong: The upper two bytes of    */
     /* the size value are set to 0xFF instead of 0x00.  We catch   */
@@ -561,13 +555,21 @@
     if ( record_size >= 0xFFFF0000UL )
       record_size &= 0xFFFFU;
 
+    FT_TRACE2(( "Hdmx ", num_records, record_size ));
+
     /* The limit for `num_records' is a heuristic value. */
-    if ( num_records > 255               ||
-         ( num_records > 0             &&
-           ( record_size > 0x10004UL ||
-             record_size < 4         ) ) )
+    if ( num_records > 255 || num_records == 0 )
+    {
+      FT_TRACE2(( "with unreasonable %u records rejected\n", num_records ));
+      goto Fail;
+    }
+
+    /* Out-of-spec tables are rejected. */
+    if ( (FT_Long)record_size != ( ( face->root.num_glyphs + 5 ) & ~3 ) )
     {
-      error = FT_THROW( Invalid_File_Format );
+      FT_TRACE2(( "with record size off by %ld bytes rejected\n",
+                   (FT_Long)record_size -
+                     ( ( face->root.num_glyphs + 5 ) & ~3 ) ));
       goto Fail;
     }
 
@@ -587,6 +589,8 @@
     face->hdmx_table_size   = table_size;
     face->hdmx_record_size  = record_size;
 
+    FT_TRACE2(( "%ux%lu loaded\n", num_records, record_size ));
+
   Exit:
     return error;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]