freetype-commit
[Top][All Lists]
Advanced

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

[freetype2-demos] master 03fd5d8: * src/ftdump.c (Print_Glyfs, Print_Pro


From: Werner Lemberg
Subject: [freetype2-demos] master 03fd5d8: * src/ftdump.c (Print_Glyfs, Print_Programs): Handle empty glyphs.
Date: Wed, 16 Jun 2021 23:49:32 -0400 (EDT)

branch: master
commit 03fd5d876c58ada7eb248ff86a92bc420399855f
Author: Alexei Podtelezhnikov <apodtele@gmail.com>
Commit: Alexei Podtelezhnikov <apodtele@gmail.com>

    * src/ftdump.c (Print_Glyfs, Print_Programs): Handle empty glyphs.
---
 ChangeLog    |   4 ++
 src/ftdump.c | 120 ++++++++++++++++++++++++++++++++++++++++-------------------
 2 files changed, 85 insertions(+), 39 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 5d18995..538df71 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2021-06-15  Alexei Podtelezhnikov  <apodtele@gmail.com>
+
+       * src/ftdump.c (Print_Glyfs, Print_Programs): Handle empty glyphs.
+
 2021-06-14  Alexei Podtelezhnikov  <apodtele@gmail.com>
 
        [ftlint] Report integral X- and Y-acutance.
diff --git a/src/ftdump.c b/src/ftdump.c
index 8e0bef3..285946d 100644
--- a/src/ftdump.c
+++ b/src/ftdump.c
@@ -728,7 +728,7 @@
   {
     FT_ULong    fpgm_length = 0;
     FT_ULong    prep_length = 0;
-    FT_ULong    loca_length = 0;
+    FT_ULong    loca_length;
     FT_ULong    glyf_length = 0;
     FT_UShort   i;
     FT_Byte*    buffer = NULL;
@@ -770,50 +770,68 @@
     Print_Bytecode( buffer, (FT_UShort)prep_length, "prep" );
 
   Glyf:
-    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
-    if ( error || glyf_length == 0 )
+    head =     (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
+    maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
+
+    if ( head == NULL || maxp == NULL )
       goto Exit;
 
-    buffer = (FT_Byte*)realloc( buffer, glyf_length );
-    if ( buffer == NULL )
+    loca_length = head->Index_To_Loc_Format ? 4 * maxp->numGlyphs + 4
+                                            : 2 * maxp->numGlyphs + 2;
+
+    offset = (FT_Byte*)malloc( loca_length );
+    if ( offset == NULL )
       goto Exit;
 
-    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
+    error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
     if ( error )
       goto Exit;
 
-    error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, NULL, &loca_length );
-    if ( error || loca_length == 0 )
+    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
+    if ( error || glyf_length == 0 )
       goto Exit;
 
-    offset = (FT_Byte*)malloc( loca_length );
-    if ( offset == NULL )
+    buffer = (FT_Byte*)realloc( buffer, glyf_length );
+    if ( buffer == NULL )
       goto Exit;
 
-    error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
+    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
     if ( error )
       goto Exit;
 
-    head =     (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
-    maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
-
     for ( i = 0; i < maxp->numGlyphs; i++ )
     {
-      FT_UInt32  loc;
+      FT_UInt32  loc, end;
       FT_UInt16  len;
       char       tag[5];
 
 
       if ( head->Index_To_Loc_Format )
+      {
         loc = (FT_UInt32)offset[4 * i    ] << 24 |
               (FT_UInt32)offset[4 * i + 1] << 16 |
               (FT_UInt32)offset[4 * i + 2] << 8  |
               (FT_UInt32)offset[4 * i + 3];
+        end = (FT_UInt32)offset[4 * i + 4] << 24 |
+              (FT_UInt32)offset[4 * i + 5] << 16 |
+              (FT_UInt32)offset[4 * i + 6] << 8  |
+              (FT_UInt32)offset[4 * i + 7];
+      }
       else
+      {
         loc = (FT_UInt32)offset[2 * i    ] << 9 |
               (FT_UInt32)offset[2 * i + 1] << 1;
+        end = (FT_UInt32)offset[2 * i + 2] << 9 |
+              (FT_UInt32)offset[2 * i + 3] << 1;
+      }
+
+      if ( end > glyf_length )
+        end = glyf_length;
 
-      if ( loc >= glyf_length )
+      if ( loc == end )
+        continue;
+
+      if ( loc + 1 >= end )
       {
         printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
         continue;
@@ -829,7 +847,7 @@
 
         do
         {
-          if ( loc >= glyf_length )
+          if ( loc + 1 >= end )
           {
             printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
             goto Continue;
@@ -852,7 +870,7 @@
       else
         loc += 2 * len;
 
-      if ( loc >= glyf_length )
+      if ( loc + 1 >= end )
       {
         printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
         continue;
@@ -865,7 +883,7 @@
 
       loc += 2;
 
-      if ( len >= glyf_length || loc >= glyf_length - len )
+      if ( loc + len > end )
       {
         printf( "\nglyf program %hd: invalid size (%d)\n", i, len );
         continue;
@@ -888,7 +906,7 @@
   static void
   Print_Glyfs( FT_Face  face )
   {
-    FT_ULong    loca_length = 0;
+    FT_ULong    loca_length;
     FT_ULong    glyf_length = 0;
     FT_UShort   i;
     FT_Byte*    buffer = NULL;
@@ -898,55 +916,77 @@
     FT_Int      simple_overlap    = 0;
     FT_Int      composite         = 0;
     FT_Int      composite_overlap = 0;
+    FT_Int      empty             = 0;
 
     TT_Header*      head;
     TT_MaxProfile*  maxp;
 
 
-    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
-    if ( error || glyf_length == 0 )
-      goto Exit;
+    head =     (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
+    maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
 
-    buffer = (FT_Byte*)malloc( glyf_length );
-    if ( buffer == NULL )
+    if ( head == NULL || maxp == NULL )
+      return;
+
+    loca_length = head->Index_To_Loc_Format ? 4 * maxp->numGlyphs + 4
+                                            : 2 * maxp->numGlyphs + 2;
+
+    offset = (FT_Byte*)malloc( loca_length );
+    if ( offset == NULL )
       goto Exit;
 
-    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
+    error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
     if ( error )
       goto Exit;
 
-    error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, NULL, &loca_length );
-    if ( error || loca_length == 0 )
+    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, NULL, &glyf_length );
+    if ( error || glyf_length == 0 )
       goto Exit;
 
-    offset = (FT_Byte*)malloc( loca_length );
-    if ( offset == NULL )
+    buffer = (FT_Byte*)malloc( glyf_length );
+    if ( buffer == NULL )
       goto Exit;
 
-    error = FT_Load_Sfnt_Table( face, TTAG_loca, 0, offset, &loca_length );
+    error = FT_Load_Sfnt_Table( face, TTAG_glyf, 0, buffer, &glyf_length );
     if ( error )
       goto Exit;
 
-    head =     (TT_Header*)FT_Get_Sfnt_Table( face, FT_SFNT_HEAD );
-    maxp = (TT_MaxProfile*)FT_Get_Sfnt_Table( face, FT_SFNT_MAXP );
-
     for ( i = 0; i < maxp->numGlyphs; i++ )
     {
-      FT_UInt32  loc;
+      FT_UInt32  loc, end;
       FT_UInt16  len;
       FT_UShort  flags;
 
 
       if ( head->Index_To_Loc_Format )
+      {
         loc = (FT_UInt32)offset[4 * i    ] << 24 |
               (FT_UInt32)offset[4 * i + 1] << 16 |
               (FT_UInt32)offset[4 * i + 2] << 8  |
               (FT_UInt32)offset[4 * i + 3];
+        end = (FT_UInt32)offset[4 * i + 4] << 24 |
+              (FT_UInt32)offset[4 * i + 5] << 16 |
+              (FT_UInt32)offset[4 * i + 6] << 8  |
+              (FT_UInt32)offset[4 * i + 7];
+      }
       else
+      {
         loc = (FT_UInt32)offset[2 * i    ] << 9 |
               (FT_UInt32)offset[2 * i + 1] << 1;
+        end = (FT_UInt32)offset[2 * i + 2] << 9 |
+              (FT_UInt32)offset[2 * i + 3] << 1;
+      }
+
+      if ( end > glyf_length )
+        end = glyf_length;
+
+      if ( loc == end )
+      {
+        empty++;
+        continue;
+      }
 
-      if ( loc >= glyf_length )
+      if ( loc + 1 >= end )
       {
         printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
         continue;
@@ -959,7 +999,7 @@
       {
         composite++;
 
-        if ( loc >= glyf_length )
+        if ( loc + 1 >= end )
         {
           printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
           continue;
@@ -976,7 +1016,7 @@
 
       loc += 2 * len;
 
-      if ( loc >= glyf_length )
+      if ( loc + 1 >= end )
       {
         printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
         continue;
@@ -986,7 +1026,7 @@
 
       loc += 2 + len;
 
-      if ( len >= glyf_length )
+      if ( len >= end )
       {
         printf( "\nglyf program %hd: invalid offset (%d)\n", i, loc );
         continue;
@@ -1005,6 +1045,8 @@
     printf( composite_overlap ? ", with overlap flagged in %d\n"
                               : "\n",
             composite_overlap );
+    if ( empty )
+      printf( "%s%d\n", Name_Field( "   empty" ), empty );
 
   Exit:
     free( buffer );



reply via email to

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