freetype-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[freetype2] OpenType-1.8 54d9993: Corrections to parse fonts following 1


From: Dave Arnold
Subject: [freetype2] OpenType-1.8 54d9993: Corrections to parse fonts following 1.8 spec.
Date: Wed, 19 Oct 2016 04:26:35 +0000 (UTC)

branch: OpenType-1.8
commit 54d9993505557af909d92291e1db549a2d4643e8
Author: Dave Arnold <address@hidden>
Commit: Dave Arnold <address@hidden>

    Corrections to parse fonts following 1.8 spec.
    
    INDEX count for CFF2 is 32 bits, while CFF is 16 bits
    This means INDEX header size is either 5 or 3 bytes.
    
    CFF2 header size is 5 bytes, while CFF is 4 bytes.
    In CFF2, offSize field is length of the Top DICT data and is 16 bits.
    
    Blend operator has changed from 31 to 23.
---
 src/cff/cffload.c  |   63 ++++++++++++++++++++++++++++++++++------------------
 src/cff/cfftoken.h |    2 +-
 src/cff/cfftypes.h |    4 +++-
 3 files changed, 45 insertions(+), 24 deletions(-)

diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 1342368..112a021 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -225,19 +225,33 @@
   static FT_Error
   cff_index_init( CFF_Index  idx,
                   FT_Stream  stream,
-                  FT_Bool    load )
+                  FT_Bool    load,
+                  FT_Bool    cff2 )
   {
     FT_Error   error;
     FT_Memory  memory = stream->memory;
-    FT_UShort  count;
+    FT_UInt    count;
 
 
     FT_MEM_ZERO( idx, sizeof ( *idx ) );
 
     idx->stream = stream;
     idx->start  = FT_STREAM_POS();
-    if ( !FT_READ_USHORT( count ) &&
-         count > 0                )
+
+    if ( cff2 )
+    {
+      if ( FT_READ_ULONG( count ) )
+        goto Exit;
+      idx->hdr_size = 5;
+    }
+    else
+    {
+      if ( FT_READ_USHORT( count ) )
+        goto Exit;
+      idx->hdr_size = 3;
+    }
+
+    if ( count > 0 )
     {
       FT_Byte   offsize;
       FT_ULong  size;
@@ -258,7 +272,7 @@
       idx->off_size = offsize;
       size          = (FT_ULong)( count + 1 ) * offsize;
 
-      idx->data_offset = idx->start + 3 + size;
+      idx->data_offset = idx->start + idx->hdr_size + size;
 
       if ( FT_STREAM_SKIP( size - offsize ) )
         goto Exit;
@@ -335,7 +349,7 @@
       data_size = (FT_ULong)( idx->count + 1 ) * offsize;
 
       if ( FT_NEW_ARRAY( idx->offsets, idx->count + 1 ) ||
-           FT_STREAM_SEEK( idx->start + 3 )             ||
+           FT_STREAM_SEEK( idx->start + idx->hdr_size ) ||
            FT_FRAME_ENTER( data_size )                  )
         goto Exit;
 
@@ -493,7 +507,7 @@
         FT_ULong  pos = element * idx->off_size;
 
 
-        if ( FT_STREAM_SEEK( idx->start + 3 + pos ) )
+        if ( FT_STREAM_SEEK( idx->start + idx->hdr_size + pos ) )
           goto Exit;
 
         off1 = cff_index_read_offset( idx, &error );
@@ -1478,6 +1492,7 @@
     FT_ULong         dict_len;
     CFF_FontRecDict  top  = &font->font_dict;
     CFF_Private      priv = &font->private_dict;
+    FT_Bool          cff2 = (code == CFF2_CODE_TOPDICT );
 
 
     cff_parser_init( &parser,
@@ -1582,7 +1597,7 @@
                            priv->local_subrs_offset ) )
         goto Exit;
 
-      error = cff_index_init( &font->local_subrs_index, stream, 1 );
+      error = cff_index_init( &font->local_subrs_index, stream, 1, cff2 );
       if ( error )
         goto Exit;
 
@@ -1622,11 +1637,10 @@
 #undef  FT_STRUCTURE
 #define FT_STRUCTURE  CFF_FontRec
 
-      FT_FRAME_START( 4 ),
+      FT_FRAME_START( 3 ),
         FT_FRAME_BYTE( version_major ),
         FT_FRAME_BYTE( version_minor ),
         FT_FRAME_BYTE( header_size ),
-        FT_FRAME_BYTE( absolute_offsize ),
       FT_FRAME_END
     };
 
