diff options
author | Werner Lemberg <wl@gnu.org> | 2017-05-29 21:04:27 +0200 |
---|---|---|
committer | Werner Lemberg <wl@gnu.org> | 2017-05-29 21:04:27 +0200 |
commit | f01463297f3d5db9cdfa59df4714c68bbef16e89 (patch) | |
tree | 070ce5abde1b98e1642d5b25932d9f70c9bf3eb8 | |
parent | fbe2fe4c7513246a666fb0cffffd29e7f6f3af4b (diff) | |
download | freetype2-f01463297f3d5db9cdfa59df4714c68bbef16e89.tar.gz |
[pcf] 32bit integer overflow run-time errors (#46149).
* src/pcf/pcfread.c (pcf_get_accel): Add sanity checks for
`fontAscent' and `fontDescent'.
(pcf_load_font): Add sanity checks for global height.
Add sanity checks for AVERAGE_WIDTH, POINT_SIZE, PIXEL_SIZE,
RESOLUTION_X, and RESOLUTION_Y properties.
-rw-r--r-- | ChangeLog | 10 | ||||
-rw-r--r-- | src/pcf/pcfread.c | 78 |
2 files changed, 79 insertions, 9 deletions
@@ -1,5 +1,15 @@ 2017-05-29 Werner Lemberg <wl@gnu.org> + [pcf] 32bit integer overflow run-time errors (#46149). + + * src/pcf/pcfread.c (pcf_get_accel): Add sanity checks for + `fontAscent' and `fontDescent'. + (pcf_load_font): Add sanity checks for global height. + Add sanity checks for AVERAGE_WIDTH, POINT_SIZE, PIXEL_SIZE, + RESOLUTION_X, and RESOLUTION_Y properties. + +2017-05-29 Werner Lemberg <wl@gnu.org> + Handle some integer overflow run-time errors (#46149, #48979). This commit (mainly for 32bit CPUs) is the first of a series of diff --git a/src/pcf/pcfread.c b/src/pcf/pcfread.c index 3eacf2baf..da216b05f 100644 --- a/src/pcf/pcfread.c +++ b/src/pcf/pcfread.c @@ -1162,6 +1162,20 @@ THE SOFTWARE. accel->fontDescent, accel->maxOverlap )); + /* sanity checks */ + if ( FT_ABS( accel->fontAscent ) > 0x7FFF ) + { + accel->fontAscent = accel->fontAscent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "pfc_get_accel: clamping font ascent to value %d\n", + accel->fontAscent )); + } + if ( FT_ABS( accel->fontDescent ) > 0x7FFF ) + { + accel->fontDescent = accel->fontDescent < 0 ? -0x7FFF : 0x7FFF; + FT_TRACE0(( "pfc_get_accel: clamping font descent to value %d\n", + accel->fontDescent )); + } + FT_TRACE5(( " minbounds:" )); error = pcf_get_metric( stream, format & ( ~PCF_FORMAT_MASK ), @@ -1496,8 +1510,16 @@ THE SOFTWARE. if ( face->accel.fontAscent + face->accel.fontDescent < 0 ) FT_TRACE0(( "pcf_load_font: negative height\n" )); #endif - bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + - face->accel.fontDescent ) ); + if ( FT_ABS( face->accel.fontAscent + + face->accel.fontDescent ) > 0x7FFF ) + { + bsize->height = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping height to value %d\n", + bsize->height )); + } + else + bsize->height = FT_ABS( (FT_Short)( face->accel.fontAscent + + face->accel.fontDescent ) ); prop = pcf_find_property( face, "AVERAGE_WIDTH" ); if ( prop ) @@ -1506,10 +1528,20 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative average width\n" )); #endif - bsize->width = FT_ABS( (FT_Short)( ( prop->value.l ) + 5 ) / 10 ); + if ( ( FT_ABS( prop->value.l ) > 0x7FFFL * 10 - 5 ) ) + { + bsize->width = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping average width to value %d\n", + bsize->width )); + } + else + bsize->width = FT_ABS( (FT_Short)( ( prop->value.l + 5 ) / 10 ) ); } else + { + /* this is a heuristical value */ bsize->width = (FT_Short)FT_MulDiv( bsize->height, 2, 3 ); + } prop = pcf_find_property( face, "POINT_SIZE" ); if ( prop ) @@ -1519,9 +1551,16 @@ THE SOFTWARE. FT_TRACE0(( "pcf_load_font: negative point size\n" )); #endif /* convert from 722.7 decipoints to 72 points per inch */ - bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), - 64 * 7200, - 72270L ); + if ( FT_ABS( prop->value.l ) > 0x504C2L ) /* 0x7FFF * 72270/7200 */ + { + bsize->size = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping point size to value %d\n", + bsize->size )); + } + else + bsize->size = FT_MulDiv( FT_ABS( prop->value.l ), + 64 * 7200, + 72270L ); } prop = pcf_find_property( face, "PIXEL_SIZE" ); @@ -1531,7 +1570,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative pixel size\n" )); #endif - bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + bsize->y_ppem = 0x7FFF << 6; + FT_TRACE0(( "pcf_load_font: clamping pixel size to value %d\n", + bsize->y_ppem )); + } + else + bsize->y_ppem = FT_ABS( (FT_Short)prop->value.l ) << 6; } prop = pcf_find_property( face, "RESOLUTION_X" ); @@ -1541,7 +1587,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative X resolution\n" )); #endif - resolution_x = FT_ABS( (FT_Short)prop->value.l ); + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + resolution_x = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping X resolution to value %d\n", + resolution_x )); + } + else + resolution_x = FT_ABS( (FT_Short)prop->value.l ); } prop = pcf_find_property( face, "RESOLUTION_Y" ); @@ -1551,7 +1604,14 @@ THE SOFTWARE. if ( prop->value.l < 0 ) FT_TRACE0(( "pcf_load_font: negative Y resolution\n" )); #endif - resolution_y = FT_ABS( (FT_Short)prop->value.l ); + if ( FT_ABS( prop->value.l ) > 0x7FFF ) + { + resolution_y = 0x7FFF; + FT_TRACE0(( "pcf_load_font: clamping Y resolution to value %d\n", + resolution_y )); + } + else + resolution_y = FT_ABS( (FT_Short)prop->value.l ); } if ( bsize->y_ppem == 0 ) |