ref: 4404ec4ef5b8dfc7edcd92bada5e5e4bcbc9a81a
parent: 0708b23e808eefb16a3a46abd738c040381fa0e3
author: Werner Lemberg <[email protected]>
date: Fri Oct 19 05:06:53 EDT 2012
[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'.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2012-10-19 Werner Lemberg <[email protected]>
+
+ [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 <[email protected]>
[psaux] Fix some value overflows.
--- 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,7 +255,12 @@
/* Arbitrarily limit exponent. */
if ( exponent > 1000 )
- goto Exit;
+ {
+ if ( exponent_sign )
+ goto Underflow;
+ else
+ goto Overflow;
+ }
}
if ( exponent_sign )
@@ -261,6 +267,9 @@
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;
}
@@ -383,33 +407,54 @@
/* read a floating point number, either integer or real */
static FT_Fixed
- cff_parse_fixed( FT_Byte** d )
+ do_fixed( FT_Byte** d,
+ FT_Long scaling )
{
- return **d == 30 ? cff_parse_real( d[0], d[1], 0, NULL )
- : cff_parse_integer( d[0], d[1] ) << 16;
- }
-
-
- /* read a floating point number, either integer or real, */
- /* but return `10^scaling' times the number read in */
- static FT_Fixed
- 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];
+ FT_Long val = cff_parse_integer( d[0], d[1] );
+ if ( scaling )
+ val *= power_tens[scaling];
+
if ( val > 0x7FFF )
- return 0x7FFFFFFFL;
+ {
+ val = 0x7FFFFFFFL;
+ goto Overflow;
+ }
else if ( val < -0x7FFF )
- return -0x7FFFFFFFL;
+ {
+ 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 do_fixed( d, 0 );
+ }
+
+
+ /* read a floating point number, either integer or real, */
+ /* but return `10^scaling' times the number read in */
+ static FT_Fixed
+ cff_parse_fixed_scaled( FT_Byte** d,
+ FT_Long scaling )
+ {
+ return do_fixed( d, scaling );
}