Fix Savannah bug #25781.
We now simply check for a valid `offset', no longer handling `delta = 1' specially. * src/sfnt/ttcmap.c (tt_cmap4_validate): Don't check `delta' for last segment. (tt_cmap4_set_range, tt_cmap4_char_map_linear, tt_cmap4_char_map_binary): Check offset.
This commit is contained in:
parent
34ca21edc6
commit
801e7bae3a
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2009-03-11 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
Fix Savannah bug #25781.
|
||||
We now simply check for a valid `offset', no longer handling `delta
|
||||
= 1' specially.
|
||||
|
||||
* src/sfnt/ttcmap.c (tt_cmap4_validate): Don't check `delta' for
|
||||
last segment.
|
||||
(tt_cmap4_set_range, tt_cmap4_char_map_linear,
|
||||
tt_cmap4_char_map_binary): Check offset.
|
||||
|
||||
2009-03-11 Werner Lemberg <wl@gnu.org>
|
||||
|
||||
* src/base/Jamfile: Fix handling of ftadvanc.c.
|
||||
|
|
|
@ -231,7 +231,7 @@
|
|||
/* language 4 USHORT Mac language code */
|
||||
/* keys 6 USHORT[256] sub-header keys */
|
||||
/* subs 518 SUBHEAD[NSUBS] sub-headers array */
|
||||
/* glyph_ids 518+NSUB*8 USHORT[] glyph id array */
|
||||
/* glyph_ids 518+NSUB*8 USHORT[] glyph ID array */
|
||||
/* */
|
||||
/* The `keys' table is used to map charcode high-bytes to sub-headers. */
|
||||
/* The value of `NSUBS' is the number of sub-headers defined in the */
|
||||
|
@ -282,7 +282,7 @@
|
|||
FT_UInt n, max_subs;
|
||||
FT_Byte* keys; /* keys table */
|
||||
FT_Byte* subs; /* sub-headers */
|
||||
FT_Byte* glyph_ids; /* glyph id array */
|
||||
FT_Byte* glyph_ids; /* glyph ID array */
|
||||
|
||||
|
||||
if ( table + length > valid->limit || length < 6 + 512 )
|
||||
|
@ -605,14 +605,14 @@
|
|||
/* each segment; can be */
|
||||
/* zero */
|
||||
/* */
|
||||
/* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph id */
|
||||
/* glyphIds 16+NUM_SEGS*8 USHORT[] array of glyph ID */
|
||||
/* ranges */
|
||||
/* */
|
||||
/* Character codes are modelled by a series of ordered (increasing) */
|
||||
/* intervals called segments. Each segment has start and end codes, */
|
||||
/* provided by the `startCount' and `endCount' arrays. Segments must */
|
||||
/* not be overlapping and the last segment should always contain the */
|
||||
/* `0xFFFF' endCount. */
|
||||
/* not overlap, and the last segment should always contain the value */
|
||||
/* 0xFFFF for `endCount'. */
|
||||
/* */
|
||||
/* The fields `searchRange', `entrySelector' and `rangeShift' are better */
|
||||
/* ignored (they are traces of over-engineering in the TrueType */
|
||||
|
@ -629,10 +629,10 @@
|
|||
/* the segment, and the value of `idDelta' is added to it. */
|
||||
/* */
|
||||
/* */
|
||||
/* Finally, note that certain fonts contain invalid charmaps that */
|
||||
/* contain end=0xFFFF, start=0xFFFF, delta=0x0001, offset=0xFFFF at the */
|
||||
/* of their charmaps (e.g. opens___.ttf which comes with OpenOffice.org) */
|
||||
/* we need special code to deal with them correctly... */
|
||||
/* Finally, note that a lot of fonts contain an invalid last segment, */
|
||||
/* where `start' and `end' are correctly set to 0xFFFF but both `delta' */
|
||||
/* and `offset' are incorrect (e.g., `opens___.ttf' which comes with */
|
||||
/* OpenOffice.org). We need special code to deal with them correctly. */
|
||||
/* */
|
||||
|
||||
#ifdef TT_CONFIG_CMAP_FORMAT_4
|
||||
|
@ -697,13 +697,22 @@
|
|||
p += num_ranges * 2;
|
||||
offset = FT_PEEK_USHORT( p );
|
||||
|
||||
/* some fonts handle the last segment incorrectly; */
|
||||
/* we have to catch it */
|
||||
/* some fonts have an incorrect last segment; */
|
||||
/* we have to catch it */
|
||||
if ( range_index >= num_ranges - 1 &&
|
||||
cmap->cur_start == 0xFFFFU &&
|
||||
cmap->cur_end == 0xFFFFU &&
|
||||
cmap->cur_delta == 0x1U )
|
||||
offset = 0;
|
||||
cmap->cur_end == 0xFFFFU )
|
||||
{
|
||||
TT_Face face = (TT_Face)cmap->cmap.cmap.charmap.face;
|
||||
FT_Byte* limit = face->cmap_table + face->cmap_size;
|
||||
|
||||
|
||||
if ( offset && p + offset + 2 > limit )
|
||||
{
|
||||
cmap->cur_delta = 1;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( offset != 0xFFFFU )
|
||||
{
|
||||
|
@ -870,7 +879,7 @@
|
|||
offsets = deltas + num_segs * 2;
|
||||
glyph_ids = offsets + num_segs * 2;
|
||||
|
||||
/* check last segment, its end count must be 0xFFFF */
|
||||
/* check last segment; its end count value must be 0xFFFF */
|
||||
if ( valid->level >= FT_VALIDATE_PARANOID )
|
||||
{
|
||||
p = ends + ( num_segs - 1 ) * 2;
|
||||
|
@ -899,10 +908,10 @@
|
|||
if ( start > end )
|
||||
FT_INVALID_DATA;
|
||||
|
||||
/* this test should be performed at default validation level; */
|
||||
/* unfortunately, some popular Asian fonts present overlapping */
|
||||
/* ranges in their charmaps */
|
||||
/* */
|
||||
/* this test should be performed at default validation level; */
|
||||
/* unfortunately, some popular Asian fonts have overlapping */
|
||||
/* ranges in their charmaps */
|
||||
/* */
|
||||
if ( start <= last_end && n > 0 )
|
||||
{
|
||||
if ( valid->level >= FT_VALIDATE_TIGHT )
|
||||
|
@ -910,7 +919,7 @@
|
|||
else
|
||||
{
|
||||
/* allow overlapping segments, provided their start points */
|
||||
/* and end points, respectively, are in ascending order. */
|
||||
/* and end points, respectively, are in ascending order */
|
||||
/* */
|
||||
if ( last_start > start || last_end > end )
|
||||
error |= TT_CMAP_FLAG_UNSORTED;
|
||||
|
@ -921,7 +930,7 @@
|
|||
|
||||
if ( offset && offset != 0xFFFFU )
|
||||
{
|
||||
p += offset; /* start of glyph id array */
|
||||
p += offset; /* start of glyph ID array */
|
||||
|
||||
/* check that we point within the glyph IDs table only */
|
||||
if ( valid->level >= FT_VALIDATE_TIGHT )
|
||||
|
@ -930,11 +939,18 @@
|
|||
p + ( end - start + 1 ) * 2 > table + length )
|
||||
FT_INVALID_DATA;
|
||||
}
|
||||
/* some fonts handle the last segment incorrectly */
|
||||
else if ( n != num_segs - 1 ||
|
||||
!( start == 0xFFFFU &&
|
||||
end == 0xFFFFU &&
|
||||
delta == 0x1U ) )
|
||||
/* Some fonts handle the last segment incorrectly. In */
|
||||
/* theory, 0xFFFF might point to an ordinary glyph -- */
|
||||
/* a cmap 4 is versatile and could be used for any */
|
||||
/* encoding, not only Unicode. However, reality shows */
|
||||
/* that far too many fonts are sloppy and incorrectly */
|
||||
/* set all fields but `start' and `end' for the last */
|
||||
/* segment if it contains only a single character. */
|
||||
/* */
|
||||
/* We thus omit the test here, delaying it to the */
|
||||
/* routines which actually access the cmap. */
|
||||
else if ( n != num_segs - 1 ||
|
||||
!( start == 0xFFFFU && end == 0xFFFFU ) )
|
||||
{
|
||||
if ( p < glyph_ids ||
|
||||
p + ( end - start + 1 ) * 2 > valid->limit )
|
||||
|
@ -965,9 +981,9 @@
|
|||
/* some fonts (erroneously?) use a range offset of 0xFFFF */
|
||||
/* to mean missing glyph in cmap table */
|
||||
/* */
|
||||
if ( valid->level >= FT_VALIDATE_PARANOID ||
|
||||
n != num_segs - 1 ||
|
||||
!( start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U ) )
|
||||
if ( valid->level >= FT_VALIDATE_PARANOID ||
|
||||
n != num_segs - 1 ||
|
||||
!( start == 0xFFFFU && end == 0xFFFFU ) )
|
||||
FT_INVALID_DATA;
|
||||
}
|
||||
|
||||
|
@ -1025,11 +1041,21 @@
|
|||
p += num_segs2;
|
||||
offset = TT_PEEK_USHORT( p );
|
||||
|
||||
/* some fonts handle the last segment incorrectly; */
|
||||
/* we have to catch it */
|
||||
if ( i >= num_segs - 1 &&
|
||||
start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U )
|
||||
offset = 0;
|
||||
/* some fonts have an incorrect last segment; */
|
||||
/* we have to catch it */
|
||||
if ( i >= num_segs - 1 &&
|
||||
start == 0xFFFFU && end == 0xFFFFU )
|
||||
{
|
||||
TT_Face face = (TT_Face)cmap->cmap.charmap.face;
|
||||
FT_Byte* limit = face->cmap_table + face->cmap_size;
|
||||
|
||||
|
||||
if ( offset && p + offset + 2 > limit )
|
||||
{
|
||||
delta = 1;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if ( offset == 0xFFFFU )
|
||||
continue;
|
||||
|
@ -1110,11 +1136,21 @@
|
|||
p += num_segs2;
|
||||
offset = TT_PEEK_USHORT( p );
|
||||
|
||||
/* some fonts handle the last segment incorrectly; */
|
||||
/* we have to catch it */
|
||||
if ( mid >= num_segs - 1 &&
|
||||
start == 0xFFFFU && end == 0xFFFFU && delta == 0x1U )
|
||||
offset = 0;
|
||||
/* some fonts have an incorrect last segment; */
|
||||
/* we have to catch it */
|
||||
if ( mid >= num_segs - 1 &&
|
||||
start == 0xFFFFU && end == 0xFFFFU )
|
||||
{
|
||||
TT_Face face = (TT_Face)cmap->cmap.charmap.face;
|
||||
FT_Byte* limit = face->cmap_table + face->cmap_size;
|
||||
|
||||
|
||||
if ( offset && p + offset + 2 > limit )
|
||||
{
|
||||
delta = 1;
|
||||
offset = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* search the first segment containing `charcode' */
|
||||
if ( cmap->flags & TT_CMAP_FLAG_OVERLAPPING )
|
||||
|
@ -1580,7 +1616,7 @@
|
|||
/* */
|
||||
/* start 0 ULONG first charcode */
|
||||
/* end 4 ULONG last charcode */
|
||||
/* startId 8 ULONG start glyph id for the group */
|
||||
/* startId 8 ULONG start glyph ID for the group */
|
||||
/* */
|
||||
|
||||
#ifdef TT_CONFIG_CMAP_FORMAT_8
|
||||
|
@ -1962,7 +1998,7 @@
|
|||
/* */
|
||||
/* start 0 ULONG first charcode */
|
||||
/* end 4 ULONG last charcode */
|
||||
/* startId 8 ULONG start glyph id for the group */
|
||||
/* startId 8 ULONG start glyph ID for the group */
|
||||
/* */
|
||||
|
||||
#ifdef TT_CONFIG_CMAP_FORMAT_12
|
||||
|
|
Loading…
Reference in New Issue