From 4404ec4ef5b8dfc7edcd92bada5e5e4bcbc9a81a Mon Sep 17 00:00:00 2001 From: Werner Lemberg Date: Fri, 19 Oct 2012 09:06:53 +0200 Subject: [PATCH] [cff] Fix more value errors and improve tracing. * src/cff/cffparse.c (cff_parse_integer): Emit tracing message in case of error. (cff_parse_real): Handle and trace overflow, underflow, and bad data consistently. (do_fixed): New helper function, handling and tracing overflow. (cff_parse_fixed, cff_parse_fixed_scaled): Use `do_fixed'. --- ChangeLog | 11 ++++++ src/cff/cffparse.c | 91 ++++++++++++++++++++++++++++++++++------------ 2 files changed, 79 insertions(+), 23 deletions(-) diff --git a/ChangeLog b/ChangeLog index d9fb1a69b..682b7c7e7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2012-10-19 Werner Lemberg + + [cff] Fix more value errors and improve tracing. + + * src/cff/cffparse.c (cff_parse_integer): Emit tracing message in + case of error. + (cff_parse_real): Handle and trace overflow, underflow, and bad data + consistently. + (do_fixed): New helper function, handling and tracing overflow. + (cff_parse_fixed, cff_parse_fixed_scaled): Use `do_fixed'. + 2012-10-17 Werner Lemberg [psaux] Fix some value overflows. diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c index 2e93bd3a1..015a1d190 100644 --- a/src/cff/cffparse.c +++ b/src/cff/cffparse.c @@ -105,6 +105,7 @@ Bad: val = 0; + FT_TRACE4(( "!!!END OF DATA:!!!" )); goto Exit; } @@ -165,7 +166,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Exit; + goto Bad; } /* Get the nibble. */ @@ -202,7 +203,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Exit; + goto Bad; } /* Get the nibble. */ @@ -241,7 +242,7 @@ /* Make sure we don't read past the end. */ if ( p >= limit ) - goto Exit; + goto Bad; } /* Get the nibble. */ @@ -254,13 +255,21 @@ /* Arbitrarily limit exponent. */ if ( exponent > 1000 ) - goto Exit; + { + if ( exponent_sign ) + goto Underflow; + else + goto Overflow; + } } if ( exponent_sign ) exponent = -exponent; } + if ( !number ) + goto Exit; + /* We don't check `power_ten' and `exponent_add'. */ exponent += power_ten + exponent_add; @@ -329,7 +338,7 @@ /* Check for overflow and underflow. */ if ( FT_ABS( integer_length ) > 5 ) - goto Exit; + goto Overflow; /* Remove non-significant digits. */ if ( integer_length < 0 ) @@ -358,17 +367,32 @@ number *= power_tens[-fraction_length]; if ( number > 0x7FFFL ) - goto Exit; + goto Overflow; result = number << 16; } } + Exit: if ( sign ) result = -result; - Exit: return result; + + Overflow: + result = 0x7FFFFFFFL; + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + goto Exit; + + Underflow: + result = 0; + FT_TRACE4(( "!!!UNDERFLOW:!!!" )); + goto Exit; + + Bad: + result = 0; + FT_TRACE4(( "!!!END OF DATA:!!!" )); + goto Exit; } @@ -381,12 +405,46 @@ } + /* read a floating point number, either integer or real */ + static FT_Fixed + do_fixed( FT_Byte** d, + FT_Long scaling ) + { + if ( **d == 30 ) + return cff_parse_real( d[0], d[1], scaling, NULL ); + else + { + FT_Long val = cff_parse_integer( d[0], d[1] ); + + + if ( scaling ) + val *= power_tens[scaling]; + + if ( val > 0x7FFF ) + { + val = 0x7FFFFFFFL; + goto Overflow; + } + else if ( val < -0x7FFF ) + { + val = -0x7FFFFFFFL; + goto Overflow; + } + + return val << 16; + + Overflow: + FT_TRACE4(( "!!!OVERFLOW:!!!" )); + return val; + } + } + + /* read a floating point number, either integer or real */ static FT_Fixed cff_parse_fixed( FT_Byte** d ) { - return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL ) - : cff_parse_integer( d[0], d[1] ) << 16; + return do_fixed( d, 0 ); } @@ -396,20 +454,7 @@ cff_parse_fixed_scaled( FT_Byte** d, FT_Long scaling ) { - if ( **d == 30 ) - return cff_parse_real( d[0], d[1], scaling, NULL ); - else - { - FT_Long val = cff_parse_integer( d[0], d[1] ) * power_tens[scaling]; - - - if ( val > 0x7FFF ) - return 0x7FFFFFFFL; - else if ( val < -0x7FFF ) - return -0x7FFFFFFFL; - - return val << 16; - } + return do_fixed( d, scaling ); }