From ba931be2af19a2a37ad55d66cd7bc53dbc0c18dc Mon Sep 17 00:00:00 2001 From: Xi Wang Date: Fri, 25 Jan 2013 00:57:09 +0100 Subject: [PATCH] [sfnt] Fix broken pointer overflow checks. Many compilers such as gcc and clang optimize away pointer overflow checks `p + n < p', because pointer overflow is undefined behavior. Use a safe form `n > p_limit - p' instead. Also avoid possible integer overflow issues, for example, using `num_glyphs > ( p_limit - p ) / 2' rather than `num_glyphs * 2' given a large `num_glyphs'. * src/sfnt/ttsbit0.c (tt_sbit_decoder_load_image): Implement it. --- ChangeLog | 16 +++++++++++++++- src/sfnt/ttsbit0.c | 20 +++++++------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2ee336b3..a81190f7 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,20 @@ +2013-01-25 Xi Wang + + [sfnt] Fix broken pointer overflow checks. + + Many compilers such as gcc and clang optimize away pointer overflow + checks `p + n < p', because pointer overflow is undefined behavior. + Use a safe form `n > p_limit - p' instead. + + Also avoid possible integer overflow issues, for example, using + `num_glyphs > ( p_limit - p ) / 2' rather than `num_glyphs * 2' + given a large `num_glyphs'. + + * src/sfnt/ttsbit0.c (tt_sbit_decoder_load_image): Implement it. + 2013-01-25 Werner Lemberg - Fix `make multi' + [base] Fix `make multi'. * src/base/ftoutln.c, src/base/fttrigon.c: Include FT_INTERNAL_CALC_H. diff --git a/src/sfnt/ttsbit0.c b/src/sfnt/ttsbit0.c index ffef10a6..691bad70 100644 --- a/src/sfnt/ttsbit0.c +++ b/src/sfnt/ttsbit0.c @@ -823,11 +823,11 @@ image_offset = FT_NEXT_ULONG( p ); /* overflow check */ - if ( decoder->eblc_base + decoder->strike_index_array + image_offset < - decoder->eblc_base ) + p = decoder->eblc_base + decoder->strike_index_array; + if ( image_offset > (FT_ULong)( p_limit - p ) ) goto Failure; - p = decoder->eblc_base + decoder->strike_index_array + image_offset; + p += image_offset; if ( p + 8 > p_limit ) goto NoBitmap; @@ -894,11 +894,8 @@ 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 ) + /* overflow check for p + ( num_glyphs + 1 ) * 4 */ + if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) ) goto NoBitmap; for ( mm = 0; mm < num_glyphs; mm++ ) @@ -936,11 +933,8 @@ num_glyphs = FT_NEXT_ULONG( p ); - /* overflow check */ - if ( p + 2 * num_glyphs < p ) - goto Failure; - - if ( p + 2 * num_glyphs > p_limit ) + /* overflow check for p + 2 * num_glyphs */ + if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) ) goto NoBitmap; for ( mm = 0; mm < num_glyphs; mm++ )