diff --git a/ChangeLog b/ChangeLog index 6f7f73705..793b5b209 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-12-31 Masatake YAMATO + + * src/gxvalid/gxvkern.c (gxv_kern_subtable_fmt0_pairs_validate): New function. + Checks uniqueness of the gid pairs. + (gxv_kern_subtable_fmt0_validate): Move some code to + `gxv_kern_subtable_fmt0_pairs_validate'. + 2006-12-22 David Turner * src/autofit/aflatin.c, src/truetype/ttgload.c: removing compiler diff --git a/src/gxvalid/gxvkern.c b/src/gxvalid/gxvkern.c index edc9af214..3b0e4b576 100644 --- a/src/gxvalid/gxvkern.c +++ b/src/gxvalid/gxvkern.c @@ -106,26 +106,19 @@ /* ============================= format 0 ============================== */ static void - gxv_kern_subtable_fmt0_validate( FT_Bytes table, - FT_Bytes limit, - GXV_Validator valid ) + gxv_kern_subtable_fmt0_pairs_validate( FT_Bytes table, + FT_Bytes limit, + FT_UShort nPairs, + GXV_Validator valid ) { - FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; - - FT_UShort nPairs; - FT_UShort unitSize; + FT_Bytes p = table; FT_UShort i; + FT_UShort last_gid_left = 0; + FT_UShort last_gid_right = 0; - GXV_NAME_ENTER( "kern subtable format0" ); - unitSize = 2 + 2 + 2; - nPairs = 0; - - /* nPairs, searchRange, entrySelector, rangeShift */ - GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); - gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); - p += 2 + 2 + 2 + 2; + GXV_NAME_ENTER( "kern format 0 paris" ); for ( i = 0; i < nPairs; i++ ) { @@ -133,17 +126,30 @@ FT_UShort gid_right; FT_Short kernValue; - /* TODO: should be checked pairs are unique. */ - - /* left */ gid_left = FT_NEXT_USHORT( p ); - gxv_glyphid_validate( gid_left, valid ); - - /* right */ gid_right = FT_NEXT_USHORT( p ); + + GXV_TRACE(( "left gid = %u, right gid = %u\n", gid_left, gid_right )); + gxv_glyphid_validate( gid_left, valid ); gxv_glyphid_validate( gid_right, valid ); + /* A pair of left and right gid must be uniqe and be sorted. */ + if ( gid_left == last_gid_left ) + { + if ( last_gid_right < gid_right ) + last_gid_right = gid_right; + else + FT_INVALID_DATA; + } + else if ( last_gid_left < gid_left ) + { + last_gid_left = gid_left; + last_gid_right = gid_right; + } + else + FT_INVALID_DATA; + /* skip the kern value */ kernValue = FT_NEXT_SHORT( p ); } @@ -151,6 +157,32 @@ GXV_EXIT; } + static void + gxv_kern_subtable_fmt0_validate( FT_Bytes table, + FT_Bytes limit, + GXV_Validator valid ) + { + FT_Bytes p = table + GXV_KERN_SUBTABLE_HEADER_SIZE; + + FT_UShort nPairs; + FT_UShort unitSize; + + + GXV_NAME_ENTER( "kern subtable format0" ); + + unitSize = 2 + 2 + 2; + nPairs = 0; + + /* nPairs, searchRange, entrySelector, rangeShift */ + GXV_LIMIT_CHECK( 2 + 2 + 2 + 2 ); + gxv_BinSrchHeader_validate( p, limit, &unitSize, &nPairs, valid ); + p += 2 + 2 + 2 + 2; + + gxv_kern_subtable_fmt0_pairs_validate( p, limit, nPairs, valid ); + + GXV_EXIT; + } + /* ============================= format 1 ============================== */