ref: b069a590a9c9e6f06f4d1d5c16df732bd6483536
parent: 0003cb916224aa7d12b4cf4c619631ea8932b878
author: Werner Lemberg <[email protected]>
date: Sat Mar 26 04:00:07 EDT 2016
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,20 @@
-2016-03-25 Werner Lemberg <[email protected]>
+2016-03-26 Werner Lemberg <[email protected]>
+
+ [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 <[email protected]>
[pfr] Fix handling of compound glyphs.
--- a/src/pfr/pfrsbit.c
+++ b/src/pfr/pfrsbit.c
@@ -277,13 +277,13 @@
pfr_lookup_bitmap_data( FT_Byte* base,
FT_Byte* limit,
FT_UInt count,
- FT_UInt flags,
+ FT_UInt* flags,
FT_UInt char_code,
FT_ULong* found_offset,
FT_ULong* found_size )
{
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;
@@ -290,11 +290,63 @@
char_len = 4;
if ( two )
char_len += 1;
- if ( flags & PFR_BITMAP_2BYTE_SIZE )
+ if ( *flags & PFR_BITMAP_2BYTE_SIZE )
char_len += 1;
- if ( flags & PFR_BITMAP_3BYTE_OFFSET )
+ if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
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;
right = count;
@@ -306,11 +358,6 @@
middle = ( left + right ) >> 1;
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 )
code = PFR_NEXT_USHORT( buff );
else
@@ -332,12 +379,12 @@
return;
Found_It:
- if ( flags & PFR_BITMAP_2BYTE_SIZE )
+ if ( *flags & PFR_BITMAP_2BYTE_SIZE )
*found_size = PFR_NEXT_USHORT( buff );
else
*found_size = PFR_NEXT_BYTE( buff );
- if ( flags & PFR_BITMAP_3BYTE_OFFSET )
+ if ( *flags & PFR_BITMAP_3BYTE_OFFSET )
*found_offset = PFR_NEXT_ULONG( buff );
else
*found_offset = PFR_NEXT_USHORT( buff );
@@ -588,7 +635,7 @@
pfr_lookup_bitmap_data( stream->cursor,
stream->limit,
strike->num_bitmaps,
- strike->flags,
+ &strike->flags,
character->char_code,
&gps_offset,
&gps_size );
--- a/src/pfr/pfrtypes.h
+++ b/src/pfr/pfrtypes.h
@@ -121,6 +121,10 @@
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_2BYTE_SIZE = 2,
PFR_BITMAP_2BYTE_CHARCODE = 1