From 91cdd50ba753131265da6350204ea9949f3c6d49 Mon Sep 17 00:00:00 2001 From: j433866 Date: Tue, 13 Aug 2019 14:03:21 +0100 Subject: [PATCH 1/6] Increase size limit for inlined fonts / icons --- webpack.config.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index 46878282..1258a5c4 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -103,11 +103,17 @@ module.exports = { "sass-loader", ] }, + /** + * The limit for these files has been increased to 60,000 (60KB) + * to ensure the material icons font is inlined. + * + * See: https://github.com/gchq/CyberChef/issues/612 + */ { test: /\.(ico|eot|ttf|woff|woff2)$/, loader: "url-loader", options: { - limit: 10000, + limit: 60000, name: "[hash].[ext]", outputPath: "assets" } From 082d939f7d02889b9125d35cfe5a553167ec25f8 Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 22 Aug 2019 11:26:04 +0100 Subject: [PATCH 2/6] Add customisations for confirm box. Can change the text of the accept and reject buttons. Now returns undefined if the user clicks off it --- src/web/App.mjs | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/web/App.mjs b/src/web/App.mjs index 56746a41..60491ef4 100755 --- a/src/web/App.mjs +++ b/src/web/App.mjs @@ -670,18 +670,22 @@ class App { * * @param {string} title - The title of the box * @param {string} body - The question (HTML supported) + * @param {string} accept - The text of the accept button + * @param {string} reject - The text of the reject button * @param {function} callback - A function accepting one boolean argument which handles the * response e.g. function(answer) {...} * @param {Object} [scope=this] - The object to bind to the callback function * * @example * // Pops up a box asking if the user would like a cookie. Prints the answer to the console. - * this.confirm("Question", "Would you like a cookie?", function(answer) {console.log(answer);}); + * this.confirm("Question", "Would you like a cookie?", "Yes", "No", function(answer) {console.log(answer);}); */ - confirm(title, body, callback, scope) { + confirm(title, body, accept, reject, callback, scope) { scope = scope || this; document.getElementById("confirm-title").innerHTML = title; document.getElementById("confirm-body").innerHTML = body; + document.getElementById("confirm-yes").innerText = accept; + document.getElementById("confirm-no").innerText = reject; document.getElementById("confirm-modal").style.display = "block"; this.confirmClosed = false; @@ -694,9 +698,14 @@ class App { callback.bind(scope)(true); $("#confirm-modal").modal("hide"); }.bind(this)) + .one("click", "#confirm-no", function() { + this.confirmClosed = true; + callback.bind(scope)(false); + }.bind(this)) .one("hide.bs.modal", function(e) { - if (!this.confirmClosed) - callback.bind(scope)(false); + if (!this.confirmClosed) { + callback.bind(scope)(undefined); + } this.confirmClosed = true; }.bind(this)); } From 9f2d1453edda0190279fae8c45f6b17885302be7 Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 22 Aug 2019 11:26:43 +0100 Subject: [PATCH 3/6] Make the wordWrap change event only fire when the word wrap checkbox is changed --- src/web/Manager.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/web/Manager.mjs b/src/web/Manager.mjs index 5ab44b21..cb579721 100755 --- a/src/web/Manager.mjs +++ b/src/web/Manager.mjs @@ -224,7 +224,7 @@ class Manager { document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options)); document.getElementById("reset-options").addEventListener("click", this.options.resetOptionsClick.bind(this.options)); this.addDynamicListener(".option-item input[type=checkbox]", "change", this.options.switchChange, this.options); - this.addDynamicListener(".option-item input[type=checkbox]", "change", this.options.setWordWrap, this.options); + this.addDynamicListener(".option-item input[type=checkbox]#wordWrap", "change", this.options.setWordWrap, this.options); this.addDynamicListener(".option-item input[type=checkbox]#useMetaKey", "change", this.bindings.updateKeybList, this.bindings); this.addDynamicListener(".option-item input[type=number]", "keyup", this.options.numberChange, this.options); this.addDynamicListener(".option-item input[type=number]", "change", this.options.numberChange, this.options); From f43a868607832f58929ada59797ffb4a53003f45 Mon Sep 17 00:00:00 2001 From: j433866 Date: Thu, 22 Aug 2019 11:53:41 +0100 Subject: [PATCH 4/6] Add carriage return detection for pasted and switched inputs. Fix switching the output to input not working properly. Add nicer confirmation boxes for zipping outputs. --- src/web/html/index.html | 17 +- src/web/index.js | 4 +- src/web/waiters/InputWaiter.mjs | 101 +++++++--- src/web/waiters/OptionsWaiter.mjs | 308 +++++++++++++++--------------- src/web/waiters/OutputWaiter.mjs | 170 ++++++++++++----- src/web/workers/InputWorker.mjs | 45 +++-- 6 files changed, 399 insertions(+), 246 deletions(-) diff --git a/src/web/html/index.html b/src/web/html/index.html index 011742d3..cb9c3dbe 100755 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -568,11 +568,18 @@
- -
+ + + +
+ +
diff --git a/src/web/waiters/InputWaiter.mjs b/src/web/waiters/InputWaiter.mjs index 36b5f05c..e519b963 100644 --- a/src/web/waiters/InputWaiter.mjs +++ b/src/web/waiters/InputWaiter.mjs @@ -728,30 +728,46 @@ class InputWaiter { e.preventDefault(); e.stopPropagation(); - const pastedData = e.clipboardData.getData("Text"); - const preserve = await this.preserveCarriageReturns(pastedData); - - if (pastedData.length < (this.app.options.ioDisplayThreshold * 1024) && !preserve) { - // Pasting normally fires the inputChange() event before - // changing the value, so instead change it here ourselves - // and manually fire inputChange() - const inputText = document.getElementById("input-text"); - const selStart = inputText.selectionStart; - const selEnd = inputText.selectionEnd; - const startVal = inputText.value.slice(0, selStart); - const endVal = inputText.value.slice(selEnd); - - inputText.value = startVal + pastedData + endVal; - inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length); - this.debounceInputChange(e); - } else { + const self = this; + /** + * Triggers the input file/binary data overlay + * + * @param {string} pastedData + */ + function triggerOverlay(pastedData) { const file = new File([pastedData], "PastedData", { type: "text/plain", lastModified: Date.now() }); - this.loadUIFiles([file]); + self.loadUIFiles([file]); + } + + const pastedData = e.clipboardData.getData("Text"); + const inputText = document.getElementById("input-text"); + const selStart = inputText.selectionStart; + const selEnd = inputText.selectionEnd; + const startVal = inputText.value.slice(0, selStart); + const endVal = inputText.value.slice(selEnd); + const val = startVal + pastedData + endVal; + + if (val.length >= (this.app.options.ioDisplayThreshold * 1024)) { + // Data too large to display, use overlay + triggerOverlay(val); return false; + } else if (await this.preserveCarriageReturns(val)) { + // Data contains a carriage return and the user doesn't wish to edit it, use overlay + // We check this in a separate condition to make sure it is not run unless absolutely + // necessary. + triggerOverlay(val); + return false; + } else { + // Pasting normally fires the inputChange() event before + // changing the value, so instead change it here ourselves + // and manually fire inputChange() + inputText.value = val; + inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length); + this.debounceInputChange(e); } } @@ -839,33 +855,34 @@ class InputWaiter { * preserved, so display an overlay so it can't be edited */ async preserveCarriageReturns(input) { - if (input.indexOf("\r") >= 0) { - const optionsStr = "This behaviour can be changed in the options"; - if (!this.app.options.userSetCR) { - let preserve = await new Promise(function(resolve, reject) { - this.app.confirm( - "Carriage Return Detected", - "A carriage return was detected in your input. As HTML textareas can't display carriage returns, editing must be turned off to preserve them.
Alternatively, you can enable editing but your carriage returns will not be preserved.

This preference will be saved, and can be toggled in the options.", - "Preserve Carriage Returns", - "Enable Editing", resolve, this); - }.bind(this)); - if (preserve === undefined) { - this.app.alert(`Not preserving carriage returns. ${optionsStr}`, 4000); - preserve = false; - } - this.manager.options.updateOption("preserveCR", preserve); - this.manager.options.updateOption("userSetCR", true); - } else { - if (this.app.options.preserveCR) { - this.app.alert(`A carriage return was detected in your input, so editing has been disabled to preserve it. ${optionsStr}`, 6000); - } else { - this.app.alert(`A carriage return was detected in your input. Editing is remaining enabled, but any carriage returns will be removed. ${optionsStr}`, 6000); - } + if (input.indexOf("\r") < 0) return false; + + const optionsStr = "This behaviour can be changed in the Options pane"; + if (!this.app.options.userSetCR) { + // User has not set a CR preference yet + let preserve = await new Promise(function(resolve, reject) { + this.app.confirm( + "Carriage Return Detected", + "A carriage return (\\r, 0x0d) was detected in your input. As HTML textareas can't display carriage returns, editing must be turned off to preserve them.
Alternatively, you can enable editing but your carriage returns will not be preserved.

This preference will be saved but can be toggled in the options pane.", + "Preserve Carriage Returns", + "Enable Editing", resolve, this); + }.bind(this)); + if (preserve === undefined) { + // The confirm pane was closed without picking a specific choice + this.app.alert(`Not preserving carriage returns.\n${optionsStr}`, 5000); + preserve = false; } - return this.app.options.preserveCR; + this.manager.options.updateOption("preserveCR", preserve); + this.manager.options.updateOption("userSetCR", true); } else { - return false; + if (this.app.options.preserveCR) { + this.app.alert(`A carriage return (\\r, 0x0d) was detected in your input, so editing has been disabled to preserve it.
${optionsStr}`, 10000); + } else { + this.app.alert(`A carriage return (\\r, 0x0d) was detected in your input. Editing is remaining enabled, but carriage returns will not be preserved.
${optionsStr}`, 10000); + } } + + return this.app.options.preserveCR; } /** diff --git a/src/web/waiters/OutputWaiter.mjs b/src/web/waiters/OutputWaiter.mjs index af39b80c..6bbe8f4a 100755 --- a/src/web/waiters/OutputWaiter.mjs +++ b/src/web/waiters/OutputWaiter.mjs @@ -546,7 +546,7 @@ class OutputWaiter { "Cancel zipping", resolve, this); }.bind(this)); - if (!cancel && cancel !== undefined) { + if (!cancel) { this.terminateZipWorker(); } }