pull back from blindly interpreting xx 80, which wasn't working
authorBen Pfaff <blp@cs.stanford.edu>
Fri, 3 Jul 2020 04:09:50 +0000 (04:09 +0000)
committerBen Pfaff <blp@cs.stanford.edu>
Fri, 3 Jul 2020 04:09:50 +0000 (04:09 +0000)
Instead, try to interpret things in more detail.  Seems to be working
better.

dump-spo2.c

index 93606cd9b9a1f465ff4a8e41ff677409a75718f2..971fbab8eacf1b3390c5c51d6709d45b531396ee 100644 (file)
@@ -256,33 +256,43 @@ all_utf8(const char *p_, size_t len)
 }
 
 static char *
-get_string2(void)
+pull_string(int len, const char *where)
 {
-  int len = data[pos] + data[pos + 1] * 256;
-  char *s = xmemdup0(&data[pos + 2], len);
-  pos += 2 + len;
+  assert (len >= 0);
+  for (int i = 0; i < len - 1; i++)
+    if (!data[pos + i])
+      {
+        fprintf(stderr, "%s: %d-byte string starting at 0x%x has null byte "
+                "at offset %d: ", where, len, pos, i);
+        hex_dump(stderr, pos, len + 64);
+        exit(1);
+      }
+
+  char *s = xmemdup0(&data[pos], len);
+  pos += len;
   return s;
 }
 
 static char *
-get_string1(void)
+get_string2(const char *where)
+{
+  return pull_string(get_u16(), where);
+}
+#define get_string2() get_string2(WHERE)
+
+static char *
+get_string1(const char *where)
 {
   int len = data[pos++];
-  if (len == 0xff)
-    return get_string2();
-  else
-    {
-      char *s = xmemdup0(&data[pos], len);
-      pos += len;
-      return s;
-    }
+  return len == 0xff ? (get_string2)(where) : pull_string(len, where);
 }
