diff --git a/src/web/App.mjs b/src/web/App.mjs index 86a97314..25efd152 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -151,7 +151,7 @@ class App { // has completed. if (this.autoBakePause) return false; - if (this.autoBake_) { + if (this.autoBake_ && !this.baking) { log.debug("Auto-baking"); this.manager.input.inputWorker.postMessage({ action: "autobake", @@ -397,11 +397,10 @@ class App { this.manager.recipe.initialiseOperationDragNDrop(); } - /** - * Checks for input and recipe in the URI parameters and loads them if present. + * */ - loadURIParams() { + getURIParams() { // Load query string or hash from URI (depending on which is populated) // We prefer getting the hash by splitting the href rather than referencing // location.hash as some browsers (Firefox) automatically URL decode it, @@ -409,8 +408,16 @@ class App { const params = window.location.search || window.location.href.split("#")[1] || window.location.hash; - this.uriParams = Utils.parseURIParams(params); + const parsedParams = Utils.parseURIParams(params); + return parsedParams; + } + + /** + * Checks for input and recipe in the URI parameters and loads them if present. + */ + loadURIParams() { this.autoBakePause = true; + this.uriParams = this.getURIParams(); // Read in recipe from URI params if (this.uriParams.recipe) { @@ -662,16 +669,17 @@ class App { this.progress = 0; this.autoBake(); - this.updateUrl(false, ""); + this.updateTitle(false, null, true); } /** - * Update the page URL to contain the new recipe and input + * Update the page title to contain the new recipe * * @param {boolean} includeInput * @param {string} input + * @param {boolean} [changeUrl=true] */ - updateUrl(includeInput, input) { + updateTitle(includeInput, input, changeUrl=true) { // Set title const recipeConfig = this.getRecipeConfig(); let title = "CyberChef"; @@ -690,7 +698,7 @@ class App { document.title = title; // Update the current history state (not creating a new one) - if (this.options.updateUrl) { + if (this.options.updateUrl && changeUrl) { this.lastStateUrl = this.manager.controls.generateStateUrl(true, includeInput, input, recipeConfig); window.history.replaceState({}, title, this.lastStateUrl); } diff --git a/src/web/ControlsWaiter.mjs b/src/web/ControlsWaiter.mjs index 21655f8d..56cfebdd 100755 --- a/src/web/ControlsWaiter.mjs +++ b/src/web/ControlsWaiter.mjs @@ -113,6 +113,7 @@ class ControlsWaiter { * * @param {boolean} includeRecipe - Whether to include the recipe in the URL. * @param {boolean} includeInput - Whether to include the input in the URL. + * @param {string} input * @param {Object[]} [recipeConfig] - The recipe configuration object array. * @param {string} [baseURL] - The CyberChef URL, set to the current URL if not included * @returns {string} @@ -127,6 +128,15 @@ class ControlsWaiter { includeRecipe = includeRecipe && (recipeConfig.length > 0); + // If we don't get passed an input, get it from the current URI + if (input === null) { + const params = this.app.getURIParams(); + if (params.input) { + includeInput = true; + input = params.input; + } + } + const params = [ includeRecipe ? ["recipe", recipeStr] : undefined, includeInput ? ["input", input] : undefined, @@ -333,7 +343,7 @@ class ControlsWaiter { e.preventDefault(); const reportBugInfo = document.getElementById("report-bug-info"); - const saveLink = this.generateStateUrl(true, true, null, "https://gchq.github.io/CyberChef/"); + const saveLink = this.generateStateUrl(true, true, null, null, "https://gchq.github.io/CyberChef/"); if (reportBugInfo) { reportBugInfo.innerHTML = `* Version: ${PKG_VERSION} diff --git a/src/web/InputWaiter.mjs b/src/web/InputWaiter.mjs index 1f403570..79da4d74 100644 --- a/src/web/InputWaiter.mjs +++ b/src/web/InputWaiter.mjs @@ -459,6 +459,15 @@ class InputWaiter { value: value } }); + let includeInput = false; + const recipeStr = toBase64(value, "A-Za-z0-9+/"); // B64 alphabet with no padding + if (recipeStr.length > 0 && recipeStr.length <= 68267) { + includeInput = true; + } + this.setUrl({ + includeInput: includeInput, + input: recipeStr + }); } /** @@ -1214,7 +1223,7 @@ class InputWaiter { * @param {string} urlData.input */ setUrl(urlData) { - this.app.updateUrl(urlData.includeInput, urlData.input); + this.app.updateTitle(urlData.includeInput, urlData.input, true); } diff --git a/src/web/InputWorker.mjs b/src/web/InputWorker.mjs index 0d80dd8c..1aa57084 100644 --- a/src/web/InputWorker.mjs +++ b/src/web/InputWorker.mjs @@ -126,7 +126,8 @@ self.autoBake = function(inputNum) { action: "queueInput", data: { input: inputData, - inputNum: parseInt(inputNum, 10) + inputNum: parseInt(inputNum, 10), + override: true } }); self.postMessage({ @@ -148,7 +149,8 @@ self.getAllInputs = function() { action: "queueInput", data: { input: inputData, - inputNum: inputNums[i] + inputNum: inputNums[i], + override: false } }); } @@ -315,13 +317,13 @@ self.setInput = function(inputData) { input: inputVal }; if (typeof inputVal !== "string") { - inputVal = inputVal.fileBuffer; - const fileSlice = inputVal.slice(0, 512001); - inputObj.input = fileSlice; inputObj.name = inputVal.name; inputObj.size = inputVal.size; inputObj.type = inputVal.type; inputObj.progress = input.progress; + inputVal = inputVal.fileBuffer; + const fileSlice = inputVal.slice(0, 512001); + inputObj.input = fileSlice; self.postMessage({ action: "setInput", @@ -389,20 +391,6 @@ self.updateInputValue = function(inputData) { } self.inputs[inputNum].status = "loaded"; self.inputs[inputNum].progress = 100; - - let includeInput = false; - const recipeStr = toBase64(value, "A-Za-z0-9+/"); // B64 alphabet with no padding - if (recipeStr.length > 0 && recipeStr.length <= 68267) { - includeInput = true; - } - - self.postMessage({ - action: "setUrl", - data: { - includeInput: includeInput, - input: recipeStr - } - }); return; } diff --git a/src/web/WorkerWaiter.mjs b/src/web/WorkerWaiter.mjs index e92d665c..ec8ca3ef 100644 --- a/src/web/WorkerWaiter.mjs +++ b/src/web/WorkerWaiter.mjs @@ -322,6 +322,7 @@ class WorkerWaiter { if (typeof nextInput.inputNum === "string") nextInput.inputNum = parseInt(nextInput.inputNum, 10); log.debug(`Baking input ${nextInput.inputNum}.`); + this.setBakingStatus(true); this.manager.output.updateOutputStatus("baking", nextInput.inputNum); this.manager.output.updateOutputMessage(`Baking input ${nextInput.inputNum}...`, nextInput.inputNum); @@ -386,14 +387,9 @@ class WorkerWaiter { * @param {object} inputData * @param {string | ArrayBuffer} inputData.input * @param {number} inputData.inputNum + * @param {boolean} inputData.override */ queueInput(inputData) { - for (let i = 0; i < this.inputs.length; i++) { - if (this.inputs[i].inputNum === inputData.inputNum) { - this.inputs[i] = inputData; - return; - } - } for (let i = 0; i < this.chefWorkers; i++) { if (this.chefWorkers[i].inputNum === inputData.inputNum) { this.chefWorkers[i].worker.terminate(); @@ -406,8 +402,18 @@ class WorkerWaiter { this.manager.output.updateOutputStatus("pending", inputData.inputNum); this.manager.output.updateOutputMessage(`Input ${inputData.inputNum} has not been baked yet.`); - this.totalOutputs++; - this.inputs.push(inputData); + + if (inputData.override) { + for (let i = this.chefWorkers.length - 1; i >= 0; i--) { + this.removeChefWorker(this.chefWorkers[i]); + } + this.totalOutputs = 1; + this.inputs = [inputData]; + this.bakeNextInput(this.addChefWorker()); + } else { + this.totalOutputs++; + this.inputs.push(inputData); + } } /**