Commit 1e4d3dc8eaeffcc1b298304ae2dcfc05e8e44850

Ewald Hew 2017-09-25T07:47:10

Extend Adobe interpreter (callsubr). * src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_cmdCALLSUBR>: Type 1 mode. * src/psaux/psft.c (cf2_initLocalRegionBuffer): Add Type 1 mode.

diff --git a/ChangeLog b/ChangeLog
index 4641f1d..1e9c972 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,14 @@
 2017-09-25  Ewald Hew  <ewaldhew@gmail.com>
 
+	[psaux] Extend Adobe interpreter (callsubr).
+
+	* src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_cmdCALLSUBR>:
+	Type 1 mode.
+
+	* src/psaux/psft.c (cf2_initLocalRegionBuffer): Add Type 1 mode.
+
+2017-09-25  Ewald Hew  <ewaldhew@gmail.com>
+
 	[psaux] Extend Adobe interpreter (div, four-byte numbers).
 
 	* src/psaux/psintrp.c (cf2_interpT2CharString) <cf2_escDIV>: Add
diff --git a/src/psaux/psft.c b/src/psaux/psft.c
index ab19826..81d3fd8 100644
--- a/src/psaux/psft.c
+++ b/src/psaux/psft.c
@@ -718,14 +718,40 @@
     FT_ZERO( buf );
 
     idx = (CF2_UInt)( subrNum + decoder->locals_bias );
-    if ( idx >= decoder->num_locals )
+    if ( idx < 0 || idx >= decoder->num_locals )
       return TRUE;     /* error */
 
     FT_ASSERT( decoder->locals );
 
-    buf->start =
-    buf->ptr   = decoder->locals[idx];
-    buf->end   = decoder->locals[idx + 1];
+    buf->start = decoder->locals[idx];
+
+    if ( decoder->builder.is_t1 )
+    {
+      /* The Type 1 driver stores subroutines without the seed bytes. */
+      /* The CID driver stores subroutines with seed bytes.  This     */
+      /* case is taken care of when decoder->subrs_len == 0.          */
+      if ( decoder->locals_len )
+        buf->end     = buf->start + decoder->locals_len[idx];
+      else
+      {
+        /* We are using subroutines from a CID font.  We must adjust */
+        /* for the seed bytes.                                       */
+        buf->start  += ( decoder->lenIV >= 0 ? decoder->lenIV : 0 );
+        buf->end     = decoder->locals[idx + 1];
+      }
+
+      if ( !buf->start )
+      {
+        FT_ERROR(( "cf2_initLocalRegionBuffer (Type 1 mode):"
+                   " invoking empty subrs\n" ));
+      }
+    }
+    else
+    {
+      buf->end   = decoder->locals[idx + 1];
+    }
+
+    buf->ptr = buf->start;
 
     return FALSE;      /* success */
   }
diff --git a/src/psaux/psintrp.c b/src/psaux/psintrp.c
index 34607ca..7ee3a25 100644
--- a/src/psaux/psintrp.c
+++ b/src/psaux/psintrp.c
@@ -975,7 +975,8 @@
           FT_TRACE4(( op1 == cf2_cmdCALLGSUBR ? " callgsubr"
                                               : " callsubr" ));
 
-          if ( charstringIndex > CF2_MAX_SUBR )
+          if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) ||
+               (  font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
           {
             /* max subr plus one for charstring */
             lastError = FT_THROW( Invalid_Glyph_Format );
@@ -991,10 +992,10 @@
           /* set up the new CFF region and pointer */
           subrNum = cf2_stack_popInt( opStack );
 
-          if ( font->isT1 && decoder->subrs_hash )
+          if ( font->isT1 && decoder->locals_hash )
           {
             size_t*  val = ft_hash_num_lookup( subrNum,
-                                               decoder->subrs_hash );
+                                               decoder->locals_hash );
 
             if ( val )
               subrNum = *val;