[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.
This commit is contained in:
Xi Wang 2013-01-25 00:57:09 +01:00 committed by Werner Lemberg
parent 817caa9f4f
commit ba931be2af
2 changed files with 22 additions and 14 deletions

View File

@ -1,6 +1,20 @@
2013-01-25 Xi Wang <xi.wang@gmail.com>
[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 <wl@gnu.org> 2013-01-25 Werner Lemberg <wl@gnu.org>
Fix `make multi' [base] Fix `make multi'.
* src/base/ftoutln.c, src/base/fttrigon.c: Include * src/base/ftoutln.c, src/base/fttrigon.c: Include
FT_INTERNAL_CALC_H. FT_INTERNAL_CALC_H.

View File

@ -823,11 +823,11 @@
image_offset = FT_NEXT_ULONG( p ); image_offset = FT_NEXT_ULONG( p );
/* overflow check */ /* overflow check */
if ( decoder->eblc_base + decoder->strike_index_array + image_offset < p = decoder->eblc_base + decoder->strike_index_array;
decoder->eblc_base ) if ( image_offset > (FT_ULong)( p_limit - p ) )
goto Failure; goto Failure;
p = decoder->eblc_base + decoder->strike_index_array + image_offset; p += image_offset;
if ( p + 8 > p_limit ) if ( p + 8 > p_limit )
goto NoBitmap; goto NoBitmap;
@ -894,11 +894,8 @@
num_glyphs = FT_NEXT_ULONG( p ); num_glyphs = FT_NEXT_ULONG( p );
/* overflow check */ /* overflow check for p + ( num_glyphs + 1 ) * 4 */
if ( p + ( num_glyphs + 1 ) * 4 < p ) if ( num_glyphs > (FT_ULong)( ( ( p_limit - p ) >> 2 ) - 1 ) )
goto Failure;
if ( p + ( num_glyphs + 1 ) * 4 > p_limit )
goto NoBitmap; goto NoBitmap;
for ( mm = 0; mm < num_glyphs; mm++ ) for ( mm = 0; mm < num_glyphs; mm++ )
@ -936,11 +933,8 @@
num_glyphs = FT_NEXT_ULONG( p ); num_glyphs = FT_NEXT_ULONG( p );
/* overflow check */ /* overflow check for p + 2 * num_glyphs */
if ( p + 2 * num_glyphs < p ) if ( num_glyphs > (FT_ULong)( ( p_limit - p ) >> 1 ) )
goto Failure;
if ( p + 2 * num_glyphs > p_limit )
goto NoBitmap; goto NoBitmap;
for ( mm = 0; mm < num_glyphs; mm++ ) for ( mm = 0; mm < num_glyphs; mm++ )