浏览代码

Changed all error returns to OperationErrors

Matt C 7 年之前
父节点
当前提交
2e4f5b7070

+ 6 - 3
src/core/operations/AESDecrypt.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import forge from "node-forge/dist/forge.min.js";
+import OperationError from "../errors/OperationError";
 
 /**
  * AES Decrypt operation
@@ -65,6 +66,8 @@ class AESDecrypt extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if cannot decrypt input or invalid key length
      */
     run(input, args) {
         const key = Utils.convertToByteArray(args[0].string, args[0].option),
@@ -75,12 +78,12 @@ class AESDecrypt extends Operation {
             gcmTag = Utils.convertToByteString(args[5].string, args[5].option);
 
         if ([16, 24, 32].indexOf(key.length) < 0) {
-            return `Invalid key length: ${key.length} bytes
+            throw new OperationError(`Invalid key length: ${key.length} bytes
 
 The following algorithms will be used based on the size of the key:
   16 bytes = AES-128
   24 bytes = AES-192
-  32 bytes = AES-256`;
+  32 bytes = AES-256`);
         }
 
         input = Utils.convertToByteString(input, inputType);
@@ -96,7 +99,7 @@ The following algorithms will be used based on the size of the key:
         if (result) {
             return outputType === "Hex" ? decipher.output.toHex() : decipher.output.getBytes();
         } else {
-            return "Unable to decrypt input with these parameters.";
+            throw new OperationError("Unable to decrypt input with these parameters.");
         }
     }
 

