dump: Some things are related to a version number.
authorBen Pfaff <blp@cs.stanford.edu>
Mon, 27 Jul 2015 06:37:32 +0000 (23:37 -0700)
committerBen Pfaff <blp@cs.stanford.edu>
Mon, 27 Jul 2015 06:37:32 +0000 (23:37 -0700)
This fixes SPV e0d720071df86f4ecedac567a1a6b851 up to and including the
fonts section.

dump.c

diff --git a/dump.c b/dump.c
index 2ac89bcab71d3bc7c81c4f6083c9e2a7f678e1fc..bc3fe39388a26c6b65f103c655ac7320e949f618 100644 (file)
--- a/dump.c
+++ b/dump.c
@@ -10,6 +10,8 @@
 static uint8_t *data;
 static size_t n;
 
+int version;
+
 static bool
 all_ascii(const uint8_t *p, size_t n)
 {
@@ -246,13 +248,16 @@ dump_value_31(FILE *stream)
           else
             match_u32_assert (0);
 
-          /* This special case is really unsatisfying, but there are several
-             examples in the corpus, all from one SPV file. */
-          int save_pos = pos;
-          if (match_u32 (0x200) && match_u32(0x1000000) && match_u32(0)
-              && match_byte(0))
-            return;
-          pos = save_pos;
+          if (version == 1)
+            {
+              /* We only have one SPV file for this version (with many
+                 tables). */
+              match_u32_assert(0x200);
+              match_u32_assert(0x1000000);
+              match_u32_assert(0);
+              match_byte_assert(0);
+              return;
+            }
 
           int outer_end = pos + get_u32();
           int inner_end = pos + get_u32();
@@ -739,26 +744,29 @@ dump_fonts(void)
       match_u32_assert(0);
       match_byte_assert(0);
 
-      /* These seem unlikely to be correct too. */
-      if (i != 3)
-        {
-          match_u32_assert(8);
-          if (!match_u32(10))
-            match_u32_assert(11);
-          match_u32_assert(1);
-        }
-      else
+      if (version > 1)
         {
+          /* These seem unlikely to be correct too. */
+          if (i != 3)
+            {
+              match_u32_assert(8);
+              if (!match_u32(10))
+                match_u32_assert(11);
+              match_u32_assert(1);
+            }
+          else
+            {
+              get_u32();
+              if (!match_u32(-1) && !match_u32(8))
+                match_u32_assert(24);
+              if (!match_u32(-1) && !match_u32(2))
+                match_u32_assert(3);
+            }
+
+          /* Who knows? Ranges from -1 to 8 with no obvious pattern. */
           get_u32();
-          if (!match_u32(-1) && !match_u32(8))
-            match_u32_assert(24);
-          if (!match_u32(-1) && !match_u32(2))
-            match_u32_assert(3);
         }
 
-      /* Who knows? Ranges from -1 to 8 with no obvious pattern. */
-      get_u32();
-
       printf ("/>\n");
     }
 
@@ -770,10 +778,12 @@ dump_fonts(void)
 
   if (match_u32(117))
     pos += 117;
+  else if (match_u32(142))
+    pos += 142;
   else
     {
-      match_u32_assert(142);
-      pos += 142;
+      match_u32_assert(16);
+      pos += 16;
     }
 
   int count = get_u32();
@@ -788,11 +798,16 @@ dump_fonts(void)
   match_byte_assert(0);
   if (!match_byte(0))
     match_byte_assert(1);
-  if (!match_byte(0x97) && !match_byte(0x98) && !match_byte(0x99))
-    match_byte_assert(0x9a);
-  match_byte_assert(7);
-  match_byte_assert(0);
-  match_byte_assert(0);
+  if (version > 1)
+    {
+      if (!match_byte(0x97) && !match_byte(0x98) && !match_byte(0x99))
+        match_byte_assert(0x9a);
+      match_byte_assert(7);
+      match_byte_assert(0);
+      match_byte_assert(0);
+    }
+  else
+    match_u32_assert(UINT32_MAX);
   if (match_byte('.'))
     match_byte_assert(',');
   else
@@ -879,9 +894,11 @@ main(int argc, char *argv[])
           match_byte_assert(1);
           match_byte_assert(0);
 
-          /* This might be a version number of some kind, because it seems to
-             only appear in an SPV file that also required its own weird
+          /* This might be a version number of some kind, because value 1 seems
+             to only appear in an SPV file that also required its own weird
              special cases in dump_value_31(). */
+          version = get_u32();
+          pos -= 4;
           if (!match_u32(1))
             match_u32_assert(3);