Browse Source

Improved file extraction error handling

n1474335 6 years ago
parent
commit
9fa7edffbf
2 changed files with 20 additions and 8 deletions
  1. 3 3
      src/core/lib/FileSignatures.mjs
  2. 17 5
      src/core/operations/ExtractFiles.mjs

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

@@ -1057,7 +1057,7 @@ export function extractJPEG(bytes, offset) {
 
     while (stream.hasMore()) {
         const marker = stream.getBytes(2);
-        if (marker[0] !== 0xff) throw new Error("Invalid JPEG marker: " + marker);
+        if (marker[0] !== 0xff) throw new Error(`Invalid marker while parsing JPEG at pos ${stream.position}: ${marker}`);
 
         let segmentSize = 0;
         switch (marker[1]) {
@@ -1609,7 +1609,7 @@ function parseDEFLATE(stream) {
 
             parseHuffmanBlock(stream, dynamicLiteralTable, dynamicDistanceTable);
         } else {
-            throw new Error("Invalid block type");
+            throw new Error(`Invalid block type while parsing DEFLATE stream at pos ${stream.position}`);
         }
     }
 
@@ -1712,7 +1712,7 @@ function readHuffmanCode(stream, table) {
     const codeLength = codeWithLength >>> 16;
 
     if (codeLength > maxCodeLength) {
-        throw new Error("Invalid code length: " + codeLength);
+        throw new Error(`Invalid Huffman Code length while parsing DEFLATE block at pos ${stream.position}: ${codeLength}`);
     }
 
     stream.moveBackwardsByBits(maxCodeLength - codeLength);

+ 17 - 5
src/core/operations/ExtractFiles.mjs

@@ -5,7 +5,7 @@
  */
 
 import Operation from "../Operation";
-// import OperationError from "../errors/OperationError";
+import OperationError from "../errors/OperationError";
 import Utils from "../Utils";
 import {scanForFileTypes, extractFile} from "../lib/FileType";
 import {FILE_SIGNATURES} from "../lib/FileSignatures";
@@ -34,7 +34,13 @@ class ExtractFiles extends Operation {
                 type: "boolean",
                 value: cat === "Miscellaneous" ? false : true
             };
-        });
+        }).concat([
+            {
+                name: "Ignore failed extractions",
+                type: "boolean",
+                value: "true"
+            }
+        ]);
     }
 
     /**
@@ -44,7 +50,8 @@ class ExtractFiles extends Operation {
      */
     run(input, args) {
         const bytes = new Uint8Array(input),
-            categories = [];
+            categories = [],
+            ignoreFailedExtractions = args.pop(1);
 
         args.forEach((cat, i) => {
             if (cat) categories.push(Object.keys(FILE_SIGNATURES)[i]);
@@ -59,8 +66,13 @@ class ExtractFiles extends Operation {
             try {
                 files.push(extractFile(bytes, detectedFile.fileDetails, detectedFile.offset));
             } catch (err) {
-                if (err.message.indexOf("No extraction algorithm available") < 0)
-                    throw err;
+                if (!ignoreFailedExtractions && err.message.indexOf("No extraction algorithm available") < 0) {
+                    throw new OperationError(
+                        `Error while attempting to extract ${detectedFile.fileDetails.name} ` +
+                        `at offset ${detectedFile.offset}:\n` +
+                        `${err.message}`
+                    );
+                }
             }
         });