ref: 88ab638e0fd4cdc5cdb40d5dc0897ec064ce9719
parent: 470210b73c2afb76a14025b7e89327a74b3f505a
author: Werner Lemberg <[email protected]>
date: Thu Jun 7 01:01:56 EDT 2007
* src/sfnt/ttsbit0.c (tt_sbit_decoder_init, tt_sbit_decoder_load_image): Protect against integer overflows. * src/pfr/pfrgload.c (pfr_glyph_load_simple): More bounding checks for `x_control' and `y_control'.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2007-06-07 Werner Lemberg <[email protected]>
+
+ * src/sfnt/ttsbit0.c (tt_sbit_decoder_init,
+ tt_sbit_decoder_load_image): Protect against integer overflows.
+
+
+ * src/pfr/pfrgload.c (pfr_glyph_load_simple): More bounding checks
+ for `x_control' and `y_control'.
+
2007-06-06 Werner Lemberg <[email protected]>
* src/base/ftoutln.c (FT_Outline_Decompose): Check `last'.
--- a/src/pfr/pfrgload.c
+++ b/src/pfr/pfrgload.c
@@ -354,7 +354,7 @@
for (;;)
{
- FT_Int format, args_format = 0, args_count, n;
+ FT_UInt format, format_low, args_format = 0, args_count, n;
/***************************************************************/
@@ -361,7 +361,8 @@
/* read instruction */
/* */
PFR_CHECK( 1 );
- format = PFR_NEXT_BYTE( p );
+ format = PFR_NEXT_BYTE( p );
+ format_low = format & 15;
switch ( format >> 4 )
{
@@ -381,30 +382,34 @@
case 5: /* move to outside contour */
FT_TRACE6(( "- move to outside" ));
Line1:
- args_format = format & 15;
+ args_format = format_low;
args_count = 1;
break;
case 2: /* horizontal line to */
- FT_TRACE6(( "- horizontal line to cx.%d", format & 15 ));
+ FT_TRACE6(( "- horizontal line to cx.%d", format_low ));
+ if ( format_low > x_count )
+ goto Failure;
+ pos[0].x = glyph->x_control[format_low];
pos[0].y = pos[3].y;
- pos[0].x = glyph->x_control[format & 15];
pos[3] = pos[0];
args_count = 0;
break;
case 3: /* vertical line to */
- FT_TRACE6(( "- vertical line to cy.%d", format & 15 ));
+ FT_TRACE6(( "- vertical line to cy.%d", format_low ));
+ if ( format_low > y_count )
+ goto Failure;
pos[0].x = pos[3].x;
- pos[0].y = glyph->y_control[format & 15];
- pos[3] = pos[0];
+ pos[0].y = glyph->y_control[format_low];
+ pos[3] = pos[0];
args_count = 0;
break;
case 6: /* horizontal to vertical curve */
FT_TRACE6(( "- hv curve " ));
- args_format = 0xB8E;
- args_count = 3;
+ args_format = 0xB8E;
+ args_count = 3;
break;
case 7: /* vertical to horizontal curve */
@@ -416,7 +421,7 @@
default: /* general curve to */
FT_TRACE6(( "- general curve" ));
args_count = 4;
- args_format = format & 15;
+ args_format = format_low;
}
/***********************************************************/
--- a/src/sfnt/ttsbit0.c
+++ b/src/sfnt/ttsbit0.c
@@ -235,7 +235,7 @@
TT_SBit_MetricsRec* metrics )
{
FT_Error error;
- FT_Stream stream = face->root.stream;
+ FT_Stream stream = face->root.stream;
FT_ULong ebdt_size;
@@ -261,14 +261,27 @@
/* now find the strike corresponding to the index */
{
- FT_Byte* p = decoder->eblc_base + 8 + 48 * strike_index;
+ FT_Byte* p;
+ if ( 8 + 48 * strike_index + 3 * 4 + 34 + 1 > face->sbit_table_size )
+ {
+ error = SFNT_Err_Invalid_File_Format;
+ goto Exit;
+ }
+
+ p = decoder->eblc_base + 8 + 48 * strike_index;
+
decoder->strike_index_array = FT_NEXT_ULONG( p );
p += 4;
decoder->strike_index_count = FT_NEXT_ULONG( p );
p += 34;
decoder->bit_depth = *p;
+
+ if ( decoder->strike_index_array > face->sbit_table_size ||
+ decoder->strike_index_array + 8 * decoder->strike_index_count >
+ face->sbit_table_size )
+ error = SFNT_Err_Invalid_File_Format;
}
Exit:
@@ -642,9 +655,9 @@
for ( nn = 0; nn < num_components; nn++ )
{
- FT_UInt gindex = FT_NEXT_USHORT( p );
- FT_Byte dx = FT_NEXT_BYTE( p );
- FT_Byte dy = FT_NEXT_BYTE( p );
+ FT_UInt gindex = FT_NEXT_USHORT( p );
+ FT_Byte dx = FT_NEXT_BYTE( p );
+ FT_Byte dy = FT_NEXT_BYTE( p );
/* NB: a recursive call */
@@ -775,9 +788,6 @@
FT_ULong image_start = 0, image_end = 0, image_offset;
- if ( p + 8 * num_ranges > p_limit )
- goto NoBitmap;
-
for ( ; num_ranges > 0; num_ranges-- )
{
start = FT_NEXT_USHORT( p );
@@ -792,6 +802,12 @@
FoundRange:
image_offset = FT_NEXT_ULONG( p );
+
+ /* overflow check */
+ if ( decoder->eblc_base + decoder->strike_index_array + image_offset <
+ decoder->eblc_base )
+ goto Failure;
+
p = decoder->eblc_base + decoder->strike_index_array + image_offset;
if ( p + 8 > p_limit )
goto NoBitmap;
@@ -831,7 +847,7 @@
goto NoBitmap;
image_start = image_size * ( glyph_index - start );
- image_end = image_start + image_size;
+ image_end = image_start + image_size;
}
break;
@@ -858,6 +874,11 @@
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p );
+
+ /* overflow check */
+ if ( p + ( num_glyphs + 1 ) * 4 < p )
+ goto Failure;
+
if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
goto NoBitmap;
@@ -895,6 +916,11 @@
goto NoBitmap;
num_glyphs = FT_NEXT_ULONG( p );
+
+ /* overflow check */
+ if ( p + 2 * num_glyphs < p )
+ goto Failure;
+
if ( p + 2 * num_glyphs > p_limit )
goto NoBitmap;
@@ -910,7 +936,7 @@
if ( mm >= num_glyphs )
goto NoBitmap;
- image_start = image_size*mm;
+ image_start = image_size * mm;
image_end = image_start + image_size;
}
break;
@@ -931,6 +957,9 @@
image_end,
x_pos,
y_pos );
+
+ Failure:
+ return SFNT_Err_Invalid_Table;
NoBitmap:
return SFNT_Err_Invalid_Argument;