+ 5 - 2
src/core/operations/AESEncrypt.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import forge from "node-forge/dist/forge.min.js";
+import OperationError from "../errors/OperationError";
 
 /**
  * AES Encrypt operation
@@ -59,6 +60,8 @@ class AESEncrypt extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if invalid key length
      */
     run(input, args) {
         const key = Utils.convertToByteArray(args[0].string, args[0].option),
@@ -68,12 +71,12 @@ class AESEncrypt extends Operation {
             outputType = args[4];
 
         if ([16, 24, 32].indexOf(key.length) < 0) {
-            return `Invalid key length: ${key.length} bytes
+            throw new OperationError(`Invalid key length: ${key.length} bytes
 
 The following algorithms will be used based on the size of the key:
   16 bytes = AES-128
   24 bytes = AES-192
-  32 bytes = AES-256`;
+  32 bytes = AES-256`);
         }
 
         input = Utils.convertToByteString(input, inputType);

+ 2 - 0
src/core/operations/AffineCipherDecode.mjs

@@ -42,6 +42,8 @@ class AffineCipherDecode extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if a or b values are invalid
      */
     run(input, args) {
         const alphabet = "abcdefghijklmnopqrstuvwxyz",

+ 2 - 0
src/core/operations/BifidCipherDecode.mjs

@@ -37,6 +37,8 @@ class BifidCipherDecode extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if invalid key
      */
     run(input, args) {
         const keywordStr = args[0].toUpperCase().replace("J", "I"),

+ 2 - 0
src/core/operations/BifidCipherEncode.mjs

@@ -37,6 +37,8 @@ class BifidCipherEncode extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if key is invalid
      */
     run(input, args) {
         const keywordStr = args[0].toUpperCase().replace("J", "I"),

+ 1 - 1
src/core/operations/CartesianProduct.mjs

@@ -41,7 +41,7 @@ class CartesianProduct extends Operation {
      * Validate input length
      *
      * @param {Object[]} sets
-     * @throws {Error} if fewer than 2 sets
+     * @throws {OperationError} if fewer than 2 sets
      */
     validateSampleNumbers(sets) {
         if (!sets || sets.length < 2) {

+ 5 - 1
src/core/operations/DisassembleX86.mjs

@@ -6,6 +6,8 @@
 
 import Operation from "../Operation";
 import * as disassemble from "../vendor/DisassembleX86-64";
+import OperationError from "../errors/OperationError";
+
 /**
  * Disassemble x86 operation
  */
@@ -68,6 +70,8 @@ class DisassembleX86 extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if invalid mode value
      */
     run(input, args) {
         const mode = args[0],
@@ -88,7 +92,7 @@ class DisassembleX86 extends Operation {
                 disassemble.setBitMode(0);
                 break;
             default:
-                throw "Invalid mode value";
+                throw new OperationError("Invalid mode value");
         }
 
         switch (compatibility) {

+ 4 - 1
src/core/operations/DropBytes.mjs

@@ -5,6 +5,7 @@
  */
 
 import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
 
 /**
  * Drop bytes operation
@@ -45,6 +46,8 @@ class DropBytes extends Operation {
      * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @returns {ArrayBuffer}
+     *
+     * @throws {OperationError} if invalid input
      */
     run(input, args) {
         const start = args[0],
@@ -52,7 +55,7 @@ class DropBytes extends Operation {
             applyToEachLine = args[2];
 
         if (start < 0 || length < 0)
-            throw "Error: Invalid value";
+            throw new OperationError("Error: Invalid value");
 
         if (!applyToEachLine) {
             const left = input.slice(0, start),

+ 2 - 1
src/core/operations/Filter.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import {INPUT_DELIM_OPTIONS} from "../lib/Delim";
+import OperationError from "../errors/OperationError";
 
 /**
  * Filter operation
@@ -56,7 +57,7 @@ class Filter extends Operation {
         try {
             regex = new RegExp(args[1]);
         } catch (err) {
-            return "Invalid regex. Details: " + err.message;
+            throw new OperationError(`Invalid regex. Details: ${err.message}`);
         }
 
         const regexFilter = function(value) {

+ 4 - 1
src/core/operations/FromCharcode.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import {DELIM_OPTIONS} from "../lib/Delim";
+import OperationError from "../errors/OperationError";
 
 /**
  * From Charcode operation
@@ -42,6 +43,8 @@ class FromCharcode extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {byteArray}
+     *
+     * @throws {OperationError} if base out of range
      */
     run(input, args) {
         const delim = Utils.charRep(args[0] || "Space"),
@@ -50,7 +53,7 @@ class FromCharcode extends Operation {
             i = 0;
 
         if (base < 2 || base > 36) {
-            throw "Error: Base argument must be between 2 and 36";
+            throw new OperationError("Error: Base argument must be between 2 and 36");
         }
 
         if (input.length === 0) {

+ 4 - 1
src/core/operations/FromUNIXTimestamp.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import moment from "moment-timezone";
 import {UNITS} from "../lib/DateTime";
+import OperationError from "../errors/OperationError";
 
 /**
  * From UNIX Timestamp operation
@@ -37,6 +38,8 @@ class FromUNIXTimestamp extends Operation {
      * @param {number} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if invalid unit
      */
     run(input, args) {
         const units = args[0];
@@ -57,7 +60,7 @@ class FromUNIXTimestamp extends Operation {
             d = moment(input / 1000000);
             return d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss.SSS") + " UTC";
         } else {
-            throw "Unrecognised unit";
+            throw new OperationError("Unrecognised unit");
         }
     }
 

+ 3 - 2
src/core/operations/HammingDistance.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import {fromHex} from "../lib/Hex";
+import OperationError from "../errors/OperationError";
 
 /**
  * Hamming Distance operation
@@ -55,11 +56,11 @@ class HammingDistance extends Operation {
             samples = input.split(delim);
 
         if (samples.length !== 2) {
-            return "Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.";
+            throw new OperationError("Error: You can only calculae the edit distance between 2 strings. Please ensure exactly two inputs are provided, separated by the specified delimiter.");
         }
 
         if (samples[0].length !== samples[1].length) {
-            return "Error: Both inputs must be of the same length.";
+            throw new OperationError("Error: Both inputs must be of the same length.");
         }
 
         if (inputType === "Hex") {

+ 2 - 1
src/core/operations/OffsetChecker.mjs

@@ -6,6 +6,7 @@
 
 import Operation from "../Operation";
 import Utils from "../Utils";
+import OperationError from "../errors/OperationError";
 
 /**
  * Offset checker operation
@@ -48,7 +49,7 @@ class OffsetChecker extends Operation {
             chr;
 
         if (!samples || samples.length < 2) {
-            return "Not enough samples, perhaps you need to modify the sample delimiter or add more data?";
+            throw new OperationError("Not enough samples, perhaps you need to modify the sample delimiter or add more data?");
         }
 
         // Initialise output strings

+ 6 - 2
src/core/operations/PGPDecrypt.mjs

@@ -7,9 +7,11 @@
 import Operation from "../Operation";
 import kbpgp from "kbpgp";
 import { ASP, importPrivateKey } from "../lib/PGP";
+import OperationError from "../errors/OperationError";
 import promisifyDefault from "es6-promisify";
 const promisify = promisifyDefault.promisify;
 
+
 /**
  * PGP Decrypt operation
  */
@@ -44,6 +46,8 @@ class PGPDecrypt extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if invalid private key
      */
     async run(input, args) {
         const encryptedMessage = input,
@@ -52,7 +56,7 @@ class PGPDecrypt extends Operation {
             keyring = new kbpgp.keyring.KeyRing();
         let plaintextMessage;
 
-        if (!privateKey) return "Enter the private key of the recipient.";
+        if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
 
         const key = await importPrivateKey(privateKey, passphrase);
         keyring.add_key_manager(key);
@@ -64,7 +68,7 @@ class PGPDecrypt extends Operation {
                 asp: ASP
             });
         } catch (err) {
-            throw `Couldn't decrypt message with provided private key: ${err}`;
+            throw new OperationError(`Couldn't decrypt message with provided private key: ${err}`);
         }
 
         return plaintextMessage.toString();

+ 6 - 5
src/core/operations/PGPDecryptAndVerify.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import kbpgp from "kbpgp";
 import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
+import OperationError from "../errors/OperationError";
 import promisifyDefault from "es6-promisify";
 const promisify = promisifyDefault.promisify;
 
@@ -58,8 +59,8 @@ class PGPDecryptAndVerify extends Operation {
             keyring = new kbpgp.keyring.KeyRing();
         let unboxedLiterals;
 
-        if (!publicKey) return "Enter the public key of the signer.";
-        if (!privateKey) return "Enter the private key of the recipient.";
+        if (!publicKey) throw new OperationError("Enter the public key of the signer.");
+        if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
         const privKey = await importPrivateKey(privateKey, passphrase);
         const pubKey = await importPublicKey(publicKey);
         keyring.add_key_manager(privKey);
@@ -97,13 +98,13 @@ class PGPDecryptAndVerify extends Operation {
                     text += unboxedLiterals.toString();
                     return text.trim();
                 } else {
-                    return "Could not identify a key manager.";
+                    throw new OperationError("Could not identify a key manager.");
                 }
             } else {
-                return "The data does not appear to be signed.";
+                throw new OperationError("The data does not appear to be signed.");
             }
         } catch (err) {
-            return `Couldn't verify message: ${err}`;
+            throw new OperationError(`Couldn't verify message: ${err}`);
         }
     }
 

+ 7 - 3
src/core/operations/PGPEncrypt.mjs

@@ -7,8 +7,10 @@
 import Operation from "../Operation";
 import kbpgp from "kbpgp";
 import { ASP } from "../lib/PGP";
+import OperationError from "../errors/OperationError";
 import promisifyDefault from "es6-promisify";
 const promisify = promisifyDefault.promisify;
+
 /**
  * PGP Encrypt operation
  */
@@ -38,6 +40,8 @@ class PGPEncrypt extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if failed private key import or failed encryption
      */
     async run(input, args) {
         const plaintextMessage = input,
@@ -45,14 +49,14 @@ class PGPEncrypt extends Operation {
         let key,
             encryptedMessage;
 
-        if (!plainPubKey) return "Enter the public key of the recipient.";
+        if (!plainPubKey) throw new OperationError("Enter the public key of the recipient.");
 
         try {
             key = await promisify(kbpgp.KeyManager.import_from_armored_pgp)({
                 armored: plainPubKey,
             });
         } catch (err) {
-            throw `Could not import public key: ${err}`;
+            throw new OperationError(`Could not import public key: ${err}`);
         }
 
         try {
@@ -62,7 +66,7 @@ class PGPEncrypt extends Operation {
                 "asp": ASP
             });
         } catch (err) {
-            throw `Couldn't encrypt message with provided public key: ${err}`;
+            throw new OperationError(`Couldn't encrypt message with provided public key: ${err}`);
         }
 
         return encryptedMessage.toString();

+ 6 - 3
src/core/operations/PGPEncryptAndSign.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import kbpgp from "kbpgp";
 import { ASP, importPrivateKey, importPublicKey } from "../lib/PGP";
+import OperationError from "../errors/OperationError";
 import promisifyDefault from "es6-promisify";
 const promisify = promisifyDefault.promisify;
 
@@ -49,6 +50,8 @@ class PGPEncryptAndSign extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if failure to sign message
      */
     async run(input, args) {
         const message = input,
@@ -57,8 +60,8 @@ class PGPEncryptAndSign extends Operation {
             publicKey = args[2];
         let signedMessage;
 
-        if (!privateKey) return "Enter the private key of the signer.";
-        if (!publicKey) return "Enter the public key of the recipient.";
+        if (!privateKey) throw new OperationError("Enter the private key of the signer.");
+        if (!publicKey) throw new OperationError("Enter the public key of the recipient.");
         const privKey = await importPrivateKey(privateKey, passphrase);
         const pubKey = await importPublicKey(publicKey);
 
@@ -70,7 +73,7 @@ class PGPEncryptAndSign extends Operation {
                 "asp": ASP
             });
         } catch (err) {
-            throw `Couldn't sign message: ${err}`;
+            throw new OperationError(`Couldn't sign message: ${err}`);
         }
 
         return signedMessage;

+ 2 - 1
src/core/operations/ParseDateTime.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import moment from "moment-timezone";
 import {DATETIME_FORMATS, FORMAT_EXAMPLES} from "../lib/DateTime";
+import OperationError from "../errors/OperationError";
 
 /**
  * Parse DateTime operation
@@ -59,7 +60,7 @@ class ParseDateTime extends Operation {
             date = moment.tz(input, inputFormat, inputTimezone);
             if (!date || date.format() === "Invalid date") throw Error;
         } catch (err) {
-            return "Invalid format.\n\n" + FORMAT_EXAMPLES;
+            throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`);
         }
 
         output += "Date: " + date.format("dddd Do MMMM YYYY") +

+ 2 - 1
src/core/operations/ParseUNIXFilePermissions.mjs

@@ -5,6 +5,7 @@
  */
 
 import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
 
 /**
  * Parse UNIX file permissions operation
@@ -169,7 +170,7 @@ class ParseUNIXFilePermissions extends Operation {
                 }
             }
         } else {
-            return "Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.";
+            throw new OperationError("Invalid input format.\nPlease enter the permissions in either octal (e.g. 755) or textual (e.g. drwxr-xr-x) format.");
         }
 
         output += "Textual representation: " + permsToStr(perms);

+ 2 - 1
src/core/operations/RawInflate.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import {INFLATE_BUFFER_TYPE} from "../lib/Zlib";
 import rawinflate from "zlibjs/bin/rawinflate.min";
+import OperationError from "../errors/OperationError";
 
 const Zlib = rawinflate.Zlib;
 
@@ -90,7 +91,7 @@ class RawInflate extends Operation {
             }
 
             if (!valid) {
-                throw "Error: Unable to inflate data";
+                throw new OperationError("Error: Unable to inflate data");
             }
         }
         // This seems to be the easiest way...

+ 2 - 1
src/core/operations/ShowBase64Offsets.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import {fromBase64, toBase64} from "../lib/Base64";
+import OperationError from "../errors/OperationError";
 
 /**
  * Show Base64 offsets operation
@@ -58,7 +59,7 @@ class ShowBase64Offsets extends Operation {
             script = "<script type='application/javascript'>$('[data-toggle=\"tooltip\"]').tooltip()</script>";
 
         if (input.length < 1) {
-            return "Please enter a string.";
+            throw new OperationError("Please enter a string.");
         }
 
         // Highlight offset 0

+ 4 - 1
src/core/operations/TakeBytes.mjs

@@ -5,6 +5,7 @@
  */
 
 import Operation from "../Operation";
+import OperationError from "../errors/OperationError";
 
 /**
  * Take bytes operation
@@ -45,6 +46,8 @@ class TakeBytes extends Operation {
      * @param {ArrayBuffer} input
      * @param {Object[]} args
      * @returns {ArrayBuffer}
+     *
+     * @throws {OperationError} if invalid value
      */
     run(input, args) {
         const start = args[0],
@@ -52,7 +55,7 @@ class TakeBytes extends Operation {
             applyToEachLine = args[2];
 
         if (start < 0 || length < 0)
-            throw "Error: Invalid value";
+            throw new OperationError("Error: Invalid value");
 
         if (!applyToEachLine)
             return input.slice(start, start+length);

+ 4 - 1
src/core/operations/ToCharcode.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import Utils from "../Utils";
 import {DELIM_OPTIONS} from "../lib/Delim";
+import OperationError from "../errors/OperationError";
 
 /**
  * To Charcode operation
@@ -42,6 +43,8 @@ class ToCharcode extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if base argument out of range
      */
     run(input, args) {
         const delim = Utils.charRep(args[0] || "Space"),
@@ -51,7 +54,7 @@ class ToCharcode extends Operation {
             ordinal;
 
         if (base < 2 || base > 36) {
-            throw "Error: Base argument must be between 2 and 36";
+            throw new OperationError("Error: Base argument must be between 2 and 36");
         }
 
         const charcode = Utils.strToCharcode(input);

+ 4 - 1
src/core/operations/ToUNIXTimestamp.mjs

@@ -7,6 +7,7 @@
 import Operation from "../Operation";
 import moment from "moment-timezone";
 import {UNITS} from "../lib/DateTime";
+import OperationError from "../errors/OperationError";
 
 /**
  * To UNIX Timestamp operation
@@ -47,6 +48,8 @@ class ToUNIXTimestamp extends Operation {
      * @param {string} input
      * @param {Object[]} args
      * @returns {string}
+     *
+     * @throws {OperationError} if unit unrecognised
      */
     run(input, args) {
         const [units, treatAsUTC, showDateTime] = args,
@@ -63,7 +66,7 @@ class ToUNIXTimestamp extends Operation {
         } else if (units === "Nanoseconds (ns)") {
             result = d.valueOf() * 1000000;
         } else {
-            throw "Unrecognised unit";
+            throw new OperationError("Unrecognised unit");
         }
 
         return showDateTime ? `${result} (${d.tz("UTC").format("ddd D MMMM YYYY HH:mm:ss")} UTC)` : result.toString();

+ 1 - 1
src/core/operations/TranslateDateTimeFormat.mjs

@@ -67,7 +67,7 @@ class TranslateDateTimeFormat extends Operation {
             date = moment.tz(input, inputFormat, inputTimezone);
             if (!date || date.format() === "Invalid date") throw Error;
         } catch (err) {
-            return "Invalid format.\n\n" + FORMAT_EXAMPLES;
+            throw new OperationError(`Invalid format.\n\n${FORMAT_EXAMPLES}`);
         }
 
         return date.tz(outputTimezone).format(outputFormat);