瀏覽代碼

Merge branch 'n1073645-OLE2'

n1474335 5 年之前
父節點
當前提交
f4d75f88a9
共有 1 個文件被更改,包括 115 次插入3 次删除
  1. 115 3
      src/core/lib/FileSignatures.mjs

+ 115 - 3
src/core/lib/FileSignatures.mjs

@@ -3075,15 +3075,127 @@ export function extractSQLITE(bytes, offset) {
 export function extractPListXML(bytes, offset) {
     const stream = new Stream(bytes.slice(offset));
 
-    // Find closing tag (</plist>)
-    stream.continueUntil([0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e]);
-    stream.moveForwardsBy(8);
+    let braceCount = 0;
+
+    // Continue to the first (<plist).
+    stream.continueUntil([0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74]);
+    stream.moveForwardsBy(6);
+    braceCount++;
+
+    // While we have an unequal amount of braces.
+    while (braceCount > 0 && stream.hasMore()) {
+        if (stream.readInt(1) === 0x3c) {
+
+            // If we hit an <plist.
+            if (stream.getBytes(5).join("") === [0x70, 0x6c, 0x69, 0x73, 0x74].join("")) {
+                braceCount++;
+            } else {
+                stream.moveBackwardsBy(5);
+            }
+
+            // If we hit an </plist>.
+            if (stream.getBytes(7).join("") === [0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e].join("")) {
+                braceCount--;
+            } else {
+                stream.moveBackwardsBy(7);
+            }
+        }
+    }
     stream.consumeIf(0x0a);
 
     return stream.carve();
 }
 
 
+/**
+ * OLE2 extractor.
+ *
+ * @param {Uint8Array} bytes
+ * @param {number} offset
+ * @returns {Uint8Array}
+ */
+export function extractOLE2(bytes, offset) {
+    const stream = new Stream(bytes.slice(offset));
+    const entries = [
+        [[0x52, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x72, 0x00, 0x79], 19, "Root Entry"],
+        [[0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x62, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6b], 15, "Workbook"],
+        [[0x43, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72],  23,  "Current User"],
+        [[0x50, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x65, 0x00, 0x72, 0x00, 0x50, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74], 37, "PowerPoint Document"],
+        [[0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x64, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74], 23, "WordDocument"],
+        [[0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x61], 7, "Data"],
+        [[0x50, 0x00, 0x69, 0x00, 0x63, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73], 15, "Pictures"],
+        [[0x31, 0x00, 0x54, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65], 11, "1Table"],
+        [[0x05, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e], 37, "SummaryInformation"],
+        [[0x05, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e], 53, "DocumentSummaryInformation"],
+        [[0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x6a], 13, "Comp Obj"],
+        [[0x01, 0x00], 2, "Entry"]
+    ];
+    let endianness = "le";
+
+    // Move to endianess field.
+    stream.moveForwardsBy(28);
+    if (stream.readInt(2, endianness) === 0xfffe)
+        endianness = "be";
+
+    // Calculate the size of the normal sectors.
+    const sizeOfSector = 2 ** stream.readInt(2, endianness);
+
+    // Move to root directory offset field.
+    stream.moveTo(48);
+
+    // Read root directory offset.
+    const rootStuff  = stream.readInt(4, endianness);
+
+    // Calculate root directory offset.
+    let total = 512 + (rootStuff * sizeOfSector);
+    stream.moveTo(total);
+
+    // While valid directory entries.
+    let found = true;
+    while (found) {
+        found = false;
+
+        // Attempt to determine what directory entry it is.
+        for (const element of entries) {
+
+            // If the byte pattern matches.
+            if (stream.getBytes(element[1]).join("") === element[0].join("")) {
+                stream.moveBackwardsBy(element[1]);
+                found = true;
+
+                // Move forwards by the size of the comp obj.
+                if (element[2] === "Comp Obj") {
+
+                    // The size of the Comp Obj entry - 128. Since we add 128 later.
+                    total += 128 * 6;
+                    stream.moveTo(total);
+                } else if (element[2] === "Entry") {
+
+                    // If there is an entry move backwards by 126 to then move forwards by 128. Hence a total displacement of 2.
+                    stream.moveBackwardsBy(126);
+                }
+                break;
+            }
+            stream.moveBackwardsBy(element[1]);
+        }
+
+        // If we have found a valid entry, move forwards by 128.
+        if (found) {
+
+            // Every entry is at least 128 in size, some are bigger which is dealt with by the above if statement.
+            total += 128;
+            stream.moveForwardsBy(128);
+        }
+    }
+
+    // Round up to a multiple of 512.
+    total = Math.ceil(total / 512) * 512;
+
+    stream.moveTo(total);
+    return stream.carve();
+}
+
+
 /**
  * GZIP extractor.
  *