Skip to content

Commit 5cb5b5d

Browse files
authored
Merge branch 'master' into fix/improve-hint-display
2 parents 7211906 + 5d33531 commit 5cb5b5d

32 files changed

Lines changed: 2475 additions & 91 deletions

.github/workflows/releases.yml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,5 @@ jobs:
9292

9393
- name: Publish to NPM
9494
uses: JS-DevTools/npm-publish@v1
95-
if: false
9695
with:
97-
token: ${{ secrets.NPM_TOKEN }}
96+
token: ${{ secrets.NPM_TOKEN }}

Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,7 @@ RUN npm run build
2929
#########################################
3030
# We are using Github Actions: redhat-actions/buildah-build@v2 which needs manual selection of arch in base image
3131
# Remove TARGETARCH if docker buildx is supported in the CI release as --platform=$TARGETPLATFORM will be automatically set
32-
ARG TARGETARCH
3332
ARG TARGETPLATFORM
34-
FROM ${TARGETARCH}/nginx:stable-alpine AS cyberchef
33+
FROM --platform=${TARGETPLATFORM} nginx:stable-alpine AS cyberchef
3534

3635
COPY --from=builder /app/build/prod /usr/share/nginx/html/

package-lock.json

Lines changed: 15 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@
132132
"file-saver": "^2.0.5",
133133
"flat": "^6.0.1",
134134
"geodesy": "1.1.3",
135+
"hash-wasm": "^4.12.0",
135136
"highlight.js": "^11.9.0",
136137
"ieee754": "^1.2.1",
137138
"jimp": "^0.22.12",
@@ -140,6 +141,7 @@
140141
"js-sha3": "^0.9.3",
141142
"jsesc": "^3.0.2",
142143
"json5": "^2.2.3",
144+
"jsonata": "^2.0.3",
143145
"jsonpath-plus": "^9.0.0",
144146
"jsonwebtoken": "8.5.1",
145147
"jsqr": "^1.4.0",