+#define get_string1() get_string1(WHERE)
 
 static void
 match_string1_assert(const char *exp, const char *where)
 {
   int start = pos;
-  char *act = get_string1();
+  char *act = (get_string1)(where);
   if (strcmp(act, exp)) 
     {
       fprintf(stderr, "%s: 0x%x: expected \"%s\", got \"%s\"\n",
@@ -296,7 +306,7 @@ static void
 match_string2_assert(const char *exp, const char *where)
 {
   int start = pos;
-  char *act = get_string2();
+  char *act = (get_string2)(where);
   if (strcmp(act, exp)) 
     {
       fprintf(stderr, "%s: 0x%x: expected \"%s\", got \"%s\"\n",
@@ -309,24 +319,8 @@ match_string2_assert(const char *exp, const char *where)
 static char *
 get_string4(const char *where)
 {
-  if (1
-      /*data[pos + 1] == 0 && data[pos + 2] == 0 && data[pos + 3] == 0*/
-      /*&& all_ascii(&data[pos + 4], data[pos])*/)
-    {
-      assert(data[pos + 3] == 0);
-      int len = data[pos] + data[pos + 1] * 256 + data[pos + 2] * 65536;
-      char *s = malloc(len + 1);
-
-      memcpy(s, &data[pos + 4], len);
-      s[len] = 0;
-      pos += 4 + len;
-      return s;
-    }
-  else
-    {
-      fprintf(stderr, "%s: 0x%x: expected string\n", where, pos);
-      exit(1);
-    }
+  assert(data[pos + 3] == 0);
+  return pull_string(get_u32(), where);
 }
 #define get_string4() get_string4(WHERE)
 
@@ -838,13 +832,63 @@ parse_IndexedCollection(void)
     }
 }
 
+static void
+parse_PTTableLook(void)
+{
+  match_byte_assert(2);
+  match_byte_assert(2);
+  match_zeros_assert(7);
+  match_u32_assert(0x36);
+  match_u32_assert(0x12);
+}
+
+static void
+parse_PVViewDimension(void)
+{
+  while (data[pos + 1] != 0x80
+         && (data[pos] != 0xff || data[pos + 1] != 0xff))
+    {
+      assert(pos < n);
+      pos++;
+    }
+}
+
+static void
+parse_PVSeparatorStyle(void)
+{
+  match_byte_assert(0);
+  match_byte_assert(1);
+  match_zeros_assert(15);
+  pos++;
+  match_byte_assert(0x80);
+  match_byte_assert(0);
+
+  match_byte_assert(1);
+  match_zeros_assert(9);
+  while (data[pos + 1] != 0x80
+         && (data[pos] != 0xff || data[pos + 1] != 0xff))
+    {
+      assert(pos < n);
+      pos++;
+    }
+}
+
+static void
+parse_PVCellStyle(void)
+{
+  match_byte_assert(0);
+  match_byte_assert(1);
+  match_zeros_assert(5);
+  match_u32_assert(0xffffff);
+  match_zeros_assert(2);
+}
+
 static void
 parse_flexible(void)
 {
   int start = pos;
-  if (data[pos] == 0xff && data[pos + 1] == 0xff)
+  if (match_u16(0xffff))
     {
-      match_u16_assert(0xffff);
       match_u16_assert(0);
       char *heading = get_string2();
       if (!strcmp(heading, "DspCell"))
@@ -877,10 +921,18 @@ parse_flexible(void)
         parse_PMModelItemInfo();
       else if (!strcmp(heading, "AbstractTreeBranch"))
         match_byte_assert(0);
+      else if (!strcmp(heading, "PTTableLook"))
+        parse_PTTableLook();
+      else if (!strcmp(heading, "PVViewDimension"))
+        parse_PVViewDimension();
+      else if (!strcmp(heading, "PVSeparatorStyle"))
+        parse_PVSeparatorStyle();
+      else if (!strcmp(heading, "PVCellStyle"))
+        parse_PVCellStyle();
       else
         {
           fprintf(stderr, "don't know %s at offset 0x%x: ", heading, start);
-          hex_dump(stderr, pos, 64);
+          hex_dump(stderr, pos, 128);
           assert(0);
         }
     }
@@ -1021,58 +1073,76 @@ parse_flexible(void)
     }
   else if (match_byte(0xa)) 
     {
-      match_byte_assert(0);
+      if (!match_byte(7))
+        match_byte_assert(0);
       if (match_u16(0x0e74))
         match_byte_assert(0);
       else
         {
           match_zeros_assert(4);
-          assert(pos == n);
-          exit (0);
+          if (pos == n)
+            exit (0);
+          match_zeros_assert (2);
         }
     }
+#if 0
   else if (match_byte(1))
     {
       match_byte_assert(0);
       get_string1();
       if (!match_byte(2))
         match_byte_assert(0);
-      match_zeros_assert(3);
-      get_string1();
-      if (match_byte(0x08))
+      if (match_byte(0))
         {
-          match_byte_assert(0);
-          match_u16_assert(0x0e74);
-          match_byte_assert(0);
-        }
-      else if (match_byte(3))
-        {
-          match_byte_assert(0);
-          if (match_u16(0x0e74))
-            match_byte_assert(0);
-          else
+          match_zeros_assert(2);
+          get_string1();
+          if (match_byte(0x08))
+            {
+              match_byte_assert(0);
+              match_u16_assert(0x0e74);
+              match_byte_assert(0);
+            }
+          else if (match_byte(3))
             {
-              match_zeros_assert(6);
-              if (!match_byte(0xe) && !match_byte(0x11))
+              match_byte_assert(0);
+              if (match_u16(0x0e74))
                 match_byte_assert(0);
+              else
+                {
+                  match_zeros_assert(6);
+                  if (!match_byte(0xe) && !match_byte(0x11))
+                    match_byte_assert(0);
+                  match_byte_assert(0);
+                  if (!match_u16(0x0e74))
+                    match_u16_assert(0);
+                  match_byte_assert(0);
+                }
+            }
+          else
+            {
               match_byte_assert(0);
-              if (!match_u16(0x0e74))
-                match_u16_assert(0);
+              match_byte_assert(1);
+              match_zeros_assert(3);
+              match_byte_assert(1);
               match_byte_assert(0);
             }
         }
-      else
+    }
+#endif
+  else //if (match_u16(2) || match_u16(3) || match_u16(4) || match_u16(5) || match_u16(6) || match_u16(7) || match_u16(8) || match_u16(9))
+    {
+      while (data[pos + 1] != 0x80
+             && (data[pos] != 0xff || data[pos + 1] != 0xff))
         {
-          match_byte_assert(0);
-          match_byte_assert(1);
-          match_zeros_assert(3);
-          match_byte_assert(1);
-          match_byte_assert(0);
+          assert(pos < n);
+          pos++;
         }
     }
-  else if (match_byte(7) || match_byte(4) || match_byte(5) || match_byte(6) || match_byte(8) || match_byte(9) || match_byte(0xb) || match_byte(0xc))
+#if 0
+  else if (match_byte(7) || match_byte(4) || match_byte(5) || match_byte(6) || match_byte(8) || match_byte(9) || match_byte(0xb) || match_byte(0xc) || match_byte(0x15) || match_byte(0x16) || match_byte(0x17) || match_byte(0x18) || match_byte(0x1e)  || match_byte(0x1a))
     {
-      match_byte_assert(0);
+      if (!match_byte(7))
+        match_byte_assert(0);
       if (!match_u16(0x0e74))
         match_byte_assert(0);
       match_byte_assert(0);
@@ -1082,24 +1152,62 @@ parse_flexible(void)
       match_byte_assert(0);
       if (!match_u16(0x0e74))
         {
-          match_zeros_assert(6);
+          match_zeros_assert(2);
           if (match_byte(0))
-            match_zeros_assert(4);
-          else
             {
-              pos++;
-              match_byte(0);
-              match_u16_assert(0x0e74);
+              match_zeros_assert(3);
+              if (match_byte(0))
+                match_zeros_assert(4);
+              else
+                {
+                  pos++;
+                  match_byte(0);
+                  match_u16_assert(0x0e74);
+                }
             }
         }
       //match_byte_assert(0);
     }
+  else if (match_byte(0xd) || match_byte(0xe) || match_byte(0xf)
+           || match_byte(0x11) || match_byte(0x12) || match_byte(0x13)
+           || match_byte(0x14) || match_byte(0x1b))
+    {
+      if (!match_byte(0x07))
+        match_byte_assert(0);
+      if (!match_u16(0x0e74))
+        match_zeros_assert(11);
+      else
+        match_byte_assert(0);
+    }
+  else if (match_byte(0xe3) || match_byte(0xdb) || match_byte(0xd8) || match_byte(0xe9) || match_byte(0xf3))
+    {
+      match_byte_assert(0x0e);
+      match_byte_assert(0x74);
+      match_byte_assert(0x0e);
+      match_byte_assert(0);
+    }
+  else if (match_byte(0x9d) || match_byte(0x9e) || match_byte(0x9c))
+    match_u32_assert(0x000e741a);
+  else if (match_byte(0x10))
+    {
+      match_byte_assert(0);
+      if (match_byte(0))
+        match_zeros_assert(10);
+      else
+        {
+          match_u16_assert(0x0e74);
+          match_byte_assert(0);
+        }
+    }
+  else if (match_byte(0x39) || match_byte(0x3a) || match_byte(0x3b))
+    match_u32_assert(0x000e7409);
   else
     {
       //fprintf (stderr, "bad record start at offset %x: ", pos);
       hex_dump (stderr, pos, 64);
       assert(0);
     }
+#endif
 }