dump: Some things are related to a version number.
[pspp] / dump.c
diff --git a/dump.c b/dump.c
index f9c315e580090dba9760640859b27eeae344066a..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
@@ -878,7 +893,15 @@ main(int argc, char *argv[])
           pos = 0;
           match_byte_assert(1);
           match_byte_assert(0);
-          match_u32_assert(3);
+
+          /* 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);
+
           match_byte_assert(1);
           if (!match_byte(0))
             match_byte_assert(1);