Browse Source

ESM: Added Zlib ops and created a Zlib library.

n1474335 7 years ago
parent
commit
083d2d1cc4

+ 2 - 2
Gruntfile.js

@@ -22,7 +22,7 @@ module.exports = function (grunt) {
     // Tasks
     grunt.registerTask("dev",
         "A persistent task which creates a development build whenever source files are modified.",
-        ["clean:dev", "clean:config", "webpack-dev-server:start"]);
+        ["clean:dev", "webpack-dev-server:start"]);
 
     grunt.registerTask("node",
         "Compiles CyberChef into a single NodeJS module.",
@@ -38,7 +38,7 @@ module.exports = function (grunt) {
 
     grunt.registerTask("prod",
         "Creates a production-ready build. Use the --msg flag to add a compile message.",
-        ["eslint", "clean:prod", "clean:config", "webpack:web", "inline", "chmod"]);
+        ["eslint", "clean:prod", "webpack:web", "inline", "chmod"]);
 
     grunt.registerTask("default",
         "Lints the code base",

+ 13 - 13
src/core/config/Categories.js

@@ -238,22 +238,22 @@ const Categories = [
     //         "Extract EXIF",
     //     ]
     // },
-    // {
-    //     name: "Compression",
-    //     ops: [
-    //         "Raw Deflate",
-    //         "Raw Inflate",
-    //         "Zlib Deflate",
-    //         "Zlib Inflate",
-    //         "Gzip",
-    //         "Gunzip",
-    //         "Zip",
-    //         "Unzip",
+    {
+        name: "Compression",
+        ops: [
+            "Raw Deflate",
+            "Raw Inflate",
+            "Zlib Deflate",
+            "Zlib Inflate",
+            "Gzip",
+            "Gunzip",
+            "Zip",
+            "Unzip",
     //         "Bzip2 Decompress",
     //         "Tar",
     //         "Untar",
-    //     ]
-    // },
+        ]
+    },
     // {
     //     name: "Hashing",
     //     ops: [

+ 220 - 0
src/core/config/OperationConfig.json

@@ -114,6 +114,102 @@
             }
         ]
     },
+    "Gunzip": {
+        "module": "Compression",
+        "description": "Decompresses data which has been compressed using the deflate algorithm with gzip headers.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": []
+    },
+    "Gzip": {
+        "module": "Compression",
+        "description": "Compresses data using the deflate algorithm with gzip headers.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Compression type",
+                "type": "option",
+                "value": [
+                    "Dynamic Huffman Coding",
+                    "Fixed Huffman Coding",
+                    "None (Store)"
+                ]
+            },
+            {
+                "name": "Filename (optional)",
+                "type": "string",
+                "value": ""
+            },
+            {
+                "name": "Comment (optional)",
+                "type": "string",
+                "value": ""
+            },
+            {
+                "name": "Include file checksum",
+                "type": "boolean",
+                "value": false
+            }
+        ]
+    },
+    "Raw Deflate": {
+        "module": "Compression",
+        "description": "Compresses data using the deflate algorithm with no headers.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Compression type",
+                "type": "option",
+                "value": [
+                    "Dynamic Huffman Coding",
+                    "Fixed Huffman Coding",
+                    "None (Store)"
+                ]
+            }
+        ]
+    },
+    "Raw Inflate": {
+        "module": "Compression",
+        "description": "Decompresses data which has been compressed using the deflate algorithm with no headers.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Start index",
+                "type": "number",
+                "value": 0
+            },
+            {
+                "name": "Initial output buffer size",
+                "type": "number",
+                "value": 0
+            },
+            {
+                "name": "Buffer expansion type",
+                "type": "option",
+                "value": [
+                    "Adaptive",
+                    "Block"
+                ]
+            },
+            {
+                "name": "Resize buffer after decompression",
+                "type": "boolean",
+                "value": false
+            },
+            {
+                "name": "Verify result",
+                "type": "boolean",
+                "value": false
+            }
+        ]
+    },
     "Show Base64 offsets": {
         "module": "Default",
         "description": "When a string is within a block of data and the whole block is Base64'd, the string itself could be represented in Base64 in three distinct ways depending on its offset within the block.<br><br>This operation shows all possible offsets for a given string so that each possible encoding can be considered.",
@@ -237,5 +333,129 @@
                 ]
             }
         ]
