[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.
This commit is contained in:
Alexei Podtelezhnikov 2024-05-03 15:44:57 +00:00
parent 13d1180f45
commit 3f28a6b6af
2 changed files with 12 additions and 27 deletions

View File

@ -18,6 +18,7 @@
#include "sfwoff.h"
#include <freetype/tttags.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
#include <freetype/ftgzip.h>
@ -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 );

View File

@ -18,6 +18,7 @@
#include "sfwoff2.h"
#include "woff2tags.h"
#include <freetype/tttags.h>
#include <freetype/internal/ftcalc.h>
#include <freetype/internal/ftdebug.h>
#include <freetype/internal/ftstream.h>
@ -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 );