From 01edeb28a669397b52126f40bb31e56f92a46c1d Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Mon, 21 Apr 2025 14:57:45 -0400 Subject: [PATCH 01/18] Wrapped XOR run function in try catch block to handle key errors --- src/core/operations/XOR.mjs | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index aa2288420c..0b86723689 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -5,6 +5,7 @@ */ import Operation from "../Operation.mjs"; +import OperationError from "../errors/OperationError.mjs"; import Utils from "../Utils.mjs"; import { bitOp, xor, BITWISE_OP_DELIMS } from "../lib/BitwiseOp.mjs"; @@ -51,11 +52,15 @@ class XOR extends Operation { * @returns {byteArray} */ run(input, args) { - input = new Uint8Array(input); - const key = Utils.convertToByteArray(args[0].string || "", args[0].option), - [, scheme, nullPreserving] = args; + try { + input = new Uint8Array(input); + const key = Utils.convertToByteArray(args[0].string || "", args[0].option), + [, scheme, nullPreserving] = args; - return bitOp(input, key, xor, nullPreserving, scheme); + return bitOp(input, key, xor, nullPreserving, scheme); + } catch (error) { + throw new OperationError("Invalid Characters in key"); + } } /** From d3f943bee4329786efac09def0fcfed72d3156b8 Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Mon, 21 Apr 2025 14:58:37 -0400 Subject: [PATCH 02/18] Removed input extraction from try catch block to seperate input errors from key errors --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index 0b86723689..87e4ebb324 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -52,8 +52,8 @@ class XOR extends Operation { * @returns {byteArray} */ run(input, args) { + input = new Uint8Array(input); try { - input = new Uint8Array(input); const key = Utils.convertToByteArray(args[0].string || "", args[0].option), [, scheme, nullPreserving] = args; From 1a6d238537ca872450aa6132889447c469c82ba0 Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Mon, 21 Apr 2025 15:05:49 -0400 Subject: [PATCH 03/18] For the sake of backwards compatibility, a boolean is passed to tell the key extraction function that an error should be thrown on invalid input. --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index 87e4ebb324..09a1e840ce 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -54,7 +54,7 @@ class XOR extends Operation { run(input, args) { input = new Uint8Array(input); try { - const key = Utils.convertToByteArray(args[0].string || "", args[0].option), + const key = Utils.convertToByteArray(args[0].string || "", args[0].option, true), [, scheme, nullPreserving] = args; return bitOp(input, key, xor, nullPreserving, scheme); From e231d1b37aca88107c0fa312b278146ec0ab428e Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Mon, 21 Apr 2025 17:33:24 -0400 Subject: [PATCH 04/18] Changed delimitor to None so non-hex characters can be detected. --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index 09a1e840ce..c6e02e1d81 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -54,7 +54,7 @@ class XOR extends Operation { run(input, args) { input = new Uint8Array(input); try { - const key = Utils.convertToByteArray(args[0].string || "", args[0].option, true), + const key = Utils.convertToByteArray(args[0].string || "", args[0].option, "None", true), [, scheme, nullPreserving] = args; return bitOp(input, key, xor, nullPreserving, scheme); From 23bfe8740f4d1be91f3444b58f1ca33acaf79652 Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Tue, 22 Apr 2025 15:31:12 -0400 Subject: [PATCH 05/18] Made warning optional since test cases involved non-hex characters --- src/core/operations/XOR.mjs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index c6e02e1d81..65ed635b03 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -42,6 +42,11 @@ class XOR extends Operation { "name": "Null preserving", "type": "boolean", "value": false + }, + { + "name": "Filter Key", + "type": "boolean", + "value": true } ]; } @@ -54,7 +59,7 @@ class XOR extends Operation { run(input, args) { input = new Uint8Array(input); try { - const key = Utils.convertToByteArray(args[0].string || "", args[0].option, "None", true), + const key = Utils.convertToByteArray(args[0].string || "", args[0].option, args[3] ? "Auto" : "None", true), [, scheme, nullPreserving] = args; return bitOp(input, key, xor, nullPreserving, scheme); @@ -91,4 +96,4 @@ class XOR extends Operation { } -export default XOR; +export default XOR; \ No newline at end of file From 0a4fd205181be4e5396e7a4cddafa124e40cc127 Mon Sep 17 00:00:00 2001 From: Katie Makarska Date: Wed, 23 Apr 2025 21:05:41 -0400 Subject: [PATCH 06/18] added delim parameter to utils.mjs --- src/core/Utils.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index a9c381d766..f00c5b3be4 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -339,12 +339,12 @@ class Utils { * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64"); */ - static convertToByteArray(str, type) { + static convertToByteArray(str, type, delim = "Auto") { switch (type.toLowerCase()) { case "binary": return fromBinary(str); case "hex": - return fromHex(str); + return fromHex(str, delim); case "decimal": return fromDecimal(str); case "base64": From 6c046f4fe857d23ac96c2667f2fffe26fa0e51b8 Mon Sep 17 00:00:00 2001 From: Katie Makarska Date: Wed, 23 Apr 2025 21:07:58 -0400 Subject: [PATCH 07/18] added throw error parameter to convertToByteArray in Utils.mjs --- src/core/Utils.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index f00c5b3be4..b6df1a5b51 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -339,12 +339,12 @@ class Utils { * // returns [208, 159, 209, 128, 208, 184, 208, 178, 208, 181, 209, 130] * Utils.convertToByteArray("0JfQtNGA0LDQstGB0YLQstGD0LnRgtC1", "base64"); */ - static convertToByteArray(str, type, delim = "Auto") { + static convertToByteArray(str, type, delim = "Auto", throwError = false) { switch (type.toLowerCase()) { case "binary": return fromBinary(str); case "hex": - return fromHex(str, delim); + return fromHex(str, delim, 2, throwError); case "decimal": return fromDecimal(str); case "base64": From 49a80b471593a0ad2aa0dd016edf0faed43af298 Mon Sep 17 00:00:00 2001 From: Katie Makarska Date: Thu, 24 Apr 2025 12:53:35 -0400 Subject: [PATCH 08/18] added new params in the header comment of convertToByteArray --- src/core/Utils.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/Utils.mjs b/src/core/Utils.mjs index b6df1a5b51..dabec6e80f 100755 --- a/src/core/Utils.mjs +++ b/src/core/Utils.mjs @@ -327,6 +327,8 @@ class Utils { * * @param {string} str * @param {string} type - One of "Binary", "Hex", "Decimal", "Base64", "UTF8" or "Latin1" + * @param {string} [delim="Auto"] - (Hex only) Delimiter used to split the input string. Set to "Auto" by default. + * @param {boolean} [throwError=false] - (Hex only) Whether to throw an error on invalid input. Defaults to false. * @returns {byteArray} * * @example From 278c221f1f5eb0cc0d126f43c2406d024817f4e1 Mon Sep 17 00:00:00 2001 From: rmurugan58 Date: Fri, 25 Apr 2025 22:11:20 -0400 Subject: [PATCH 09/18] extracted substr and added check for throwError in Hex.mjs --- src/core/lib/Hex.mjs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/core/lib/Hex.mjs b/src/core/lib/Hex.mjs index 78e1ad58ca..919d945b9f 100644 --- a/src/core/lib/Hex.mjs +++ b/src/core/lib/Hex.mjs @@ -100,7 +100,7 @@ export function toHexFast(data) { * // returns [10,20,30] * fromHex("0a:14:1e", "Colon"); */ -export function fromHex(data, delim="Auto", byteLen=2) { +export function fromHex(data, delim="Auto", byteLen=2, throwError=false) { //added throwError parameter if (byteLen < 1 || Math.round(byteLen) !== byteLen) throw new OperationError("Byte length must be a positive integer"); @@ -114,7 +114,11 @@ export function fromHex(data, delim="Auto", byteLen=2) { const output = []; for (let i = 0; i < data.length; i++) { for (let j = 0; j < data[i].length; j += byteLen) { - output.push(parseInt(data[i].substr(j, byteLen), 16)); + const chunk = data[i].substr(j, byteLen); //extracted substr into a chunk variable + if (throwError && /[^a-f\d]/i.test(chunk)) { //added validation check for when throwError is true + throw new OperationError(`Invalid hex character in chunk "${chunk}"`); //throw on invalid hex chunk + } + output.push(parseInt(chunk, 16)); //parseInt now uses chunk } } return output; From 78b4a1f447660ad1bf6a6bcd523de981816ad1a5 Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Sun, 27 Apr 2025 12:21:41 -0400 Subject: [PATCH 10/18] Fixed lint errors in src/core/operations/XOR.mjs --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index 65ed635b03..511a76804a 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -96,4 +96,4 @@ class XOR extends Operation { } -export default XOR; \ No newline at end of file +export default XOR; From 34fe96deaeb988b4926de4711895895a1734695c Mon Sep 17 00:00:00 2001 From: rmurugan58 Date: Sun, 27 Apr 2025 12:24:17 -0400 Subject: [PATCH 11/18] added new param descriptor and fixed lint errors in Hex.mjs --- src/core/lib/Hex.mjs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/core/lib/Hex.mjs b/src/core/lib/Hex.mjs index 919d945b9f..71ce7a131a 100644 --- a/src/core/lib/Hex.mjs +++ b/src/core/lib/Hex.mjs @@ -91,6 +91,7 @@ export function toHexFast(data) { * @param {string} data * @param {string} [delim] * @param {number} [byteLen=2] + * @param {boolean} [throwError=false] * @returns {byteArray} * * @example @@ -100,7 +101,7 @@ export function toHexFast(data) { * // returns [10,20,30] * fromHex("0a:14:1e", "Colon"); */ -export function fromHex(data, delim="Auto", byteLen=2, throwError=false) { //added throwError parameter +export function fromHex(data, delim="Auto", byteLen=2, throwError=false) { if (byteLen < 1 || Math.round(byteLen) !== byteLen) throw new OperationError("Byte length must be a positive integer"); @@ -114,11 +115,11 @@ export function fromHex(data, delim="Auto", byteLen=2, throwError=false) { //add const output = []; for (let i = 0; i < data.length; i++) { for (let j = 0; j < data[i].length; j += byteLen) { - const chunk = data[i].substr(j, byteLen); //extracted substr into a chunk variable - if (throwError && /[^a-f\d]/i.test(chunk)) { //added validation check for when throwError is true - throw new OperationError(`Invalid hex character in chunk "${chunk}"`); //throw on invalid hex chunk + const chunk = data[i].substr(j, byteLen); + if (throwError && /[^a-f\d]/i.test(chunk)) { + throw new OperationError(`Invalid hex character in chunk "${chunk}"`); } - output.push(parseInt(chunk, 16)); //parseInt now uses chunk + output.push(parseInt(chunk, 16)); } } return output; From 2e710c75e725fcc4fd599b3989254fd142c38c75 Mon Sep 17 00:00:00 2001 From: rmurugan58 Date: Sun, 27 Apr 2025 12:27:16 -0400 Subject: [PATCH 12/18] fixed lint errors in XOR.mjs --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index 65ed635b03..511a76804a 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -96,4 +96,4 @@ class XOR extends Operation { } -export default XOR; \ No newline at end of file +export default XOR; From 8589e06e7814223541dae6dd3e040317285c15a9 Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 30 Apr 2025 13:07:29 -0400 Subject: [PATCH 13/18] created a test for the new error that should be thrown if an invalid character is in the key for XOR with a Hex option --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index 511a76804a..c093b4333f 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -46,7 +46,7 @@ class XOR extends Operation { { "name": "Filter Key", "type": "boolean", - "value": true + "value": false } ]; } From 605e7b11f5fb1dee818bd03f927d531e27d6b8af Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Wed, 30 Apr 2025 21:57:23 -0400 Subject: [PATCH 14/18] Fixed error where xor filter key value was default false instead of true --- src/core/operations/XOR.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index c093b4333f..511a76804a 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -46,7 +46,7 @@ class XOR extends Operation { { "name": "Filter Key", "type": "boolean", - "value": false + "value": true } ]; } From b82426852562551f63ed375cdfb70935c471883e Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 30 Apr 2025 22:00:24 -0400 Subject: [PATCH 15/18] fix: revert previous commit wrong file staged, added file with new test for error feature --- src/core/operations/XOR.mjs | 2 +- tests/node/tests/operations.mjs | 13 +++++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/core/operations/XOR.mjs b/src/core/operations/XOR.mjs index c093b4333f..511a76804a 100644 --- a/src/core/operations/XOR.mjs +++ b/src/core/operations/XOR.mjs @@ -46,7 +46,7 @@ class XOR extends Operation { { "name": "Filter Key", "type": "boolean", - "value": false + "value": true } ]; } diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 4c5d4adab5..ea902ace44 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -974,6 +974,19 @@ smothering ampersand abreast`; "QV\u0010\u0004UDWQ"); }), + it("XOR: should throw 'Invalid Characters in key' error when key contains invalid characters", () => { + const invalidKeys = [ + { string: "zz 00 11", option: "Hex" }, + + { string: "4~ 00 11", option: "Hex" } + ]; + invalidKeys.forEach(invalidKey => { + assert.throws(() => { + chef.XOR("fe023da5", { key: invalidKey }); + }, /Invalid Characters in key/); + }); + }), + it("XPath expression", () => { assert.strictEqual( chef.XPathExpression("abc", {xPath: "contact-info/company"}).toString(), From 765d5ee97b60d2985edbd4d135184f8f9c0e415b Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 30 Apr 2025 22:11:55 -0400 Subject: [PATCH 16/18] changed filterKey to false for testing XOR invalid characters error --- tests/node/tests/operations.mjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index ea902ace44..7e1b891384 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -982,7 +982,7 @@ smothering ampersand abreast`; ]; invalidKeys.forEach(invalidKey => { assert.throws(() => { - chef.XOR("fe023da5", { key: invalidKey }); + chef.XOR("fe023da5", { key: invalidKey, filterKey: false }); }, /Invalid Characters in key/); }); }), From 70be54e262a91ac8d520996e1f32763c0de64c62 Mon Sep 17 00:00:00 2001 From: Jonas Date: Wed, 30 Apr 2025 22:33:33 -0400 Subject: [PATCH 17/18] added test to check that the error isn't raised on valid keys with filter set to false --- tests/node/tests/operations.mjs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index 7e1b891384..e46d426f44 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -987,6 +987,14 @@ smothering ampersand abreast`; }); }), + it("XOR: should not throw 'Invalid Characters in key' error when key contains only valid characters", () => { + assert.strictEqual(chef.XOR("fe023da5", { + key: "73 6f 6d 65", + filterKey: false + }).toString(), + "\u0015\n]W@\u000b\fP"); + }), + it("XPath expression", () => { assert.strictEqual( chef.XPathExpression("abc", {xPath: "contact-info/company"}).toString(), From 9a193affbfc85eb5f7ac4666643817beb725f9d8 Mon Sep 17 00:00:00 2001 From: Ryan Chernoff Date: Thu, 1 May 2025 15:08:14 -0400 Subject: [PATCH 18/18] Fixed error where test for XOR operation with valid key had an invalid key --- tests/node/tests/operations.mjs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/node/tests/operations.mjs b/tests/node/tests/operations.mjs index e46d426f44..1bf4b92bb2 100644 --- a/tests/node/tests/operations.mjs +++ b/tests/node/tests/operations.mjs @@ -979,7 +979,7 @@ smothering ampersand abreast`; { string: "zz 00 11", option: "Hex" }, { string: "4~ 00 11", option: "Hex" } - ]; + ]; invalidKeys.forEach(invalidKey => { assert.throws(() => { chef.XOR("fe023da5", { key: invalidKey, filterKey: false }); @@ -989,7 +989,7 @@ smothering ampersand abreast`; it("XOR: should not throw 'Invalid Characters in key' error when key contains only valid characters", () => { assert.strictEqual(chef.XOR("fe023da5", { - key: "73 6f 6d 65", + key: "736f6d65", filterKey: false }).toString(), "\u0015\n]W@\u000b\fP");