+    },
+    "Unzip": {
+        "module": "Compression",
+        "description": "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Password",
+                "type": "binaryString",
+                "value": ""
+            },
+            {
+                "name": "Verify result",
+                "type": "boolean",
+                "value": false
+            }
+        ]
+    },
+    "Zip": {
+        "module": "Compression",
+        "description": "Compresses data using the PKZIP algorithm with the given filename.<br><br>No support for multiple files at this time.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Filename",
+                "type": "string",
+                "value": "file.txt"
+            },
+            {
+                "name": "Comment",
+                "type": "string",
+                "value": ""
+            },
+            {
+                "name": "Password",
+                "type": "binaryString",
+                "value": ""
+            },
+            {
+                "name": "Compression method",
+                "type": "option",
+                "value": [
+                    "Deflate",
+                    "None (Store)"
+                ]
+            },
+            {
+                "name": "Operating system",
+                "type": "option",
+                "value": [
+                    "MSDOS",
+                    "Unix",
+                    "Macintosh"
+                ]
+            },
+            {
+                "name": "Compression type",
+                "type": "option",
+                "value": [
+                    "Dynamic Huffman Coding",
+                    "Fixed Huffman Coding",
+                    "None (Store)"
+                ]
+            }
+        ]
+    },
+    "Zlib Deflate": {
+        "module": "Compression",
+        "description": "Compresses data using the deflate algorithm adding zlib headers.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Compression type",
+                "type": "option",
+                "value": [
+                    "Dynamic Huffman Coding",
+                    "Fixed Huffman Coding",
+                    "None (Store)"
+                ]
+            }
+        ]
+    },
+    "Zlib Inflate": {
+        "module": "Compression",
+        "description": "Decompresses data which has been compressed using the deflate algorithm with zlib headers.",
+        "inputType": "byteArray",
+        "outputType": "byteArray",
+        "flowControl": false,
+        "args": [
+            {
+                "name": "Start index",
+                "type": "number",
+                "value": 0
+            },
+            {
+                "name": "Initial output buffer size",
+                "type": "number",
+                "value": 0
+            },
+            {
+                "name": "Buffer expansion type",
+                "type": "option",
+                "value": [
+                    "Adaptive",
+                    "Block"
+                ]
+            },
+            {
+                "name": "Resize buffer after decompression",
+                "type": "boolean",
+                "value": false
+            },
+            {
+                "name": "Verify result",
+                "type": "boolean",
+                "value": false
+            }
+        ]
     }
 }

+ 30 - 0
src/core/config/modules/Compression.mjs

@@ -0,0 +1,30 @@
+/**
+* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateConfig.mjs
+*
+* @author n1474335 [n1474335@gmail.com]
+* @copyright Crown Copyright 2018
+* @license Apache-2.0
+*/
+import Gunzip from "../../operations/Gunzip";
+import Gzip from "../../operations/Gzip";
+import RawDeflate from "../../operations/RawDeflate";
+import RawInflate from "../../operations/RawInflate";
+import Unzip from "../../operations/Unzip";
+import Zip from "../../operations/Zip";
+import ZlibDeflate from "../../operations/ZlibDeflate";
+import ZlibInflate from "../../operations/ZlibInflate";
+
+const OpModules = typeof self === "undefined" ? {} : self.OpModules || {};
+
+OpModules.Compression = {
+    "Gunzip": Gunzip,
+    "Gzip": Gzip,
+    "Raw Deflate": RawDeflate,
+    "Raw Inflate": RawInflate,
+    "Unzip": Unzip,
+    "Zip": Zip,
+    "Zlib Deflate": ZlibDeflate,
+    "Zlib Inflate": ZlibInflate,
+};
+
+export default OpModules;

+ 2 - 0
src/core/config/modules/OpModules.mjs

