diff options
author | Alexei Podtelezhnikov <apodtele@gmail.com> | 2021-11-25 22:38:40 -0500 |
---|---|---|
committer | Alexei Podtelezhnikov <apodtele@gmail.com> | 2021-11-25 22:38:40 -0500 |
commit | 32f13c11a4edb2c22d5fad5dca7eb9bcdf2bcdad (patch) | |
tree | ea1842eac2d94eae04e9579a7ecc969a3e4fe0b6 /src | |
parent | cff026d41599945498044d2f4dcc0e610ffb6929 (diff) | |
download | freetype2-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.
Diffstat (limited to 'src')
-rw-r--r-- | src/truetype/ttpload.c | 26 |
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; |