summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexei Podtelezhnikov <apodtele@gmail.com>2021-11-25 22:38:40 -0500
committerAlexei Podtelezhnikov <apodtele@gmail.com>2021-11-25 22:38:40 -0500
commit32f13c11a4edb2c22d5fad5dca7eb9bcdf2bcdad (patch)
treeea1842eac2d94eae04e9579a7ecc969a3e4fe0b6
parentcff026d41599945498044d2f4dcc0e610ffb6929 (diff)
downloadfreetype2-32f13c11a4edb2c22d5fad5dca7eb9bcdf2bcdad.tar.gz
[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.
-rw-r--r--src/truetype/ttpload.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/src/truetype/ttpload.c b/src/truetype/ttpload.c
index 55a2238fd..c1ce0d634 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;