@@ -8,12 +8,14 @@
 * @license Apache-2.0
 */
 import DefaultModule from "./Default";
+import CompressionModule from "./Compression";
 
 const OpModules = {};
 
 Object.assign(
     OpModules,
     DefaultModule,
+    CompressionModule,
 );
 
 export default OpModules;

+ 19 - 0
src/core/lib/Zlib.mjs

@@ -0,0 +1,19 @@
+/**
+ * Zlib exports.
+ *
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
+
+const Zlib = zlibAndGzip.Zlib;
+
+export const COMPRESSION_TYPE = ["Dynamic Huffman Coding", "Fixed Huffman Coding", "None (Store)"];
+export const INFLATE_BUFFER_TYPE = ["Adaptive", "Block"];
+export const ZLIB_COMPRESSION_TYPE_LOOKUP = {
+    "Fixed Huffman Coding":   Zlib.Deflate.CompressionType.FIXED,
+    "Dynamic Huffman Coding": Zlib.Deflate.CompressionType.DYNAMIC,
+    "None (Store)":           Zlib.Deflate.CompressionType.NONE,
+};

+ 46 - 0
src/core/operations/Gunzip.mjs

@@ -0,0 +1,46 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
+
+const Zlib = zlibAndGzip.Zlib;
+
+/**
+ * Gunzip operation
+ */
+class Gunzip extends Operation {
+
+    /**
+     * Gunzip constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Gunzip";
+        this.module = "Compression";
+        this.description = "Decompresses data which has been compressed using the deflate algorithm with gzip headers.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        // Deal with character encoding issues
+        input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
+        const gunzip = new Zlib.Gunzip(input);
+        return Array.prototype.slice.call(gunzip.decompress());
+    }
+
+}
+
+export default Gunzip;

+ 85 - 0
src/core/operations/Gzip.mjs

@@ -0,0 +1,85 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {COMPRESSION_TYPE, ZLIB_COMPRESSION_TYPE_LOOKUP} from "../lib/Zlib";
+import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
+
+const Zlib = zlibAndGzip.Zlib;
+
+/**
+ * Gzip operation
+ */
+class Gzip extends Operation {
+
+    /**
+     * Gzip constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Gzip";
+        this.module = "Compression";
+        this.description = "Compresses data using the deflate algorithm with gzip headers.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Compression type",
+                type: "option",
+                value: COMPRESSION_TYPE
+            },
+            {
+                name: "Filename (optional)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Comment (optional)",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Include file checksum",
+                type: "boolean",
+                value: false
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const filename = args[1],
+            comment = args[2],
+            options = {
+                deflateOptions: {
+                    compressionType: ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]]
+                },
+                flags: {
+                    fhcrc: args[3]
+                }
+            };
+
+        if (filename.length) {
+            options.flags.fname = true;
+            options.filename = filename;
+        }
+        if (comment.length) {
+            options.flags.fcommenct = true;
+            options.comment = comment;
+        }
+
+        const gzip = new Zlib.Gzip(input, options);
+        return Array.prototype.slice.call(gzip.compress());
+    }
+
+}
+
+export default Gzip;

+ 58 - 0
src/core/operations/RawDeflate.mjs

@@ -0,0 +1,58 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {COMPRESSION_TYPE} from "../lib/Zlib";
+import rawdeflate from "zlibjs/bin/rawdeflate.min";
+
+const Zlib = rawdeflate.Zlib;
+
+const RAW_COMPRESSION_TYPE_LOOKUP = {
+    "Fixed Huffman Coding":   Zlib.RawDeflate.CompressionType.FIXED,
+    "Dynamic Huffman Coding": Zlib.RawDeflate.CompressionType.DYNAMIC,
+    "None (Store)":           Zlib.RawDeflate.CompressionType.NONE,
+};
+
+/**
+ * Raw Deflate operation
+ */
+class RawDeflate extends Operation {
+
+    /**
+     * RawDeflate constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Raw Deflate";
+        this.module = "Compression";
+        this.description = "Compresses data using the deflate algorithm with no headers.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Compression type",
+                type: "option",
+                value: COMPRESSION_TYPE
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const deflate = new Zlib.RawDeflate(input, {
+            compressionType: RAW_COMPRESSION_TYPE_LOOKUP[args[0]]
+        });
+        return Array.prototype.slice.call(deflate.compress());
+    }
+
+}
+
+export default RawDeflate;

+ 105 - 0
src/core/operations/RawInflate.mjs

@@ -0,0 +1,105 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
+import rawinflate from "zlibjs/bin/rawinflate.min";
+
+const Zlib = rawinflate.Zlib;
+
+const RAW_BUFFER_TYPE_LOOKUP = {
+    "Adaptive": Zlib.RawInflate.BufferType.ADAPTIVE,
+    "Block":    Zlib.RawInflate.BufferType.BLOCK,
+};
+
+/**
+ * Raw Inflate operation
+ */
+class RawInflate extends Operation {
+
+    /**
+     * RawInflate constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Raw Inflate";
+        this.module = "Compression";
+        this.description = "Decompresses data which has been compressed using the deflate algorithm with no headers.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Start index",
+                type: "number",
+                value: 0
+            },
+            {
+                name: "Initial output buffer size",
+                type: "number",
+                value: 0
+            },
+            {
+                name: "Buffer expansion type",
+                type: "option",
+                value: INFLATE_BUFFER_TYPE
+            },
+            {
+                name: "Resize buffer after decompression",
+                type: "boolean",
+                value: false
+            },
+            {
+                name: "Verify result",
+                type: "boolean",
+                value: false
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        // Deal with character encoding issues
+        input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
+        const inflate = new Zlib.RawInflate(input, {
+                index: args[0],
+                bufferSize: args[1],
+                bufferType: RAW_BUFFER_TYPE_LOOKUP[args[2]],
+                resize: args[3],
+                verify: args[4]
+            }),
+            result = Array.prototype.slice.call(inflate.decompress());
+
+        // Raw Inflate somethimes messes up and returns nonsense like this:
+        // ]....]....]....]....]....]....]....]....]....]....]....]....]....]...
+        // e.g. Input data of [8b, 1d, dc, 44]
+        // Look for the first two square brackets:
+        if (result.length > 158 && result[0] === 93 && result[5] === 93) {
+            // If the first two square brackets are there, check that the others
+            // are also there. If they are, throw an error. If not, continue.
+            let valid = false;
+            for (let i = 0; i < 155; i += 5) {
+                if (result[i] !== 93) {
+                    valid = true;
+                }
+            }
+
+            if (!valid) {
+                throw "Error: Unable to inflate data";
+            }
+        }
+        // This seems to be the easiest way...
+        return result;
+    }
+
+}
+
+export default RawInflate;

+ 80 - 0
src/core/operations/Unzip.mjs

@@ -0,0 +1,80 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import unzip from "zlibjs/bin/unzip.min";
+
+const Zlib = unzip.Zlib;
+
+/**
+ * Unzip operation
+ */
+class Unzip extends Operation {
+
+    /**
+     * Unzip constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Unzip";
+        this.module = "Compression";
+        this.description = "Decompresses data using the PKZIP algorithm and displays it per file, with support for passwords.";
+        this.inputType = "byteArray";
+        this.outputType = "html";
+        this.args = [
+            {
+                name: "Password",
+                type: "binaryString",
+                value: ""
+            },
+            {
+                name: "Verify result",
+                type: "boolean",
+                value: false
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {html}
+     */
+    run(input, args) {
+        const options = {
+                password: Utils.strToByteArray(args[0]),
+                verify: args[1]
+            },
+            unzip = new Zlib.Unzip(input, options),
+            filenames = unzip.getFilenames(),
+            files = [];
+
+        filenames.forEach(function(fileName) {
+            const bytes = unzip.decompress(fileName);
+            const contents = Utils.byteArrayToUtf8(bytes);
+
+            const file = {
+                fileName: fileName,
+                size: contents.length,
+            };
+
+            const isDir = contents.length === 0 && fileName.endsWith("/");
+            if (!isDir) {
+                file.bytes = bytes;
+                file.contents = contents;
+            }
+
+            files.push(file);
+        });
+
+        return Utils.displayFilesAsHTML(files);
+    }
+
+}
+
+export default Unzip;

+ 101 - 0
src/core/operations/Zip.mjs

@@ -0,0 +1,101 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {COMPRESSION_TYPE, ZLIB_COMPRESSION_TYPE_LOOKUP} from "../lib/Zlib";
+import zip from "zlibjs/bin/zip.min";
+
+const Zlib = zip.Zlib;
+
+const ZIP_COMPRESSION_METHOD_LOOKUP = {
+    "Deflate":      Zlib.Zip.CompressionMethod.DEFLATE,
+    "None (Store)": Zlib.Zip.CompressionMethod.STORE
+};
+
+const ZIP_OS_LOOKUP = {
+    "MSDOS":     Zlib.Zip.OperatingSystem.MSDOS,
+    "Unix":      Zlib.Zip.OperatingSystem.UNIX,
+    "Macintosh": Zlib.Zip.OperatingSystem.MACINTOSH
+};
+
+/**
+ * Zip operation
+ */
+class Zip extends Operation {
+
+    /**
+     * Zip constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Zip";
+        this.module = "Compression";
+        this.description = "Compresses data using the PKZIP algorithm with the given filename.<br><br>No support for multiple files at this time.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Filename",
+                type: "string",
+                value: "file.txt"
+            },
+            {
+                name: "Comment",
+                type: "string",
+                value: ""
+            },
+            {
+                name: "Password",
+                type: "binaryString",
+                value: ""
+            },
+            {
+                name: "Compression method",
+                type: "option",
+                value: ["Deflate", "None (Store)"]
+            },
+            {
+                name: "Operating system",
+                type: "option",
+                value: ["MSDOS", "Unix", "Macintosh"]
+            },
+            {
+                name: "Compression type",
+                type: "option",
+                value: COMPRESSION_TYPE
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const password = Utils.strToByteArray(args[2]),
+            options = {
+                filename: Utils.strToByteArray(args[0]),
+                comment: Utils.strToByteArray(args[1]),
+                compressionMethod: ZIP_COMPRESSION_METHOD_LOOKUP[args[3]],
+                os: ZIP_OS_LOOKUP[args[4]],
+                deflateOption: {
+                    compressionType: ZLIB_COMPRESSION_TYPE_LOOKUP[args[5]]
+                },
+            },
+            zip = new Zlib.Zip();
+
+        if (password.length)
+            zip.setPassword(password);
+        zip.addFile(input, options);
+        return Array.prototype.slice.call(zip.compress());
+    }
+
+}
+
+export default Zip;

+ 52 - 0
src/core/operations/ZlibDeflate.mjs

@@ -0,0 +1,52 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import {COMPRESSION_TYPE, ZLIB_COMPRESSION_TYPE_LOOKUP} from "../lib/Zlib";
+import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
+
+const Zlib = zlibAndGzip.Zlib;
+
+/**
+ * Zlib Deflate operation
+ */
+class ZlibDeflate extends Operation {
+
+    /**
+     * ZlibDeflate constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Zlib Deflate";
+        this.module = "Compression";
+        this.description = "Compresses data using the deflate algorithm adding zlib headers.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Compression type",
+                type: "option",
+                value: COMPRESSION_TYPE
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        const deflate = new Zlib.Deflate(input, {
+            compressionType: ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]]
+        });
+        return Array.prototype.slice.call(deflate.compress());
+    }
+
+}
+
+export default ZlibDeflate;

+ 84 - 0
src/core/operations/ZlibInflate.mjs

@@ -0,0 +1,84 @@
+/**
+ * @author n1474335 [n1474335@gmail.com]
+ * @copyright Crown Copyright 2016
+ * @license Apache-2.0
+ */
+
+import Operation from "../Operation";
+import Utils from "../Utils";
+import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
+import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
+
+const Zlib = zlibAndGzip.Zlib;
+
+const ZLIB_BUFFER_TYPE_LOOKUP = {
+    "Adaptive": Zlib.Inflate.BufferType.ADAPTIVE,
+    "Block":    Zlib.Inflate.BufferType.BLOCK,
+};
+
+/**
+ * Zlib Inflate operation
+ */
+class ZlibInflate extends Operation {
+
+    /**
+     * ZlibInflate constructor
+     */
+    constructor() {
+        super();
+
+        this.name = "Zlib Inflate";
+        this.module = "Compression";
+        this.description = "Decompresses data which has been compressed using the deflate algorithm with zlib headers.";
+        this.inputType = "byteArray";
+        this.outputType = "byteArray";
+        this.args = [
+            {
+                name: "Start index",
+                type: "number",
+                value: 0
+            },
+            {
+                name: "Initial output buffer size",
+                type: "number",
+                value: 0
+            },
+            {
+                name: "Buffer expansion type",
+                type: "option",
+                value: INFLATE_BUFFER_TYPE
+            },
+            {
+                name: "Resize buffer after decompression",
+                type: "boolean",
+                value: false
+            },
+            {
+                name: "Verify result",
+                type: "boolean",
+                value: false
+            }
+        ];
+    }
+
+    /**
+     * @param {byteArray} input
+     * @param {Object[]} args
+     * @returns {byteArray}
+     */
+    run(input, args) {
+        // Deal with character encoding issues
+        input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
+        const inflate = new Zlib.Inflate(input, {
+            index: args[0],
+            bufferSize: args[1],
+            bufferType: ZLIB_BUFFER_TYPE_LOOKUP[args[2]],
+            resize: args[3],
+            verify: args[4]
+        });
+        return Array.prototype.slice.call(inflate.decompress());
+    }
+
+}
+
+export default ZlibInflate;

+ 16 - 0
src/core/operations/index.mjs

@@ -8,17 +8,33 @@
 import FromBase32 from "./FromBase32";
 import FromBase64 from "./FromBase64";
 import FromHex from "./FromHex";
+import Gunzip from "./Gunzip";
+import Gzip from "./Gzip";
+import RawDeflate from "./RawDeflate";
+import RawInflate from "./RawInflate";
 import ShowBase64Offsets from "./ShowBase64Offsets";
 import ToBase32 from "./ToBase32";
 import ToBase64 from "./ToBase64";
 import ToHex from "./ToHex";
+import Unzip from "./Unzip";
+import Zip from "./Zip";
+import ZlibDeflate from "./ZlibDeflate";
+import ZlibInflate from "./ZlibInflate";
 
 export {
     FromBase32,
     FromBase64,
     FromHex,
+    Gunzip,
+    Gzip,
+    RawDeflate,
+    RawInflate,
     ShowBase64Offsets,
     ToBase32,
     ToBase64,
     ToHex,
+    Unzip,
+    Zip,
+    ZlibDeflate,
+    ZlibInflate,
 };

+ 0 - 335
src/core/operations/legacy/Compress.js

@@ -1,22 +1,6 @@
 import Utils from "../Utils.js";
-import rawdeflate from "zlibjs/bin/rawdeflate.min";
-import rawinflate from "zlibjs/bin/rawinflate.min";
-import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min";
-import zip from "zlibjs/bin/zip.min";
-import unzip from "zlibjs/bin/unzip.min";
 import bzip2 from "exports-loader?bzip2!../vendor/bzip2.js";
 
-const Zlib = {
-    RawDeflate: rawdeflate.Zlib.RawDeflate,
-    RawInflate: rawinflate.Zlib.RawInflate,
-    Deflate:    zlibAndGzip.Zlib.Deflate,
-    Inflate:    zlibAndGzip.Zlib.Inflate,
-    Gzip:       zlibAndGzip.Zlib.Gzip,
-    Gunzip:     zlibAndGzip.Zlib.Gunzip,
-    Zip:        zip.Zlib.Zip,
-    Unzip:      unzip.Zlib.Unzip,
-};
-
 
 /**
  * Compression operations.
@@ -29,325 +13,6 @@ const Zlib = {
  */
 const Compress = {
 
-    /**
-     * @constant
-     * @default
-     */
-    COMPRESSION_TYPE: ["Dynamic Huffman Coding", "Fixed Huffman Coding", "None (Store)"],
-    /**
-     * @constant
-     * @default
-     */
-    INFLATE_BUFFER_TYPE: ["Adaptive", "Block"],
-    /**
-     * @constant
-     * @default
-     */
-    COMPRESSION_METHOD: ["Deflate", "None (Store)"],
-    /**
-     * @constant
-     * @default
-     */
-    OS: ["MSDOS", "Unix", "Macintosh"],
-    /**
-     * @constant
-     * @default
-     */
-    RAW_COMPRESSION_TYPE_LOOKUP: {
-        "Fixed Huffman Coding":   Zlib.RawDeflate.CompressionType.FIXED,
-        "Dynamic Huffman Coding": Zlib.RawDeflate.CompressionType.DYNAMIC,
-        "None (Store)":           Zlib.RawDeflate.CompressionType.NONE,
-    },
-
-    /**
-     * Raw Deflate operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runRawDeflate: function(input, args) {
-        const deflate = new Zlib.RawDeflate(input, {
-            compressionType: Compress.RAW_COMPRESSION_TYPE_LOOKUP[args[0]]
-        });
-        return Array.prototype.slice.call(deflate.compress());
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    INFLATE_INDEX: 0,
-    /**
-     * @constant
-     * @default
-     */
-    INFLATE_BUFFER_SIZE: 0,
-    /**
-     * @constant
-     * @default
-     */
-    INFLATE_RESIZE: false,
-    /**
-     * @constant
-     * @default
-     */
-    INFLATE_VERIFY: false,
-    /**
-     * @constant
-     * @default
-     */
-    RAW_BUFFER_TYPE_LOOKUP: {
-        "Adaptive": Zlib.RawInflate.BufferType.ADAPTIVE,
-        "Block":    Zlib.RawInflate.BufferType.BLOCK,
-    },
-
-    /**
-     * Raw Inflate operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runRawInflate: function(input, args) {
-        // Deal with character encoding issues
-        input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
-        let inflate = new Zlib.RawInflate(input, {
-                index: args[0],
-                bufferSize: args[1],
-                bufferType: Compress.RAW_BUFFER_TYPE_LOOKUP[args[2]],
-                resize: args[3],
-                verify: args[4]
-            }),
-            result = Array.prototype.slice.call(inflate.decompress());
-
-        // Raw Inflate somethimes messes up and returns nonsense like this:
-        // ]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]....]...
-        // e.g. Input data of [8b, 1d, dc, 44]
-        // Look for the first two square brackets:
-        if (result.length > 158 && result[0] === 93 && result[5] === 93) {
-            // If the first two square brackets are there, check that the others
-            // are also there. If they are, throw an error. If not, continue.
-            let valid = false;
-            for (let i = 0; i < 155; i += 5) {
-                if (result[i] !== 93) {
-                    valid = true;
-                }
-            }
-
-            if (!valid) {
-                throw "Error: Unable to inflate data";
-            }
-        }
-        // Trust me, this is the easiest way...
-        return result;
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    ZLIB_COMPRESSION_TYPE_LOOKUP: {
-        "Fixed Huffman Coding":   Zlib.Deflate.CompressionType.FIXED,
-        "Dynamic Huffman Coding": Zlib.Deflate.CompressionType.DYNAMIC,
-        "None (Store)":           Zlib.Deflate.CompressionType.NONE,
-    },
-
-    /**
-     * Zlib Deflate operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runZlibDeflate: function(input, args) {
-        const deflate = new Zlib.Deflate(input, {
-            compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]]
-        });
-        return Array.prototype.slice.call(deflate.compress());
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    ZLIB_BUFFER_TYPE_LOOKUP: {
-        "Adaptive": Zlib.Inflate.BufferType.ADAPTIVE,
-        "Block":    Zlib.Inflate.BufferType.BLOCK,
-    },
-
-    /**
-     * Zlib Inflate operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runZlibInflate: function(input, args) {
-        // Deal with character encoding issues
-        input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
-        const inflate = new Zlib.Inflate(input, {
-            index: args[0],
-            bufferSize: args[1],
-            bufferType: Compress.ZLIB_BUFFER_TYPE_LOOKUP[args[2]],
-            resize: args[3],
-            verify: args[4]
-        });
-        return Array.prototype.slice.call(inflate.decompress());
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    GZIP_CHECKSUM: false,
-
-    /**
-     * Gzip operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runGzip: function(input, args) {
-        let filename = args[1],
-            comment = args[2],
-            options = {
-                deflateOptions: {
-                    compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[0]]
-                },
-                flags: {
-                    fhcrc: args[3]
-                }
-            };
-
-        if (filename.length) {
-            options.flags.fname = true;
-            options.filename = filename;
-        }
-        if (comment.length) {
-            options.flags.fcommenct = true;
-            options.comment = comment;
-        }
-
-        const gzip = new Zlib.Gzip(input, options);
-        return Array.prototype.slice.call(gzip.compress());
-    },
-
-
-    /**
-     * Gunzip operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runGunzip: function(input, args) {
-        // Deal with character encoding issues
-        input = Utils.strToByteArray(Utils.byteArrayToUtf8(input));
-        const gunzip = new Zlib.Gunzip(input);
-        return Array.prototype.slice.call(gunzip.decompress());
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    PKZIP_FILENAME: "file.txt",
-    /**
-     * @constant
-     * @default
-     */
-    ZIP_COMPRESSION_METHOD_LOOKUP: {
-        "Deflate":      Zlib.Zip.CompressionMethod.DEFLATE,
-        "None (Store)": Zlib.Zip.CompressionMethod.STORE
-    },
-    /**
-     * @constant
-     * @default
-     */
-    ZIP_OS_LOOKUP: {
-        "MSDOS":     Zlib.Zip.OperatingSystem.MSDOS,
-        "Unix":      Zlib.Zip.OperatingSystem.UNIX,
-        "Macintosh": Zlib.Zip.OperatingSystem.MACINTOSH
-    },
-
-    /**
-     * Zip operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {byteArray}
-     */
-    runPkzip: function(input, args) {
-        let password = Utils.strToByteArray(args[2]),
-            options = {
-                filename: Utils.strToByteArray(args[0]),
-                comment: Utils.strToByteArray(args[1]),
-                compressionMethod: Compress.ZIP_COMPRESSION_METHOD_LOOKUP[args[3]],
-                os: Compress.ZIP_OS_LOOKUP[args[4]],
-                deflateOption: {
-                    compressionType: Compress.ZLIB_COMPRESSION_TYPE_LOOKUP[args[5]]
-                },
-            },
-            zip = new Zlib.Zip();
-
-        if (password.length)
-            zip.setPassword(password);
-        zip.addFile(input, options);
-        return Array.prototype.slice.call(zip.compress());
-    },
-
-
-    /**
-     * @constant
-     * @default
-     */
-    PKUNZIP_VERIFY: false,
-
-    /**
-     * Unzip operation.
-     *
-     * @param {byteArray} input
-     * @param {Object[]} args
-     * @returns {string}
-     */
-    runPkunzip: function(input, args) {
-        let options = {
-                password: Utils.strToByteArray(args[0]),
-                verify: args[1]
-            },
-            unzip = new Zlib.Unzip(input, options),
-            filenames = unzip.getFilenames(),
-            files = [];
-
-        filenames.forEach(function(fileName) {
-            const bytes = unzip.decompress(fileName);
-            const contents = Utils.byteArrayToUtf8(bytes);
-
-            const file = {
-                fileName: fileName,
-                size: contents.length,
-            };
-
-            const isDir = contents.length === 0 && fileName.endsWith("/");
-            if (!isDir) {
-                file.bytes = bytes;
-                file.contents = contents;
-            }
-
-            files.push(file);
-        });
-
-        return Utils.displayFilesAsHTML(files);
-    },
-
-
     /**
      * Bzip2 Decompress operation.
      *