From 3dddb516c9470d609d87318ffe0469c70802022c Mon Sep 17 00:00:00 2001 From: Adamkadaban Date: Sat, 27 Jul 2024 20:06:18 -0700 Subject: [PATCH 1/4] add offset field to 'Add Line Numbers' operation --- src/core/operations/AddLineNumbers.mjs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/core/operations/AddLineNumbers.mjs b/src/core/operations/AddLineNumbers.mjs index c1c6159a..7b05c848 100644 --- a/src/core/operations/AddLineNumbers.mjs +++ b/src/core/operations/AddLineNumbers.mjs @@ -22,7 +22,13 @@ class AddLineNumbers extends Operation { this.description = "Adds line numbers to the output."; this.inputType = "string"; this.outputType = "string"; - this.args = []; + this.args = [ + { + "name": "Offset", + "type": "number", + "value": 0 + } + ]; } /** @@ -33,10 +39,11 @@ class AddLineNumbers extends Operation { run(input, args) { const lines = input.split("\n"), width = lines.length.toString().length; + const offset = parseInt(args[0], 10); let output = ""; for (let n = 0; n < lines.length; n++) { - output += (n+1).toString().padStart(width, " ") + " " + lines[n] + "\n"; + output += (n+1+offset).toString().padStart(width, " ") + " " + lines[n] + "\n"; } return output.slice(0, output.length-1); } From 738e6feda06270c6ed19185e84c12726b29fd183 Mon Sep 17 00:00:00 2001 From: c65722 <53181351+c65722@users.noreply.github.com> Date: Sun, 15 Sep 2024 17:42:45 +0100 Subject: [PATCH 2/4] Add Strip IPv4 header operation --- src/core/config/Categories.json | 1 + src/core/operations/StripIPv4Header.mjs | 57 ++++++++++ tests/operations/index.mjs | 1 + tests/operations/tests/StripIPv4Header.mjs | 126 +++++++++++++++++++++ 4 files changed, 185 insertions(+) create mode 100644 src/core/operations/StripIPv4Header.mjs create mode 100644 tests/operations/tests/StripIPv4Header.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index bebdd6a5..77cc3ca0 100644 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -234,6 +234,7 @@ "Parse IP range", "Parse IPv6 address", "Parse IPv4 header", + "Strip IPv4 header", "Parse TCP", "Parse UDP", "Parse SSH Host Key", diff --git a/src/core/operations/StripIPv4Header.mjs b/src/core/operations/StripIPv4Header.mjs new file mode 100644 index 00000000..4b6ef1af --- /dev/null +++ b/src/core/operations/StripIPv4Header.mjs @@ -0,0 +1,57 @@ +/** + * @author c65722 [] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; +import Stream from "../lib/Stream.mjs"; + +/** + * Strip IPv4 header operation + */ +class StripIPv4Header extends Operation { + + /** + * StripIPv4Header constructor + */ + constructor() { + super(); + + this.name = "Strip IPv4 header"; + this.module = "Default"; + this.description = "Strips the IPv4 header from an IPv4 packet, outputting the payload."; + this.infoURL = "https://wikipedia.org/wiki/IPv4"; + this.inputType = "ArrayBuffer"; + this.outputType = "ArrayBuffer"; + this.args = []; + } + + /** + * @param {ArrayBuffer} input + * @param {Object[]} args + * @returns {ArrayBuffer} + */ + run(input, args) { + const MIN_HEADER_LEN = 20; + + const s = new Stream(new Uint8Array(input)); + if (s.length < MIN_HEADER_LEN) { + throw new OperationError("Input length is less than minimum IPv4 header length"); + } + + const ihl = s.readInt(1) & 0x0f; + const dataOffsetBytes = ihl * 4; + if (s.length < dataOffsetBytes) { + throw new OperationError("Input length is less than IHL"); + } + + s.moveTo(dataOffsetBytes); + + return s.getBytes().buffer; + } + +} + +export default StripIPv4Header; diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index 40ce7a2e..a1acb0c3 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -142,6 +142,7 @@ import "./tests/SIGABA.mjs"; import "./tests/SM4.mjs"; // import "./tests/SplitColourChannels.mjs"; // Cannot test operations that use the File type yet import "./tests/StrUtils.mjs"; +import "./tests/StripIPv4Header.mjs"; import "./tests/Subsection.mjs"; import "./tests/SwapCase.mjs"; import "./tests/SymmetricDifference.mjs"; diff --git a/tests/operations/tests/StripIPv4Header.mjs b/tests/operations/tests/StripIPv4Header.mjs new file mode 100644 index 00000000..739bc70d --- /dev/null +++ b/tests/operations/tests/StripIPv4Header.mjs @@ -0,0 +1,126 @@ +/** + * Strip IPv4 header tests. + * + * @author c65722 [] + * @copyright Crown Copyright 2024 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +TestRegister.addTests([ + { + name: "Strip IPv4 header: No options, No payload", + input: "450000140005400080060000c0a80001c0a80002", + expectedOutput: "", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip IPv4 header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip IPv4 header: No options, Payload", + input: "450000140005400080060000c0a80001c0a80002ffffffffffffffff", + expectedOutput: "ffffffffffffffff", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip IPv4 header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip IPv4 header: Options, No payload", + input: "460000140005400080060000c0a80001c0a8000207000000", + expectedOutput: "", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip IPv4 header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip IPv4 header: Options, Payload", + input: "460000140005400080060000c0a80001c0a8000207000000ffffffffffffffff", + expectedOutput: "ffffffffffffffff", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip IPv4 header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip IPv4 header: Input length lesss than minimum header length", + input: "450000140005400080060000c0a80001c0a800", + expectedOutput: "Input length is less than minimum IPv4 header length", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip IPv4 header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + }, + { + name: "Strip IPv4 header: Input length less than IHL", + input: "460000140005400080060000c0a80001c0a80000", + expectedOutput: "Input length is less than IHL", + recipeConfig: [ + { + op: "From Hex", + args: ["None"] + }, + { + op: "Strip IPv4 header", + args: [], + }, + { + op: "To Hex", + args: ["None", 0] + } + ] + } +]); From 6b75ba8903149a01575ccdbe3e9f0378e87e52d3 Mon Sep 17 00:00:00 2001 From: Adamkadaban Date: Mon, 13 Jan 2025 15:48:18 -0500 Subject: [PATCH 3/4] fix bug where no input leads to error in console --- src/core/operations/AddLineNumbers.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/AddLineNumbers.mjs b/src/core/operations/AddLineNumbers.mjs index 7b05c848..3eee6544 100644 --- a/src/core/operations/AddLineNumbers.mjs +++ b/src/core/operations/AddLineNumbers.mjs @@ -39,7 +39,7 @@ class AddLineNumbers extends Operation { run(input, args) { const lines = input.split("\n"), width = lines.length.toString().length; - const offset = parseInt(args[0], 10); + const offset = args[0] ? parseInt(args[0], 10) : 0; let output = ""; for (let n = 0; n < lines.length; n++) { From d3ee16f38b156ce9279b259dd6d88f3e3d03fb95 Mon Sep 17 00:00:00 2001 From: a3957273 <89583054+a3957273@users.noreply.github.com> Date: Tue, 11 Feb 2025 00:49:14 +0000 Subject: [PATCH 4/4] Disable flakey URL test --- tests/browser/01_io.js | 56 +++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/tests/browser/01_io.js b/tests/browser/01_io.js index f8f7f9e1..cbfec083 100644 --- a/tests/browser/01_io.js +++ b/tests/browser/01_io.js @@ -675,42 +675,42 @@ module.exports = { } }, - "Loading from URL": browser => { - utils.clear(browser); + // "Loading from URL": browser => { + // utils.clear(browser); - /* Side panel displays correct info */ - utils.uploadFile(browser, "files/TowelDay.jpeg"); + // /* Side panel displays correct info */ + // utils.uploadFile(browser, "files/TowelDay.jpeg"); - browser - .waitForElementVisible("#input-text .cm-file-details") - .waitForElementVisible("#input-text .cm-file-details .file-details-toggle-shown") - .waitForElementVisible("#input-text .cm-file-details .file-details-thumbnail") - .waitForElementVisible("#input-text .cm-file-details .file-details-name") - .waitForElementVisible("#input-text .cm-file-details .file-details-size") - .waitForElementVisible("#input-text .cm-file-details .file-details-type") - .waitForElementVisible("#input-text .cm-file-details .file-details-loaded"); + // browser + // .waitForElementVisible("#input-text .cm-file-details") + // .waitForElementVisible("#input-text .cm-file-details .file-details-toggle-shown") + // .waitForElementVisible("#input-text .cm-file-details .file-details-thumbnail") + // .waitForElementVisible("#input-text .cm-file-details .file-details-name") + // .waitForElementVisible("#input-text .cm-file-details .file-details-size") + // .waitForElementVisible("#input-text .cm-file-details .file-details-type") + // .waitForElementVisible("#input-text .cm-file-details .file-details-loaded"); - /* Complex deep link populates the input correctly (encoding, eol, input) */ - browser - .urlHash("recipe=To_Base64('A-Za-z0-9%2B/%3D')&input=VGhlIHNoaXBzIGh1bmcgaW4gdGhlIHNreSBpbiBtdWNoIHRoZSBzYW1lIHdheSB0aGF0IGJyaWNrcyBkb24ndC4M&ienc=21866&oenc=1201&ieol=FF&oeol=PS") - .waitForElementVisible("#rec-list li.operation"); + // /* Complex deep link populates the input correctly (encoding, eol, input) */ + // browser + // .urlHash("recipe=To_Base64('A-Za-z0-9%2B/%3D')&input=VGhlIHNoaXBzIGh1bmcgaW4gdGhlIHNreSBpbiBtdWNoIHRoZSBzYW1lIHdheSB0aGF0IGJyaWNrcyBkb24ndC4M&ienc=21866&oenc=1201&ieol=FF&oeol=PS") + // .waitForElementVisible("#rec-list li.operation"); - browser.expect.element(`#input-text .cm-content`).to.have.property("textContent").match(/^.{65}$/); - browser.expect.element("#input-text .cm-status-bar .stats-length-value").text.to.equal("66"); - browser.expect.element("#input-text .cm-status-bar .stats-lines-value").text.to.equal("2"); + // browser.expect.element(`#input-text .cm-content`).to.have.property("textContent").match(/^.{65}$/); + // browser.expect.element("#input-text .cm-status-bar .stats-length-value").text.to.equal("66"); + // browser.expect.element("#input-text .cm-status-bar .stats-lines-value").text.to.equal("2"); - browser.expect.element("#input-text .chr-enc-value").text.that.equals("KOI8-U Ukrainian Cyrillic"); - browser.expect.element("#output-text .chr-enc-value").text.that.equals("UTF-16BE"); + // browser.expect.element("#input-text .chr-enc-value").text.that.equals("KOI8-U Ukrainian Cyrillic"); + // browser.expect.element("#output-text .chr-enc-value").text.that.equals("UTF-16BE"); - browser.expect.element("#input-text .eol-value").text.that.equals("FF"); - browser.expect.element("#output-text .eol-value").text.that.equals("PS"); + // browser.expect.element("#input-text .eol-value").text.that.equals("FF"); + // browser.expect.element("#output-text .eol-value").text.that.equals("PS"); - utils.bake(browser); + // utils.bake(browser); - browser.expect.element(`#output-text .cm-content`).to.have.property("textContent").match(/^.{44}$/); - browser.expect.element("#output-text .cm-status-bar .stats-length-value").text.to.equal("44"); - browser.expect.element("#output-text .cm-status-bar .stats-lines-value").text.to.equal("1"); - }, + // browser.expect.element(`#output-text .cm-content`).to.have.property("textContent").match(/^.{44}$/); + // browser.expect.element("#output-text .cm-status-bar .stats-length-value").text.to.equal("44"); + // browser.expect.element("#output-text .cm-status-bar .stats-lines-value").text.to.equal("1"); + // }, "Replace input with output": browser => { /* Input is correctly populated */