Commit a87fb8ccf3d9362154f92ed78da9f6e4879a531e

Chris Liddell 2015-05-12T07:27:35

[cff] Make the `*curveto' operators more tolerant. * src/cff/cf2intrp.c (cf2_interpT2CharString): The opcodes `vvcurveto', `hhcurveto', `vhcurveto', and `hvcurveto' all iterate, pulling values off the stack until the stack is exhausted. Implicitly the stack must be a multiple (or for subtly different behaviour) a multiple plus a specific number of extra values deep. If that's not the case, enforce it (as the old code did).

diff --git a/ChangeLog b/ChangeLog
index 79e6b36..3cbd45d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,16 @@
 2015-05-12  Chris Liddell  <chris.liddell@artifex.com>
 
+	[cff] Make the `*curveto' operators more tolerant.
+
+	* src/cff/cf2intrp.c (cf2_interpT2CharString): The opcodes
+	`vvcurveto', `hhcurveto', `vhcurveto', and `hvcurveto' all iterate,
+	pulling values off the stack until the stack is exhausted.
+	Implicitly the stack must be a multiple (or for subtly different
+	behaviour) a multiple plus a specific number of extra values deep.
+	If that's not the case, enforce it (as the old code did).
+
+2015-05-12  Chris Liddell  <chris.liddell@artifex.com>
+
 	[cff] fix incremental interface with new cff code.
 
 	* src/cff/cf2ft.c (cf2_getSeacComponent): When using the incremental
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index d7f7a7b..537e060 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -1298,10 +1298,16 @@
 
       case cf2_cmdVVCURVETO:
         {
-          CF2_UInt  count = cf2_stack_count( opStack );
+          CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
 
+          /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
+          /* we enforce it by clearing the second bit           */
+          /* (and sorting the stack indexing to suit)           */
+          count  = count1 & ~2;
+          index += count1 - count;
+
           FT_TRACE4(( " vvcurveto\n" ));
 
           while ( index < count )
@@ -1337,10 +1343,16 @@
 
       case cf2_cmdHHCURVETO:
         {
-          CF2_UInt  count = cf2_stack_count( opStack );
+          CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
 
+          /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
+          /* we enforce it by clearing the second bit           */
+          /* (and sorting the stack indexing to suit)           */
+          count  = count1 & ~2;
+          index += count1 - count;
+
           FT_TRACE4(( " hhcurveto\n" ));
 
           while ( index < count )
@@ -1377,12 +1389,19 @@
       case cf2_cmdVHCURVETO:
       case cf2_cmdHVCURVETO:
         {
-          CF2_UInt  count = cf2_stack_count( opStack );
+          CF2_UInt  count, count1 = cf2_stack_count( opStack );
           CF2_UInt  index = 0;
 
           FT_Bool  alternate = op1 == cf2_cmdHVCURVETO;
 
 
+          /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */
+          /* 8n+4, or 8n+5, we enforce it by clearing the     */
+          /* second bit                                       */
+          /* (and sorting the stack indexing to suit)         */
+          count  = count1 & ~2;
+          index += count1 - count;
+
           FT_TRACE4(( alternate ? " hvcurveto\n" : " vhcurveto\n" ));
 
           while ( index < count )