Browse Source

Operations can now set options from within the worker

n1474335 7 years ago
parent
commit
f6b52b7c82

+ 4 - 1
.eslintrc.json

@@ -97,6 +97,9 @@
 
         "COMPILE_TIME": false,
         "COMPILE_MSG": false,
-        "PKG_VERSION": false
+        "PKG_VERSION": false,
+        "ENVIRONMENT_IS_WORKER": false,
+        "ENVIRONMENT_IS_NODE": false,
+        "ENVIRONMENT_IS_WEB": false
     }
 }

+ 18 - 3
Gruntfile.js

@@ -72,7 +72,16 @@ module.exports = function (grunt) {
         BUILD_CONSTANTS = {
             COMPILE_TIME: JSON.stringify(compileTime),
             COMPILE_MSG: JSON.stringify(grunt.option("compile-msg") || grunt.option("msg") || ""),
-            PKG_VERSION: JSON.stringify(pkg.version)
+            PKG_VERSION: JSON.stringify(pkg.version),
+            ENVIRONMENT_IS_WORKER: function() {
+                return typeof importScripts === "function";
+            },
+            ENVIRONMENT_IS_NODE: function() {
+                return typeof process === "object" && typeof require === "function";
+            },
+            ENVIRONMENT_IS_WEB: function() {
+                return typeof window === "object";
+            }
         },
         moduleEntryPoints = listEntryModules();
 
@@ -277,7 +286,10 @@ module.exports = function (grunt) {
                 output: {
                     filename: "index.js",
                     path: __dirname + "/build/test"
-                }
+                },
+                plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS)
+                ]
             },
             node: {
                 target: "node",
@@ -288,7 +300,10 @@ module.exports = function (grunt) {
                     path: __dirname + "/build/node",
                     library: "CyberChef",
                     libraryTarget: "commonjs2"
-                }
+                },
+                plugins: [
+                    new webpack.DefinePlugin(BUILD_CONSTANTS)
+                ]
             }
         },
         "webpack-dev-server": {

+ 1 - 8
src/core/Chef.js

@@ -30,7 +30,6 @@ const Chef = function() {
  * @returns {string} response.result - The output of the recipe
  * @returns {string} response.type - The data type of the result
  * @returns {number} response.progress - The position that we have got to in the recipe
- * @returns {number} response.options - The app options object (which may have been changed)
  * @returns {number} response.duration - The number of ms it took to execute the recipe
  * @returns {number} response.error - The error object thrown by a failed operation (false if no error)
 */
@@ -40,12 +39,7 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
         containsFc = recipe.containsFlowControl(),
         error      = false;
 
-    // Reset attemptHighlight flag
-    if (options.hasOwnProperty("attemptHighlight")) {
-        options.attemptHighlight = true;
-    }
-
-    if (containsFc) options.attemptHighlight = false;
+    if (containsFc && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
     // Clean up progress
     if (progress >= recipeConfig.length) {
@@ -86,7 +80,6 @@ Chef.prototype.bake = async function(inputText, recipeConfig, options, progress,
             this.dish.get(Dish.STRING),
         type: Dish.enumLookup(this.dish.type),
         progress: progress,
-        options: options,
         duration: new Date().getTime() - startTime,
         error: error
     };

+ 25 - 7
src/core/ChefWorker.js

@@ -41,23 +41,24 @@ self.postMessage({
  */
 self.addEventListener("message", function(e) {
     // Handle message
-    switch (e.data.action) {
+    const r = e.data;
+    switch (r.action) {
         case "bake":
-            bake(e.data.data);
+            bake(r.data);
             break;
         case "silentBake":
-            silentBake(e.data.data);
+            silentBake(r.data);
             break;
         case "docURL":
             // Used to set the URL of the current document so that scripts can be
             // imported into an inline worker.
-            self.docURL = e.data.data;
+            self.docURL = r.data;
             break;
         case "highlight":
             calculateHighlights(
-                e.data.data.recipeConfig,
-                e.data.data.direction,
-                e.data.data.pos
+                r.data.recipeConfig,
+                r.data.direction,
+                r.data.pos
             );
             break;
         default:
@@ -158,3 +159,20 @@ self.sendStatusMessage = function(msg) {
         data: msg
     });
 };
+
+
+/**
+ * Send an option value update to the app.
+ *
+ * @param {string} option
+ * @param {*} value
+ */
+self.setOption = function(option, value) {
+    self.postMessage({
+        action: "optionUpdate",
+        data: {
+            option: option,
+            value: value
+        }
+    });
+};

+ 14 - 5
src/core/Utils.js

@@ -234,7 +234,7 @@ const Utils = {
      * @returns {string}
      */
     printable: function(str, preserveWs) {
-        if (typeof window !== "undefined" && window.app && !window.app.options.treatAsUtf8) {
+        if (ENVIRONMENT_IS_WEB() && window.app && !window.app.options.treatAsUtf8) {
             str = Utils.byteArrayToChars(Utils.strToByteArray(str));
         }
 
@@ -384,8 +384,12 @@ const Utils = {
         let wordArray = CryptoJS.enc.Utf8.parse(str),
             byteArray = Utils.wordArrayToByteArray(wordArray);
 
-        if (typeof window !== "undefined" && str.length !== wordArray.sigBytes) {
-            window.app.options.attemptHighlight = false;
+        if (str.length !== wordArray.sigBytes) {
+            if (ENVIRONMENT_IS_WORKER()) {
+                self.setOption("attemptHighlight", false);
+            } else if (ENVIRONMENT_IS_WEB()) {
+                window.app.options.attemptHighlight = false;
+            }
         }
         return byteArray;
     },
@@ -448,8 +452,13 @@ const Utils = {
             let wordArray = new CryptoJS.lib.WordArray.init(words, byteArray.length),
                 str = CryptoJS.enc.Utf8.stringify(wordArray);
 
-            if (typeof window !== "undefined" && str.length !== wordArray.sigBytes)
-                window.app.options.attemptHighlight = false;
+            if (str.length !== wordArray.sigBytes) {
+                if (ENVIRONMENT_IS_WORKER()) {
+                    self.setOption("attemptHighlight", false);
+                } else if (ENVIRONMENT_IS_WEB()) {
+                    window.app.options.attemptHighlight = false;
+                }
+            }
             return str;
         } catch (err) {
             // If it fails, treat it as ANSI

+ 3 - 2
src/core/operations/BitwiseOp.js

@@ -137,7 +137,8 @@ const BitwiseOp = {
 
         input = input.slice(sampleOffset, sampleOffset + sampleLength);
 
-        if (self) self.sendStatusMessage("Calculating " + Math.pow(256, keyLength) + " values...");
+        if (ENVIRONMENT_IS_WORKER())
+            self.sendStatusMessage("Calculating " + Math.pow(256, keyLength) + " values...");
 
         /**
          * Converts an integer to an array of bytes expressing that number.
@@ -156,7 +157,7 @@ const BitwiseOp = {
         };
 
         for (let key = 1, l = Math.pow(256, keyLength); key < l; key++) {
-            if (key % 10000 === 0 && self) {
+            if (key % 10000 === 0 && ENVIRONMENT_IS_WORKER()) {
                 self.sendStatusMessage("Calculating " + l + " values... " + Math.floor(key / l * 100) + "%");
             }
 

+ 3 - 5
src/core/operations/ByteRepr.js

@@ -119,11 +119,11 @@ const ByteRepr = {
                 else if (ordinal < 4294967296) padding = 8;
                 else padding = 2;
 
-                if (padding > 2 && app) app.options.attemptHighlight = false;
+                if (padding > 2 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
                 output += Utils.hex(ordinal, padding) + delim;
             } else {
-                if (app) app.options.attemptHighlight = false;
+                if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
                 output += ordinal.toString(base) + delim;
             }
         }
@@ -149,9 +149,7 @@ const ByteRepr = {
             throw "Error: Base argument must be between 2 and 36";
         }
 
-        if (base !== 16 && app) {
-            app.options.attemptHighlight = false;
-        }
+        if (base !== 16 && ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
 
         // Split into groups of 2 if the whole string is concatenated and
         // too long to be a single character

+ 1 - 1
src/core/operations/Hexdump.js

@@ -92,7 +92,7 @@ const Hexdump = {
         const w = (width - 13) / 4;
         // w should be the specified width of the hexdump and therefore a round number
         if (Math.floor(w) !== w || input.indexOf("\r") !== -1 || output.indexOf(13) !== -1) {
-            //TODO if (self) self.setOption("attemptHighlight", false);
+            if (ENVIRONMENT_IS_WORKER()) self.setOption("attemptHighlight", false);
         }
         return output;
     },

+ 3 - 0
src/web/App.js

@@ -105,6 +105,9 @@ App.prototype.handleError = function(err) {
 App.prototype.bake = function(step) {
     if (this.baking) return;
 
+    // Reset attemptHighlight flag
+    this.options.attemptHighlight = true;
+
     this.manager.worker.bake(
         this.getInput(),        // The user's input
         this.getRecipeConfig(), // The configuration of the recipe

+ 9 - 6
src/web/WorkerWaiter.js

@@ -40,12 +40,13 @@ WorkerWaiter.prototype.registerChefWorker = function() {
  * @param {MessageEvent} e
  */
 WorkerWaiter.prototype.handleChefMessage = function(e) {
-    switch (e.data.action) {
+    const r = e.data;
+    switch (r.action) {
         case "bakeSuccess":
-            this.bakingComplete(e.data.data);
+            this.bakingComplete(r.data);
             break;
         case "bakeError":
-            this.app.handleError(e.data.data);
+            this.app.handleError(r.data);
             this.setBakingStatus(false);
             break;
         case "silentBakeComplete":
@@ -55,10 +56,13 @@ WorkerWaiter.prototype.handleChefMessage = function(e) {
             this.app.loaded();
             break;
         case "statusMessage":
-            this.manager.output.setStatusMsg(e.data.data);
+            this.manager.output.setStatusMsg(r.data);
+            break;
+        case "optionUpdate":
+            this.app.options[r.data.option] = r.data.value;
             break;
         case "highlightsCalculated":
-            this.manager.highlighter.displayHighlights(e.data.data.pos, e.data.data.direction);
+            this.manager.highlighter.displayHighlights(r.data.pos, r.data.direction);
             break;
         default:
             console.error("Unrecognised message from ChefWorker", e);
@@ -104,7 +108,6 @@ WorkerWaiter.prototype.bakingComplete = function(response) {
         this.app.handleError(response.error);
     }
 
-    this.app.options  = response.options;
     this.app.dishStr  = response.type === "html" ? Utils.stripHtmlTags(response.result, true) : response.result;
     this.app.progress = response.progress;
     this.manager.recipe.updateBreakpointIndicator(response.progress);