[sfnt] Handle infinite recursion in bitmap strikes (#46344).

* src/sfnt/ttsbit.c (TT_SBitDecoder_LoadFunc,
tt_sbit_decoder_load_bitmap, tt_sbit_decoder_load_byte_aligned,
tt_sbit_decoder_load_bit_aligned, tt_sbit_decoder_load_png): Add
argument for recursion depth.
(tt_sbit_decoder_load_compound): Add argument for recursion depth.
Increase recursion counter for recursive call.
(tt_sbit_decoder_load_image): Add argument for recursion depth.
Check recurse depth.
(tt_face_load_sbit_image): Updated.
This commit is contained in:
Werner Lemberg 2015-10-31 17:52:56 +01:00
parent 4188deacf3
commit 009cc15035
2 changed files with 61 additions and 21 deletions

View File

@ -1,3 +1,17 @@
2015-10-31 Werner Lemberg <wl@gnu.org>
[sfnt] Handle infinite recursion in bitmap strikes (#46344).
* src/sfnt/ttsbit.c (TT_SBitDecoder_LoadFunc,
tt_sbit_decoder_load_bitmap, tt_sbit_decoder_load_byte_aligned,
tt_sbit_decoder_load_bit_aligned, tt_sbit_decoder_load_png): Add
argument for recursion depth.
(tt_sbit_decoder_load_compound): Add argument for recursion depth.
Increase recursion counter for recursive call.
(tt_sbit_decoder_load_image): Add argument for recursion depth.
Check recurse depth.
(tt_face_load_sbit_image): Updated.
2015-10-29 Werner Lemberg <wl@gnu.org> 2015-10-29 Werner Lemberg <wl@gnu.org>
* src/autofit/afhints.c (af_glyph_hints_dump_points): Minor. * src/autofit/afhints.c (af_glyph_hints_dump_points): Minor.

View File

@ -608,13 +608,16 @@
tt_sbit_decoder_load_image( TT_SBitDecoder decoder, tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
FT_UInt glyph_index, FT_UInt glyph_index,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ); FT_Int y_pos,
FT_UInt recurse_count );
typedef FT_Error (*TT_SBitDecoder_LoadFunc)( TT_SBitDecoder decoder, typedef FT_Error (*TT_SBitDecoder_LoadFunc)(
TT_SBitDecoder decoder,
FT_Byte* p, FT_Byte* p,
FT_Byte* plimit, FT_Byte* plimit,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ); FT_Int y_pos,
FT_UInt recurse_count );
static FT_Error static FT_Error
@ -622,7 +625,8 @@
FT_Byte* p, FT_Byte* p,
FT_Byte* limit, FT_Byte* limit,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos,
FT_UInt recurse_count )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Byte* line; FT_Byte* line;
@ -630,6 +634,8 @@
FT_UInt bit_height, bit_width; FT_UInt bit_height, bit_width;
FT_Bitmap* bitmap; FT_Bitmap* bitmap;
FT_UNUSED( recurse_count );
/* check that we can write the glyph into the bitmap */ /* check that we can write the glyph into the bitmap */
bitmap = decoder->bitmap; bitmap = decoder->bitmap;
@ -761,7 +767,8 @@
FT_Byte* p, FT_Byte* p,
FT_Byte* limit, FT_Byte* limit,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos,
FT_UInt recurse_count )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_Byte* line; FT_Byte* line;
@ -770,6 +777,8 @@
FT_Bitmap* bitmap; FT_Bitmap* bitmap;
FT_UShort rval; FT_UShort rval;
FT_UNUSED( recurse_count );
/* check that we can write the glyph into the bitmap */ /* check that we can write the glyph into the bitmap */
bitmap = decoder->bitmap; bitmap = decoder->bitmap;
@ -885,7 +894,8 @@
FT_Byte* p, FT_Byte* p,
FT_Byte* limit, FT_Byte* limit,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos,
FT_UInt recurse_count )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_UInt num_components, nn; FT_UInt num_components, nn;
@ -919,8 +929,11 @@
/* NB: a recursive call */ /* NB: a recursive call */
error = tt_sbit_decoder_load_image( decoder, gindex, error = tt_sbit_decoder_load_image( decoder,
x_pos + dx, y_pos + dy ); gindex,
x_pos + dx,
y_pos + dy,
recurse_count + 1 );
if ( error ) if ( error )
break; break;
} }
@ -952,11 +965,14 @@
FT_Byte* p, FT_Byte* p,
FT_Byte* limit, FT_Byte* limit,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos,
FT_UInt recurse_count )
{ {
FT_Error error = FT_Err_Ok; FT_Error error = FT_Err_Ok;
FT_ULong png_len; FT_ULong png_len;
FT_UNUSED( recurse_count );
if ( limit - p < 4 ) if ( limit - p < 4 )
{ {
@ -998,7 +1014,8 @@
FT_ULong glyph_start, FT_ULong glyph_start,
FT_ULong glyph_size, FT_ULong glyph_size,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos,
FT_UInt recurse_count )
{ {
FT_Error error; FT_Error error;
FT_Stream stream = decoder->stream; FT_Stream stream = decoder->stream;
@ -1124,7 +1141,7 @@
goto Fail; goto Fail;
} }
error = loader( decoder, p, p_limit, x_pos, y_pos ); error = loader( decoder, p, p_limit, x_pos, y_pos, recurse_count );
} }
Fail: Fail:
@ -1139,13 +1156,9 @@
tt_sbit_decoder_load_image( TT_SBitDecoder decoder, tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
FT_UInt glyph_index, FT_UInt glyph_index,
FT_Int x_pos, FT_Int x_pos,
FT_Int y_pos ) FT_Int y_pos,
FT_UInt recurse_count )
{ {
/*
* First, we find the correct strike range that applies to this
* glyph index.
*/
FT_Byte* p = decoder->eblc_base + decoder->strike_index_array; FT_Byte* p = decoder->eblc_base + decoder->strike_index_array;
FT_Byte* p_limit = decoder->eblc_limit; FT_Byte* p_limit = decoder->eblc_limit;
FT_ULong num_ranges = decoder->strike_index_count; FT_ULong num_ranges = decoder->strike_index_count;
@ -1153,6 +1166,17 @@
FT_ULong image_start = 0, image_end = 0, image_offset; FT_ULong image_start = 0, image_end = 0, image_offset;
/* arbitrary recursion limit */
if ( recurse_count > 100 )
{
FT_TRACE4(( "tt_sbit_decoder_load_image:"
" recursion depth exceeded\n" ));
goto Failure;
}
/* First, we find the correct strike range that applies to this */
/* glyph index. */
for ( ; num_ranges > 0; num_ranges-- ) for ( ; num_ranges > 0; num_ranges-- )
{ {
start = FT_NEXT_USHORT( p ); start = FT_NEXT_USHORT( p );
@ -1317,7 +1341,8 @@
image_start, image_start,
image_end, image_end,
x_pos, x_pos,
y_pos ); y_pos,
recurse_count );
Failure: Failure:
return FT_THROW( Invalid_Table ); return FT_THROW( Invalid_Table );
@ -1480,6 +1505,7 @@
error = tt_sbit_decoder_load_image( decoder, error = tt_sbit_decoder_load_image( decoder,
glyph_index, glyph_index,
0, 0,
0,
0 ); 0 );
tt_sbit_decoder_done( decoder ); tt_sbit_decoder_done( decoder );
} }