@@ -1653,16 +1667,21 @@
 
     /* check format */
     if ( font->version_major != ( cff2 ? 2 : 1 ) ||
-         font->header_size      < 4 ||
-         ( !cff2 && font->absolute_offsize > 4 ) )
+         font->header_size      < 4 )
     {
       FT_TRACE2(( "  not a CFF font header\n" ));
       error = FT_THROW( Unknown_File_Format );
       goto Exit;
     }
 
+    if ( cff2 )
+    {
+      if ( FT_READ_USHORT( font->top_dict_length ) )
+        goto Exit;
+    }
+
     /* skip the rest of the header */
-    if ( FT_STREAM_SKIP( font->header_size - 4 ) )
+    if ( FT_STREAM_SEEK( base_offset + font->header_size ) )
       goto Exit;
 
     if ( cff2 )
@@ -1674,28 +1693,28 @@
       /* length of data, but leave count at zero as an indicator   */
       FT_ZERO( &font->font_dict_index );
       font->font_dict_index.data_offset = FT_STREAM_POS();
-      font->font_dict_index.data_size = font->absolute_offsize;
+      font->font_dict_index.data_size = font->top_dict_length;
 
       /* skip the top dict data for now, we'll parse it later      */
-      if ( FT_STREAM_SKIP( font->absolute_offsize ) )
+      if ( FT_STREAM_SKIP( font->top_dict_length ) )
         goto Exit;
 
       /* next, read the global subrs index                         */
       if ( FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
-                                       stream, 1 ) ) )
+                                       stream, 1, cff2 ) ) )
         goto Exit;
     }
     else
     {
       /* for CFF, read the name, top dict, string and global subrs index */
       if ( FT_SET_ERROR( cff_index_init( &font->name_index,
-                                       stream, 0 ) )                       ||
+                                       stream, 0, cff2 ) )                 ||
          FT_SET_ERROR( cff_index_init( &font->font_dict_index,
-                                       stream, 0 ) )                       ||
+                                       stream, 0, cff2 ) )                 ||
          FT_SET_ERROR( cff_index_init( &string_index,
-                                       stream, 1 ) )                       ||
+                                       stream, 1, cff2 ) )                 ||
          FT_SET_ERROR( cff_index_init( &font->global_subrs_index,
-                                       stream, 1 ) )                       ||
+                                       stream, 1, cff2 ) )                 ||
          FT_SET_ERROR( cff_index_get_pointers( &string_index,
                                                &font->strings,
                                                &font->string_pool,
@@ -1755,7 +1774,7 @@
     if ( FT_STREAM_SEEK( base_offset + dict->charstrings_offset ) )
       goto Exit;
 
-    error = cff_index_init( &font->charstrings_index, stream, 0 );
+    error = cff_index_init( &font->charstrings_index, stream, 0, cff2 );
     if ( error )
       goto Exit;
 
@@ -1773,7 +1792,7 @@
       if ( FT_STREAM_SEEK( base_offset + dict->cid_fd_array_offset ) )
         goto Exit;
 
-      error = cff_index_init( &fd_index, stream, 0 );
+      error = cff_index_init( &fd_index, stream, 0, cff2 );
       if ( error )
         goto Exit;
 
diff --git a/src/cff/cfftoken.h b/src/cff/cfftoken.h
index c6712da..a1b8ae6 100644
--- a/src/cff/cfftoken.h
+++ b/src/cff/cfftoken.h
@@ -144,7 +144,7 @@
   CFF_FIELD_NUM       ( 0x111, language_group,         "LanguageGroup" )
   CFF_FIELD_FIXED     ( 0x112, expansion_factor,       "ExpansionFactor" )
   CFF_FIELD_NUM       ( 22,    vsindex,                "vsindex" )
-  CFF_FIELD_BLEND     ( 31,                            "blend" )
+  CFF_FIELD_BLEND     ( 23,                            "blend" )
   CFF_FIELD_NUM       ( 19,    local_subrs_offset,     "Subrs" )
 
 
diff --git a/src/cff/cfftypes.h b/src/cff/cfftypes.h
index 379c1d0..c6ed4df 100644
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -64,6 +64,7 @@ FT_BEGIN_HEADER
   {
     FT_Stream  stream;
     FT_ULong   start;
+    FT_UInt    hdr_size;
     FT_UInt    count;
     FT_Byte    off_size;
     FT_ULong   data_offset;
@@ -272,7 +273,8 @@ FT_BEGIN_HEADER
     FT_Byte          version_major;
     FT_Byte          version_minor;
     FT_Byte          header_size;
-    FT_Byte          absolute_offsize;  /* cff2_top_dict_length */
+
+    FT_UInt          top_dict_length;   /* cff2 only */
 
     FT_Bool          cff2;
 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]