src/core/config/Categories.json

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,7 @@
294294
"To Upper case",
295295
"To Lower case",
296296
"Swap case",
297+
"Alternating Caps",
297298
"To Case Insensitive Regex",
298299
"From Case Insensitive Regex",
299300
"Add line numbers",
@@ -369,6 +370,7 @@
369370
"Regular expression",
370371
"XPath expression",
371372
"JPath expression",
373+
"Jsonata Query",
372374
"CSS selector",
373375
"Extract EXIF",
374376
"Extract ID3",
@@ -404,6 +406,7 @@
404406
"name": "Hashing",
405407
"ops": [
406408
"Analyse hash",
409+
"Generate all checksums",
407410
"Generate all hashes",
408411
"MD2",
409412
"MD4",
@@ -422,6 +425,7 @@
422425
"Snefru",
423426
"BLAKE2b",
424427
"BLAKE2s",
428+
"BLAKE3",
425429
"GOST Hash",
426430
"Streebog",
427431
"SSDEEP",
@@ -446,7 +450,8 @@
446450
"Adler-32 Checksum",
447451
"Luhn Checksum",
448452
"CRC Checksum",
449-
"TCP/IP Checksum"
453+
"TCP/IP Checksum",
454+
"XOR Checksum"
450455
]
451456
},
452457
{
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/**
2+
* @author sw5678
3+
* @copyright Crown Copyright 2023
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
9+
/**
10+
* Alternating caps operation
11+
*/
12+
class AlternatingCaps extends Operation {
13+
14+
/**
15+
* AlternatingCaps constructor
16+
*/
17+
constructor() {
18+
super();
19+
20+
this.name = "Alternating Caps";
21+
this.module = "Default";
22+
this.description = "Alternating caps, also known as studly caps, sticky caps, or spongecase is a form of text notation in which the capitalization of letters varies by some pattern, or arbitrarily. An example of this would be spelling 'alternative caps' as 'aLtErNaTiNg CaPs'.";
23+
this.infoURL = "https://en.wikipedia.org/wiki/Alternating_caps";
24+
this.inputType = "string";
25+
this.outputType = "string";
26+
this.args= [];
27+
}
28+
29+
/**
30+
* @param {string} input
31+
* @param {Object[]} args
32+
* @returns {string}
33+
*/
34+
run(input, args) {
35+
let output = "";
36+
let previousCaps = true;
37+
for (let i = 0; i < input.length; i++) {
38+
// Check if the element is a letter
39+
if (!RegExp(/^\p{L}/, "u").test(input[i])) {
40+
output += input[i];
41+
} else if (previousCaps) {
42+
output += input[i].toLowerCase();
43+
previousCaps = false;
44+
} else {
45+
output += input[i].toUpperCase();
46+
previousCaps = true;
47+
}
48+
}
49+
return output;
50+
}
51+
}
52+
53+
export default AlternatingCaps;

src/core/operations/BLAKE3.mjs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* @author xumptex [xumptex@outlook.fr]
3+
* @copyright Crown Copyright 2025
4+
* @license Apache-2.0
5+
*/
6+
7+
import Operation from "../Operation.mjs";
8+
import OperationError from "../errors/OperationError.mjs";
9+
import { blake3 } from "hash-wasm";
10+
/**
11+
* BLAKE3 operation
12+
*/
13+
class BLAKE3 extends Operation {
14+
15+
/**
16+
* BLAKE3 constructor
17+
*/
18+
constructor() {
19+
super();
20+
21+
this.name = "BLAKE3";
22+
this.module = "Hashing";
23+
this.description = "Hashes the input using BLAKE3 (UTF-8 encoded), with an optional key (also UTF-8), and outputs the result in hexadecimal format.";
24+
this.infoURL = "https://en.wikipedia.org/wiki/BLAKE_(hash_function)#BLAKE3";
25+
this.inputType = "string";
26+
this.outputType = "string";
27+
this.args = [
28+
{
29+
"name": "Size (bytes)",
30+
"type": "number"
31+
}, {
32+
"name": "Key",
33+
"type": "string",
34+
"value": ""
35+
}
36+
];
37+
}
38+
39+
/**
40+
* @param {string} input
41+
* @param {Object[]} args
42+
* @returns {string}
43+
*/
44+
run(input, args) {
45+
const key = args[1];
46+
const size = args[0];
47+
// Check if the user want a key hash or not
48+
if (key === "") {
49+
return blake3(input, size*8);
50+
} if (key.length !== 32) {
51+
throw new OperationError("The key must be exactly 32 bytes long");
52+
}
53+
return blake3(input, size*8, key);
54+
}
55+
56+
}
57+
58+
export default BLAKE3;

src/core/operations/ECDSAVerify.mjs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import OperationError from "../errors/OperationError.mjs";
99
import { fromBase64 } from "../lib/Base64.mjs";
1010
import { toHexFast } from "../lib/Hex.mjs";
1111
import r from "jsrsasign";
12+
import Utils from "../Utils.mjs";
1213

1314
/**
1415
* ECDSA Verify operation
@@ -59,6 +60,11 @@ class ECDSAVerify extends Operation {
5960
name: "Message",
6061
type: "text",
6162
value: ""
63+
},
64+
{
65+
name: "Message format",
66+
type: "option",
67+
value: ["Raw", "Hex", "Base64"]
6268
}
6369
];
6470
}
@@ -70,7 +76,7 @@ class ECDSAVerify extends Operation {
7076
*/
7177
run(input, args) {
7278
let inputFormat = args[0];
73-
const [, mdAlgo, keyPem, msg] = args;
79+
const [, mdAlgo, keyPem, msg, msgFormat] = args;
7480

7581
if (keyPem.replace("-----BEGIN PUBLIC KEY-----", "").length === 0) {
7682
throw new OperationError("Please enter a public key.");
@@ -145,7 +151,8 @@ class ECDSAVerify extends Operation {
145151
throw new OperationError("Provided key is not a public key.");
146152
}
147153
sig.init(key);
148-
sig.updateString(msg);
154+
const messageStr = Utils.convertToByteString(msg, msgFormat);
155+
sig.updateString(messageStr);
149156
const result = sig.verify(signatureASN1Hex);
150157
return result ? "Verified OK" : "Verification Failure";
151158
}

src/core/operations/ExtractEmailAddresses.mjs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ class ExtractEmailAddresses extends Operation {
5151
run(input, args) {
5252
const [displayTotal, sort, unique] = args,
5353
// email regex from: https://www.regextester.com/98066
54-
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
54+
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\])/ig;
5555

5656
const results = search(
5757
input,

src/core/operations/ExtractIPAddresses.mjs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ class ExtractIPAddresses extends Operation {
2121

2222
this.name = "Extract IP addresses";
2323
this.module = "Regex";
24-
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>710.65.0.456</code>, this will match <code>10.65.0.45</code> so always check the original input!";
24+
this.description = "Extracts all IPv4 and IPv6 addresses.<br><br>Warning: Given a string <code>1.2.3.4.5.6.7.8</code>, this will match <code>1.2.3.4 and 5.6.7.8</code> so always check the original input!";
2525
this.inputType = "string";
2626
this.outputType = "string";
2727
this.args = [
@@ -65,7 +65,21 @@ class ExtractIPAddresses extends Operation {
6565
*/
6666
run(input, args) {
6767
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
68-
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
68+
69+
// IPv4 decimal groups can have values 0 to 255. To construct a regex the following sub-regex is reused:
70+
ipv4DecimalByte = "(?:25[0-5]|2[0-4]\\d|1?[0-9]\\d|\\d)",
71+
ipv4OctalByte = "(?:0[1-3]?[0-7]{1,2})",
72+
73+
// Look behind and ahead will be used to exclude matches with additional decimal digits left and right of IP address
74+
lookBehind = "(?<!\\d)",
75+
lookAhead = "(?!\\d)",
76+
77+
// Each variant requires exactly 4 groups with literal . between.
78+
ipv4Decimal = "(?:" + lookBehind + ipv4DecimalByte + "\\.){3}" + "(?:" + ipv4DecimalByte + lookAhead + ")",
79+
ipv4Octal = "(?:" + lookBehind + ipv4OctalByte + "\\.){3}" + "(?:" + ipv4OctalByte + lookAhead + ")",
80+
81+
// Then we allow IPv4 addresses to be expressed either entirely in decimal or entirely in Octal
82+
ipv4 = "(?:" + ipv4Decimal + "|" + ipv4Octal + ")",
6983
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})(([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}";
7084
let ips = "";
7185

0 commit comments

Comments
 (0)