summaryrefslogtreecommitdiffstats
path: root/src/sfnt/ttkern.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sfnt/ttkern.c')
-rw-r--r--src/sfnt/ttkern.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/src/sfnt/ttkern.c b/src/sfnt/ttkern.c
index 28e52c3..67d5115 100644
--- a/src/sfnt/ttkern.c
+++ b/src/sfnt/ttkern.c
@@ -5,7 +5,7 @@
/* Load the basic TrueType kerning table. This doesn't handle */
/* kerning data within the GPOS table at the moment. */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -103,6 +103,9 @@
p_next += length;
+ if ( p_next > p_limit ) /* handle broken table */
+ p_next = p_limit;
+
/* only use horizontal kerning tables */
if ( ( coverage & ~8 ) != 0x0001 ||
p + 8 > p_limit )
@@ -111,8 +114,8 @@
num_pairs = FT_NEXT_USHORT( p );
p += 6;
- if ( p + 6 * num_pairs > p_limit )
- goto NextTable;
+ if ( ( p_next - p ) / 6 < (int)num_pairs ) /* handle broken count */
+ num_pairs = (FT_UInt)( ( p_next - p ) / 6 );
avail |= mask;
@@ -181,18 +184,22 @@
FT_Int result = 0;
FT_UInt count, mask = 1;
FT_Byte* p = face->kern_table;
+ FT_Byte* p_limit = p + face->kern_table_size;
p += 4;
mask = 0x0001;
- for ( count = face->num_kern_tables; count > 0; count--, mask <<= 1 )
+ for ( count = face->num_kern_tables;
+ count > 0 && p + 6 <= p_limit;
+ count--, mask <<= 1 )
{
FT_Byte* base = p;
FT_Byte* next = base;
FT_UInt version = FT_NEXT_USHORT( p );
FT_UInt length = FT_NEXT_USHORT( p );
FT_UInt coverage = FT_NEXT_USHORT( p );
+ FT_UInt num_pairs;
FT_Int value = 0;
FT_UNUSED( version );
@@ -200,21 +207,27 @@
next = base + length;
+ if ( next > p_limit ) /* handle broken table */
+ next = p_limit;
+
if ( ( face->kern_avail_bits & mask ) == 0 )
goto NextTable;
if ( p + 8 > next )
goto NextTable;
+ num_pairs = FT_NEXT_USHORT( p );
+ p += 6;
+
+ if ( ( next - p ) / 6 < (int)num_pairs ) /* handle broken count */
+ num_pairs = (FT_UInt)( ( next - p ) / 6 );
+
switch ( coverage >> 8 )
{
case 0:
{
- FT_UInt num_pairs = FT_NEXT_USHORT( p );
- FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph );
-
+ FT_ULong key0 = TT_KERN_INDEX( left_glyph, right_glyph );
- p += 6;
if ( face->kern_order_bits & mask ) /* binary search */
{