[pfr] Robustify bitmap strike handling (#47514).
We did a binary search for a charcode without ensuring that the searched data is ordered. Validating the order is now done lazily, this is, the first access to a bitmap glyph triggers the order check in the corresponding bitmap strike. * src/pfr/pfrtypes.h (PFR_BitmapFlags): New values `PFR_BITMAP_VALID_CHARCODES' and `PFR_BITMAP_CHARCODES_VALIDATED'. * src/pfr/pfrsbit.c (pfr_lookup_bitmap_data): Make `flags' argument a pointer. Handle new PFR_BITMAP_XXX flags. (pfr_slot_load_bitmap): Updated.
This commit is contained in:
parent
0003cb9162
commit
b069a590a9
18
ChangeLog
18
ChangeLog
|
@ -1,4 +1,20 @@
|
||||||
2016-03-25 Werner Lemberg <wl@gnu.org>
|
2016-03-26 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
|
[pfr] Robustify bitmap strike handling (#47514).
|
||||||
|
|
||||||
|
We did a binary search for a charcode without ensuring that the
|
||||||
|
searched data is ordered. Validating the order is now done lazily,
|
||||||
|
this is, the first access to a bitmap glyph triggers the order check
|
||||||
|
in the corresponding bitmap strike.
|
||||||
|
|
||||||
|
* src/pfr/pfrtypes.h (PFR_BitmapFlags): New values
|
||||||
|
`PFR_BITMAP_VALID_CHARCODES' and `PFR_BITMAP_CHARCODES_VALIDATED'.
|
||||||
|
|
||||||
|
* src/pfr/pfrsbit.c (pfr_lookup_bitmap_data): Make `flags' argument
|
||||||
|
a pointer. Handle new PFR_BITMAP_XXX flags.
|
||||||
|
(pfr_slot_load_bitmap): Updated.
|
||||||
|
|
||||||
|
2016-03-26 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
[pfr] Fix handling of compound glyphs.
|
[pfr] Fix handling of compound glyphs.
|
||||||
|
|
||||||
|
|
|
@ -277,24 +277,76 @@
|
||||||
pfr_lookup_bitmap_data( FT_Byte* base,
|
pfr_lookup_bitmap_data( FT_Byte* base,
|
||||||
FT_Byte* limit,
|
FT_Byte* limit,
|
||||||
FT_UInt count,
|
FT_UInt count,
|
||||||
FT_UInt flags,
|
FT_UInt* flags,
|
||||||
FT_UInt char_code,
|
FT_UInt char_code,
|
||||||
FT_ULong* found_offset,
|
FT_ULong* found_offset,
|
||||||
FT_ULong* found_size )
|
FT_ULong* found_size )
|
||||||
{
|
{
|
||||||
FT_UInt left, right, char_len;
|
FT_UInt left, right, char_len;
|
||||||
FT_Bool two = FT_BOOL( flags & PFR_BITMAP_2BYTE_CHARCODE );
|
FT_Bool two = FT_BOOL( *flags & PFR_BITMAP_2BYTE_CHARCODE );
|
||||||
FT_Byte* buff;
|
FT_Byte* buff;
|
||||||
|
|
||||||
|
|
||||||
char_len = 4;
|
char_len = 4;
|
||||||
if ( two )
|
if ( two )
|
||||||
char_len += 1;
|
char_len += 1;
|
||||||
if ( flags & PFR_BITMAP_2BYTE_SIZE )
|
if ( *flags & PFR_BITMAP_2BYTE_SIZE )
|
||||||
char_len += 1;
|
char_len += 1;
|
||||||
if ( flags & PFR_BITMAP_3BYTE_OFFSET )
|
if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
|
||||||
char_len += 1;
|
char_len += 1;
|
||||||
|
|
||||||
|
if ( !( *flags & PFR_BITMAP_CHARCODES_VALIDATED ) )
|
||||||
|
{
|
||||||
|
FT_Byte* p;
|
||||||
|
FT_Byte* lim;
|
||||||
|
FT_UInt code;
|
||||||
|
FT_Long prev_code;
|
||||||
|
|
||||||
|
|
||||||
|
*flags |= PFR_BITMAP_VALID_CHARCODES;
|
||||||
|
prev_code = -1;
|
||||||
|
lim = base + count * char_len;
|
||||||
|
|
||||||
|
if ( lim > limit )
|
||||||
|
{
|
||||||
|
FT_TRACE0(( "pfr_lookup_bitmap_data:"
|
||||||
|
" number of bitmap records too large,\n"
|
||||||
|
" "
|
||||||
|
" thus ignoring all bitmaps in this strike\n" ));
|
||||||
|
*flags &= ~PFR_BITMAP_VALID_CHARCODES;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* check whether records are sorted by code */
|
||||||
|
for ( p = base; p < lim; p += char_len )
|
||||||
|
{
|
||||||
|
if ( two )
|
||||||
|
code = FT_PEEK_USHORT( p );
|
||||||
|
else
|
||||||
|
code = *p;
|
||||||
|
|
||||||
|
if ( code <= prev_code )
|
||||||
|
{
|
||||||
|
FT_TRACE0(( "pfr_lookup_bitmap_data:"
|
||||||
|
" bitmap records are not sorted,\n"
|
||||||
|
" "
|
||||||
|
" thus ignoring all bitmaps in this strike\n" ));
|
||||||
|
*flags &= ~PFR_BITMAP_VALID_CHARCODES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
prev_code = code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*flags |= PFR_BITMAP_CHARCODES_VALIDATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ignore bitmaps in case table is not valid */
|
||||||
|
/* (this might be sanitized, but PFR is dead...) */
|
||||||
|
if ( !( *flags & PFR_BITMAP_VALID_CHARCODES ) )
|
||||||
|
goto Fail;
|
||||||
|
|
||||||
left = 0;
|
left = 0;
|
||||||
right = count;
|
right = count;
|
||||||
|
|
||||||
|
@ -306,11 +358,6 @@
|
||||||
middle = ( left + right ) >> 1;
|
middle = ( left + right ) >> 1;
|
||||||
buff = base + middle * char_len;
|
buff = base + middle * char_len;
|
||||||
|
|
||||||
/* check that we are not outside of the table -- */
|
|
||||||
/* this is possible with broken fonts... */
|
|
||||||
if ( buff + char_len > limit )
|
|
||||||
goto Fail;
|
|
||||||
|
|
||||||
if ( two )
|
if ( two )
|
||||||
code = PFR_NEXT_USHORT( buff );
|
code = PFR_NEXT_USHORT( buff );
|
||||||
else
|
else
|
||||||
|
@ -332,12 +379,12 @@
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Found_It:
|
Found_It:
|
||||||
if ( flags & PFR_BITMAP_2BYTE_SIZE )
|
if ( *flags & PFR_BITMAP_2BYTE_SIZE )
|
||||||
*found_size = PFR_NEXT_USHORT( buff );
|
*found_size = PFR_NEXT_USHORT( buff );
|
||||||
else
|
else
|
||||||
*found_size = PFR_NEXT_BYTE( buff );
|
*found_size = PFR_NEXT_BYTE( buff );
|
||||||
|
|
||||||
if ( flags & PFR_BITMAP_3BYTE_OFFSET )
|
if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
|
||||||
*found_offset = PFR_NEXT_ULONG( buff );
|
*found_offset = PFR_NEXT_ULONG( buff );
|
||||||
else
|
else
|
||||||
*found_offset = PFR_NEXT_USHORT( buff );
|
*found_offset = PFR_NEXT_USHORT( buff );
|
||||||
|
@ -588,7 +635,7 @@
|
||||||
pfr_lookup_bitmap_data( stream->cursor,
|
pfr_lookup_bitmap_data( stream->cursor,
|
||||||
stream->limit,
|
stream->limit,
|
||||||
strike->num_bitmaps,
|
strike->num_bitmaps,
|
||||||
strike->flags,
|
&strike->flags,
|
||||||
character->char_code,
|
character->char_code,
|
||||||
&gps_offset,
|
&gps_offset,
|
||||||
&gps_size );
|
&gps_size );
|
||||||
|
|
|
@ -121,6 +121,10 @@ FT_BEGIN_HEADER
|
||||||
|
|
||||||
typedef enum PFR_BitmapFlags_
|
typedef enum PFR_BitmapFlags_
|
||||||
{
|
{
|
||||||
|
/* not part of the specification but used for implementation */
|
||||||
|
PFR_BITMAP_VALID_CHARCODES = 0x80,
|
||||||
|
PFR_BITMAP_CHARCODES_VALIDATED = 0x40,
|
||||||
|
|
||||||
PFR_BITMAP_3BYTE_OFFSET = 4,
|
PFR_BITMAP_3BYTE_OFFSET = 4,
|
||||||
PFR_BITMAP_2BYTE_SIZE = 2,
|
PFR_BITMAP_2BYTE_SIZE = 2,
|
||||||
PFR_BITMAP_2BYTE_CHARCODE = 1
|
PFR_BITMAP_2BYTE_CHARCODE = 1
|
||||||
|
|
Loading…
Reference in New Issue