[sfnt] Fix Savannah bug #41696. * src/sfnt/ttcmap.c (tt_cmap0_validate, tt_cmap2_validate, tt_cmap4_validate, tt_cmap14_validate): Fix limit tests.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123
diff --git a/ChangeLog b/ChangeLog
index f23507a..2010fda 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,12 @@
2014-02-26 Werner Lemberg <wl@gnu.org>
+ [sfnt] Fix Savannah bug #41696.
+
+ * src/sfnt/ttcmap.c (tt_cmap0_validate, tt_cmap2_validate,
+ tt_cmap4_validate, tt_cmap14_validate): Fix limit tests.
+
+2014-02-26 Werner Lemberg <wl@gnu.org>
+
[winfnt] Fix Savannah bug #41694.
* src/winfonts/winfnt.c (FNT_Load_Glyph): Check glyph offset.
diff --git a/src/sfnt/ttcmap.c b/src/sfnt/ttcmap.c
index f17ce59..c717f5f 100644
--- a/src/sfnt/ttcmap.c
+++ b/src/sfnt/ttcmap.c
@@ -88,9 +88,15 @@
tt_cmap0_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p = table + 2;
- FT_UInt length = TT_NEXT_USHORT( p );
+ FT_Byte* p;
+ FT_UInt length;
+
+ if ( table + 2 + 2 > valid->limit )
+ FT_INVALID_TOO_SHORT;
+
+ p = table + 2; /* skip format */
+ length = TT_NEXT_USHORT( p );
if ( table + length > valid->limit || length < 262 )
FT_INVALID_TOO_SHORT;
@@ -279,14 +285,21 @@
tt_cmap2_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p = table + 2; /* skip format */
- FT_UInt length = TT_PEEK_USHORT( p );
+ FT_Byte* p;
+ FT_UInt length;
+
FT_UInt n, max_subs;
- FT_Byte* keys; /* keys table */
- FT_Byte* subs; /* sub-headers */
- FT_Byte* glyph_ids; /* glyph ID array */
+ FT_Byte* keys; /* keys table */
+ FT_Byte* subs; /* sub-headers */
+ FT_Byte* glyph_ids; /* glyph ID array */
+ if ( table + 2 + 2 > valid->limit )
+ FT_INVALID_TOO_SHORT;
+
+ p = table + 2; /* skip format */
+ length = TT_NEXT_USHORT( p );
+
if ( table + length > valid->limit || length < 6 + 512 )
FT_INVALID_TOO_SHORT;
@@ -818,13 +831,20 @@
tt_cmap4_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p = table + 2; /* skip format */
- FT_UInt length = TT_NEXT_USHORT( p );
+ FT_Byte* p;
+ FT_UInt length;
+
FT_Byte *ends, *starts, *offsets, *deltas, *glyph_ids;
FT_UInt num_segs;
FT_Error error = FT_Err_Ok;
+ if ( table + 2 + 2 > valid->limit )
+ FT_INVALID_TOO_SHORT;
+
+ p = table + 2; /* skip format */
+ length = TT_NEXT_USHORT( p );
+
if ( length < 16 )
FT_INVALID_TOO_SHORT;
@@ -2044,9 +2064,9 @@
tt_cmap12_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p;
- FT_ULong length;
- FT_ULong num_groups;
+ FT_Byte* p;
+ FT_ULong length;
+ FT_ULong num_groups;
if ( table + 16 > valid->limit )
@@ -2754,10 +2774,17 @@
tt_cmap14_validate( FT_Byte* table,
FT_Validator valid )
{
- FT_Byte* p = table + 2;
- FT_ULong length = TT_NEXT_ULONG( p );
- FT_ULong num_selectors = TT_NEXT_ULONG( p );
+ FT_Byte* p;
+ FT_ULong length;
+ FT_ULong num_selectors;
+
+
+ if ( table + 2 + 4 + 4 > valid->limit )
+ FT_INVALID_TOO_SHORT;
+ p = table + 2;
+ length = TT_NEXT_ULONG( p );
+ num_selectors = TT_NEXT_ULONG( p );
if ( length > (FT_ULong)( valid->limit - table ) ||
length < 10 + 11 * num_selectors )