[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>
* src/autofit/afhints.c (af_glyph_hints_dump_points): Minor.

View File

@ -608,13 +608,16 @@
tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
FT_UInt glyph_index,
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,
FT_Byte* p,
FT_Byte* plimit,
FT_Int x_pos,
FT_Int y_pos );
typedef FT_Error (*TT_SBitDecoder_LoadFunc)(
TT_SBitDecoder decoder,
FT_Byte* p,
FT_Byte* plimit,
FT_Int x_pos,
FT_Int y_pos,
FT_UInt recurse_count );
static FT_Error
@ -622,7 +625,8 @@
FT_Byte* p,
FT_Byte* limit,
FT_Int x_pos,
FT_Int y_pos )
FT_Int y_pos,
FT_UInt recurse_count )
{
FT_Error error = FT_Err_Ok;
FT_Byte* line;
@ -630,6 +634,8 @@
FT_UInt bit_height, bit_width;
FT_Bitmap* bitmap;
FT_UNUSED( recurse_count );
/* check that we can write the glyph into the bitmap */
bitmap = decoder->bitmap;
@ -761,7 +767,8 @@
FT_Byte* p,
FT_Byte* limit,
FT_Int x_pos,
FT_Int y_pos )
FT_Int y_pos,
FT_UInt recurse_count )
{
FT_Error error = FT_Err_Ok;
FT_Byte* line;
@ -770,6 +777,8 @@
FT_Bitmap* bitmap;
FT_UShort rval;
FT_UNUSED( recurse_count );
/* check that we can write the glyph into the bitmap */
bitmap = decoder->bitmap;
@ -885,7 +894,8 @@
FT_Byte* p,
FT_Byte* limit,
FT_Int x_pos,
FT_Int y_pos )
FT_Int y_pos,
FT_UInt recurse_count )
{
FT_Error error = FT_Err_Ok;
FT_UInt num_components, nn;
@ -919,8 +929,11 @@
/* NB: a recursive call */
error = tt_sbit_decoder_load_image( decoder, gindex,
x_pos + dx, y_pos + dy );
error = tt_sbit_decoder_load_image( decoder,
gindex,
x_pos + dx,
y_pos + dy,
recurse_count + 1 );
if ( error )
break;
}
@ -952,11 +965,14 @@
FT_Byte* p,
FT_Byte* limit,
FT_Int x_pos,
FT_Int y_pos )
FT_Int y_pos,
FT_UInt recurse_count )
{
FT_Error error = FT_Err_Ok;
FT_ULong png_len;
FT_UNUSED( recurse_count );
if ( limit - p < 4 )
{
@ -998,7 +1014,8 @@
FT_ULong glyph_start,
FT_ULong glyph_size,
FT_Int x_pos,
FT_Int y_pos )
FT_Int y_pos,
FT_UInt recurse_count )
{
FT_Error error;
FT_Stream stream = decoder->stream;
@ -1124,7 +1141,7 @@
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:
@ -1139,13 +1156,9 @@
tt_sbit_decoder_load_image( TT_SBitDecoder decoder,
FT_UInt glyph_index,
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_limit = decoder->eblc_limit;
FT_ULong num_ranges = decoder->strike_index_count;
@ -1153,6 +1166,17 @@
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-- )
{
start = FT_NEXT_USHORT( p );
@ -1317,7 +1341,8 @@
image_start,
image_end,
x_pos,
y_pos );
y_pos,
recurse_count );
Failure:
return FT_THROW( Invalid_Table );
@ -1480,6 +1505,7 @@
error = tt_sbit_decoder_load_image( decoder,
glyph_index,
0,
0,
0 );
tt_sbit_decoder_done( decoder );
}