From 3f28a6b6afed06a7eeaeefb7e319e6c23bdd3eb8 Mon Sep 17 00:00:00 2001 From: Alexei Podtelezhnikov Date: Fri, 3 May 2024 15:44:57 +0000 Subject: [PATCH] [woff,woff2] Limit the number of tables and use FT_MSB. The upper limit of 4095 is implied by the SFNT header format where the multiplication by 16 would overflow without it. * src/sfnt/sfwoff.c (woff_open_font): Updated. * src/sfnt/sfwoff2.c (woff2_open_font): Ditto. --- src/sfnt/sfwoff.c | 18 +++++------------- src/sfnt/sfwoff2.c | 21 +++++++-------------- 2 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/sfnt/sfwoff.c b/src/sfnt/sfwoff.c index 8d33b7133..14514bf95 100644 --- a/src/sfnt/sfwoff.c +++ b/src/sfnt/sfwoff.c @@ -18,6 +18,7 @@ #include "sfwoff.h" #include +#include #include #include #include @@ -149,6 +150,7 @@ /* Miscellaneous checks. */ if ( woff.length != stream->size || woff.num_tables == 0 || + woff.num_tables > 0xFFFU || 44 + woff.num_tables * 20UL >= woff.length || 12 + woff.num_tables * 16UL >= woff.totalSfntSize || ( woff.totalSfntSize & 3 ) != 0 || @@ -169,21 +171,11 @@ /* Write sfnt header. */ { - FT_UInt searchRange, entrySelector, rangeShift, x; + FT_Int entrySelector = FT_MSB( woff.num_tables ); + FT_Int searchRange = ( 1 << entrySelector ) * 16; + FT_Int rangeShift = woff.num_tables * 16 - searchRange; - x = woff.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = woff.num_tables * 16 - searchRange; - WRITE_ULONG ( sfnt_header, woff.flavor ); WRITE_USHORT( sfnt_header, woff.num_tables ); WRITE_USHORT( sfnt_header, searchRange ); diff --git a/src/sfnt/sfwoff2.c b/src/sfnt/sfwoff2.c index 0e272fc99..bc7a55d79 100644 --- a/src/sfnt/sfwoff2.c +++ b/src/sfnt/sfwoff2.c @@ -18,6 +18,7 @@ #include "sfwoff2.h" #include "woff2tags.h" #include +#include #include #include @@ -1844,6 +1845,7 @@ /* Miscellaneous checks. */ if ( woff2.length != stream->size || woff2.num_tables == 0 || + woff2.num_tables > 0xFFFU || 48 + woff2.num_tables * 20UL >= woff2.length || ( woff2.metaOffset == 0 && ( woff2.metaLength != 0 || woff2.metaOrigLength != 0 ) ) || @@ -2134,7 +2136,7 @@ WOFF2_TtcFont ttc_font = woff2.ttc_fonts + face_index; - if ( ttc_font->num_tables == 0 ) + if ( ttc_font->num_tables == 0 || ttc_font->num_tables > 0xFFFU ) { FT_ERROR(( "woff2_open_font: invalid WOFF2 CollectionFontEntry\n" )); error = FT_THROW( Invalid_Table ); @@ -2197,23 +2199,14 @@ goto Exit; { - FT_UInt searchRange, entrySelector, rangeShift, x; FT_Byte* sfnt_header = sfnt; + FT_Int entrySelector = FT_MSB( woff.num_tables ); + FT_Int searchRange = ( 1 << entrySelector ) * 16; + FT_Int rangeShift = woff.num_tables * 16 - searchRange; - x = woff2.num_tables; - entrySelector = 0; - while ( x ) - { - x >>= 1; - entrySelector += 1; - } - entrySelector--; - searchRange = ( 1 << entrySelector ) * 16; - rangeShift = ( woff2.num_tables * 16 ) - searchRange; - - WRITE_ULONG( sfnt_header, woff2.flavor ); + WRITE_ULONG ( sfnt_header, woff2.flavor ); WRITE_USHORT( sfnt_header, woff2.num_tables ); WRITE_USHORT( sfnt_header, searchRange ); WRITE_USHORT( sfnt_header, entrySelector );