summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXi Wang <xi.wang@gmail.com>2013-01-25 00:57:09 +0100
committerWerner Lemberg <wl@gnu.org>2013-01-25 00:57:09 +0100
commitba931be2af19a2a37ad55d66cd7bc53dbc0c18dc (patch)
tree22e3e8026c2542303a5d7afbaced8879da35b4d8
parent817caa9f4f2d018058a697fc4ba5ad92164dc0f3 (diff)
downloadfreetype2-ba931be2af19a2a37ad55d66cd7bc53dbc0c18dc.tar.gz
[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.
-rw-r--r--ChangeLog16
-rw-r--r--src/sfnt/ttsbit0.c20
2 files changed, 22 insertions, 14 deletions
diff --git a/ChangeLog b/ChangeLog
index 2ee336b32..a81190f74 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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>
- 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 ffef10a6c..691bad704 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++ )