From ce6d38860dcc1b76fc85ecbecde04dbceeb57416 Mon Sep 17 00:00:00 2001 From: Oshawk Date: Mon, 21 Oct 2019 19:39:01 +0100 Subject: [PATCH 1/5] Add operation Added 'Take nth bytes' operation. --- src/core/config/Categories.json | 3 +- src/core/operations/TakeNthBytes.mjs | 78 ++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 src/core/operations/TakeNthBytes.mjs diff --git a/src/core/config/Categories.json b/src/core/config/Categories.json index db2ab3a632..9fb63d360e 100755 --- a/src/core/config/Categories.json +++ b/src/core/config/Categories.json @@ -238,7 +238,8 @@ "Escape string", "Unescape string", "Pseudo-Random Number Generator", - "Sleep" + "Sleep", + "Take nth bytes" ] }, { diff --git a/src/core/operations/TakeNthBytes.mjs b/src/core/operations/TakeNthBytes.mjs new file mode 100644 index 0000000000..7dcf9c6ee3 --- /dev/null +++ b/src/core/operations/TakeNthBytes.mjs @@ -0,0 +1,78 @@ +/** + * @author Oshawk [oshawk@protonmail.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; + +/** + * Take nth bytes operation + */ +class TakeNthBytes extends Operation { + + /** + * TakeNthBytes constructor + */ + constructor() { + super(); + + this.name = "Take nth bytes"; + this.module = "Default"; + this.description = "Takes every nth byte starting with a given byte."; + this.infoURL = ""; + this.inputType = "byteArray"; + this.outputType = "byteArray"; + this.args = [ + { + name: "Take every", + type: "number", + value: 4 + }, + { + name: "Starting at", + type: "number", + value: 0 + }, + { + name: "Apply to each line", + type: "boolean", + value: false + } + ]; + } + + /** + * @param {byteArray} input + * @param {Object[]} args + * @returns {byteArray} + */ + run(input, args) { + let n = args[0]; + let start = args[1]; + let eachLine = args[2]; + + if (parseInt(n) !== n || n <= 0) { + throw new OperationError("'Take every' must be a positive integer.") + } + if (parseInt(start) !== start || start < 0) { + throw new OperationError("'Starting at' must be a positive or zero integer.") + } + + let offset = 0; + let output = []; + for (let i = 0; i < input.length; i++) { + if (eachLine && input[i] == 0x0a) { + offset = i + 1; + } else if (i - offset >= start && (i - (start + offset)) % n == 0) { + output.push(input[i]); + } + } + + return output; + } + +} + +export default TakeNthBytes; From 7c7d1823ca4e31139a804c3ca067806c200c530c Mon Sep 17 00:00:00 2001 From: Oshawk Date: Mon, 21 Oct 2019 19:53:57 +0100 Subject: [PATCH 2/5] Fix formatting issue Fixed issue where new lines were truncated. --- src/core/operations/TakeNthBytes.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/operations/TakeNthBytes.mjs b/src/core/operations/TakeNthBytes.mjs index 7dcf9c6ee3..ffc42ff9e8 100644 --- a/src/core/operations/TakeNthBytes.mjs +++ b/src/core/operations/TakeNthBytes.mjs @@ -64,6 +64,7 @@ class TakeNthBytes extends Operation { let output = []; for (let i = 0; i < input.length; i++) { if (eachLine && input[i] == 0x0a) { + output.push(0x0a); offset = i + 1; } else if (i - offset >= start && (i - (start + offset)) % n == 0) { output.push(input[i]); From 502f126986cc10c2eb4df2aca46bcbe98cadeb3a Mon Sep 17 00:00:00 2001 From: Oshawk Date: Mon, 21 Oct 2019 20:15:45 +0100 Subject: [PATCH 3/5] Fix linting Fixed linting. --- src/core/operations/TakeNthBytes.mjs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/core/operations/TakeNthBytes.mjs b/src/core/operations/TakeNthBytes.mjs index ffc42ff9e8..05de88697a 100644 --- a/src/core/operations/TakeNthBytes.mjs +++ b/src/core/operations/TakeNthBytes.mjs @@ -49,24 +49,24 @@ class TakeNthBytes extends Operation { * @returns {byteArray} */ run(input, args) { - let n = args[0]; - let start = args[1]; - let eachLine = args[2]; + const n = args[0]; + const start = args[1]; + const eachLine = args[2]; - if (parseInt(n) !== n || n <= 0) { - throw new OperationError("'Take every' must be a positive integer.") + if (parseInt(n, 10) !== n || n <= 0) { + throw new OperationError("'Take every' must be a positive integer."); } - if (parseInt(start) !== start || start < 0) { - throw new OperationError("'Starting at' must be a positive or zero integer.") + if (parseInt(start, 10) !== start || start < 0) { + throw new OperationError("'Starting at' must be a positive or zero integer."); } - + let offset = 0; - let output = []; + const output = []; for (let i = 0; i < input.length; i++) { - if (eachLine && input[i] == 0x0a) { + if (eachLine && input[i] === 0x0a) { output.push(0x0a); offset = i + 1; - } else if (i - offset >= start && (i - (start + offset)) % n == 0) { + } else if (i - offset >= start && (i - (start + offset)) % n === 0) { output.push(input[i]); } } From 02f65379736b3a9739342f335fa84476600ea39e Mon Sep 17 00:00:00 2001 From: Oshawk Date: Mon, 21 Oct 2019 20:16:14 +0100 Subject: [PATCH 4/5] Add tests Added tests for the 'Take nth byte' operation. --- tests/operations/tests/TakeNthBytes.mjs | 123 ++++++++++++++++++++++++ 1 file changed, 123 insertions(+) create mode 100644 tests/operations/tests/TakeNthBytes.mjs diff --git a/tests/operations/tests/TakeNthBytes.mjs b/tests/operations/tests/TakeNthBytes.mjs new file mode 100644 index 0000000000..22181c3d28 --- /dev/null +++ b/tests/operations/tests/TakeNthBytes.mjs @@ -0,0 +1,123 @@ +/** + * @author Oshawk [oshawk@protonmail.com] + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ + +import TestRegister from "../../lib/TestRegister.mjs"; + +/** + * Take nth bytes tests + */ +TestRegister.addTests([ + { + name: "Take nth bytes: Nothing", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 0, false], + }, + ], + }, + { + name: "Take nth bytes: Nothing (apply to each line)", + input: "", + expectedOutput: "", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 0, true], + }, + ], + }, + { + name: "Take nth bytes: Basic single line", + input: "0123456789", + expectedOutput: "048", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 0, false], + }, + ], + }, + { + name: "Take nth bytes: Basic single line (apply to each line)", + input: "0123456789", + expectedOutput: "048", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 0, true], + }, + ], + }, + { + name: "Take nth bytes: Complex single line", + input: "0123456789", + expectedOutput: "59", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 5, false], + }, + ], + }, + { + name: "Take nth bytes: Complex single line (apply to each line)", + input: "0123456789", + expectedOutput: "59", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 5, true], + }, + ], + }, + { + name: "Take nth bytes: Basic multi line", + input: "01234\n56789", + expectedOutput: "047", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 0, false], + }, + ], + }, + { + name: "Take nth bytes: Basic multi line (apply to each line)", + input: "01234\n56789", + expectedOutput: "04\n59", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 0, true], + }, + ], + }, + { + name: "Take nth bytes: Complex multi line", + input: "01234\n56789", + expectedOutput: "\n8", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 5, false], + }, + ], + }, + { + name: "Take nth bytes: Complex multi line (apply to each line)", + input: "012345\n6789ab", + expectedOutput: "5\nb", + recipeConfig: [ + { + op: "Take nth bytes", + args: [4, 5, true], + }, + ], + } +]); From 518b33643198ed6ee474b9296fa6f7ffdd6f9dfb Mon Sep 17 00:00:00 2001 From: Oshawk Date: Mon, 21 Oct 2019 21:01:33 +0100 Subject: [PATCH 5/5] Add tests to index Added tests to index. --- tests/operations/index.mjs | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index d64a773770..348e84605f 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -91,6 +91,7 @@ import "./tests/Protobuf.mjs"; import "./tests/ParseSSHHostKey.mjs"; import "./tests/DefangIP.mjs"; import "./tests/ParseUDP.mjs"; +import "./tests/TakeNthBytes.mjs"; // Cannot test operations that use the File type yet // import "./tests/SplitColourChannels.mjs";