cyberchef 10.24.0 → 11.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.devcontainer/devcontainer.json +1 -1
- package/.nvmrc +1 -1
- package/CHANGELOG.md +28 -0
- package/Dockerfile +2 -2
- package/Gruntfile.js +1 -1
- package/README.md +3 -3
- package/babel.config.js +4 -1
- package/package.json +18 -14
- package/src/core/ChefWorker.js +1 -1
- package/src/core/Recipe.mjs +1 -1
- package/src/core/lib/Magic.mjs +1 -1
- package/src/core/operations/FromPunycode.mjs +1 -1
- package/src/core/operations/ShowBase64Offsets.mjs +28 -28
- package/src/core/operations/ToPunycode.mjs +1 -1
- package/src/node/NodeRecipe.mjs +8 -7
- package/src/node/api.mjs +4 -4
- package/src/web/index.js +2 -2
- package/src/web/static/sitemap.mjs +1 -1
- package/tests/lib/wasmFetchPolyfill.mjs +31 -0
- package/tests/node/consumers/cjs-consumer.js +2 -2
- package/tests/node/consumers/esm-consumer.mjs +2 -2
- package/tests/node/tests/Categories.mjs +2 -2
- package/tests/node/tests/nodeApi.mjs +55 -58
- package/tests/operations/index.mjs +1 -0
- package/tests/operations/tests/Base64.mjs +11 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
{
|
|
4
4
|
"name": "CyberChef",
|
|
5
5
|
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
|
|
6
|
-
"image": "mcr.microsoft.com/devcontainers/javascript-node:
|
|
6
|
+
"image": "mcr.microsoft.com/devcontainers/javascript-node:24-trixie",
|
|
7
7
|
|
|
8
8
|
// Features to add to the dev container. More info: https://containers.dev/features.
|
|
9
9
|
"features": {
|
package/.nvmrc
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
24
|
package/CHANGELOG.md
CHANGED
|
@@ -13,6 +13,22 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
13
13
|
|
|
14
14
|
## Details
|
|
15
15
|
|
|
16
|
+
## [11.0.0] - 2026-04-28
|
|
17
|
+
- Revert sitemap to v8.0.X to fix build/deploy on master [@GCHQDeveloper581] | [#2348]
|
|
18
|
+
- Node version update from 22 to 24 [@lzandman] [@GCHQDeveloper581] | [#2347]
|
|
19
|
+
- Fix XSS in Show Base64 offsets [@C85297] | [#2346]
|
|
20
|
+
- Make compatible with node >=22 [@GCHQDeveloper581] | [#2273]
|
|
21
|
+
- Fix(node): enable asynchronous operation support in Node.js API [@engin0223] [@GCHQDeveloper581] | [#2342]
|
|
22
|
+
- Feature: Change to nginx-unprivileged image for better kubernetes support [@hsolberg] | [#1922]
|
|
23
|
+
|
|
24
|
+
Breaking changes:
|
|
25
|
+
- Minimum supported node version - now v24 (was v16)
|
|
26
|
+
- Change of exported port on Docker Container - now 8080 (was 80)
|
|
27
|
+
- Node API now exports "bake" and "execute" functions as async.
|
|
28
|
+
|
|
29
|
+
<details>
|
|
30
|
+
<summary>Click to expand v10 minor versions</summary>
|
|
31
|
+
|
|
16
32
|
### [10.24.0] - 2026-04-27
|
|
17
33
|
- Update CONTRIBUTING.md [@GCHQDeveloper581] | [#2333]
|
|
18
34
|
- Fix, and link, Fernet tests [@GCHQDeveloper581] | [#2335]
|
|
@@ -277,6 +293,8 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
277
293
|
- Added 'Levenshtein Distance' operation [@mikecat] | [#1498]
|
|
278
294
|
- Added 'Swap case' operation [@mikecat] | [#1499]
|
|
279
295
|
|
|
296
|
+
</details>
|
|
297
|
+
|
|
280
298
|
## [10.0.0] - 2023-03-22
|
|
281
299
|
- [Full details explained here](https://github.com/gchq/CyberChef/wiki/Character-encoding,-EOL-separators,-and-editor-features)
|
|
282
300
|
- Status bars added to the Input and Output [@n1474335] | [#1405]
|
|
@@ -620,6 +638,7 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
620
638
|
## [4.0.0] - 2016-11-28
|
|
621
639
|
- Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
|
|
622
640
|
|
|
641
|
+
[11.0.0]: https://github.com/gchq/CyberChef/releases/tag/v11.0.0
|
|
623
642
|
[10.24.0]: https://github.com/gchq/CyberChef/releases/tag/v10.24.0
|
|
624
643
|
[10.23.0]: https://github.com/gchq/CyberChef/releases/tag/v10.23.0
|
|
625
644
|
[10.22.0]: https://github.com/gchq/CyberChef/releases/tag/v10.22.0
|
|
@@ -901,6 +920,9 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
901
920
|
[@BjoernAkAManf]: https://github.com/BjoernAkAManf
|
|
902
921
|
[@ko80240]: https://github.com/ko80240
|
|
903
922
|
[@BigYellowHammer]: https://github.com/BigYellowHammer
|
|
923
|
+
[@hsolberg]: https://github.com/hsolberg
|
|
924
|
+
[@lzandman]: https://github.com/lzandman
|
|
925
|
+
[@engin0223]: https://github.com/engin0223
|
|
904
926
|
|
|
905
927
|
|
|
906
928
|
[8ad18b]: https://github.com/gchq/CyberChef/commit/8ad18bc7db6d9ff184ba3518686293a7685bf7b7
|
|
@@ -1192,4 +1214,10 @@ All major and minor version changes will be documented in this file. Details of
|
|
|
1192
1214
|
[#2315]: https://github.com/gchq/CyberChef/pull/2315
|
|
1193
1215
|
[#2313]: https://github.com/gchq/CyberChef/pull/2313
|
|
1194
1216
|
[#2311]: https://github.com/gchq/CyberChef/pull/2311
|
|
1217
|
+
[#2348]: https://github.com/gchq/CyberChef/pull/2348
|
|
1218
|
+
[#2347]: https://github.com/gchq/CyberChef/pull/2347
|
|
1219
|
+
[#2346]: https://github.com/gchq/CyberChef/pull/2346
|
|
1220
|
+
[#2273]: https://github.com/gchq/CyberChef/pull/2273
|
|
1221
|
+
[#2342]: https://github.com/gchq/CyberChef/pull/2342
|
|
1222
|
+
[#1922]: https://github.com/gchq/CyberChef/pull/1922
|
|
1195
1223
|
|
package/Dockerfile
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
|
|
5
5
|
# This is because npm "chromedriver" package is not compatiable with all platforms
|
|
6
6
|
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
|
|
7
|
-
FROM --platform=$BUILDPLATFORM node:
|
|
7
|
+
FROM --platform=$BUILDPLATFORM node:24-alpine AS builder
|
|
8
8
|
|
|
9
9
|
WORKDIR /app
|
|
10
10
|
|
|
@@ -27,7 +27,7 @@ RUN npm run build
|
|
|
27
27
|
#########################################
|
|
28
28
|
# Package static build files into nginx #
|
|
29
29
|
#########################################
|
|
30
|
-
FROM nginx:stable-alpine AS cyberchef
|
|
30
|
+
FROM nginxinc/nginx-unprivileged:stable-alpine AS cyberchef
|
|
31
31
|
|
|
32
32
|
LABEL maintainer="GCHQ <oss@gchq.gov.uk>"
|
|
33
33
|
|
package/Gruntfile.js
CHANGED
|
@@ -6,7 +6,7 @@ const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPl
|
|
|
6
6
|
const glob = require("glob");
|
|
7
7
|
const path = require("path");
|
|
8
8
|
|
|
9
|
-
const nodeFlags = "--
|
|
9
|
+
const nodeFlags = "--no-warnings --no-deprecation";
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Grunt configuration for building the app in various formats.
|
package/README.md
CHANGED
|
@@ -36,7 +36,7 @@ docker build --tag cyberchef --ulimit nofile=10000 .
|
|
|
36
36
|
```
|
|
37
37
|
2. Run the docker container
|
|
38
38
|
```bash
|
|
39
|
-
docker run -it -p 8080:
|
|
39
|
+
docker run -it -p 8080:8080 cyberchef
|
|
40
40
|
```
|
|
41
41
|
3. Navigate to `http://localhost:8080` in your browser
|
|
42
42
|
|
|
@@ -45,7 +45,7 @@ docker run -it -p 8080:80 cyberchef
|
|
|
45
45
|
If you prefer to skip the build process, you can use the pre-built image
|
|
46
46
|
|
|
47
47
|
```bash
|
|
48
|
-
docker run -it -p 8080:
|
|
48
|
+
docker run -it -p 8080:8080 ghcr.io/gchq/cyberchef:latest
|
|
49
49
|
```
|
|
50
50
|
|
|
51
51
|
Just like before, navigate to `http://localhost:8080` in your browser.
|
|
@@ -120,7 +120,7 @@ CyberChef is built to support
|
|
|
120
120
|
|
|
121
121
|
## Node.js support
|
|
122
122
|
|
|
123
|
-
CyberChef is built to fully support Node.js `
|
|
123
|
+
CyberChef is built to fully support Node.js `v24`. For more information, see the ["Node API" wiki page](https://github.com/gchq/CyberChef/wiki/Node-API)
|
|
124
124
|
|
|
125
125
|
|
|
126
126
|
## Contributing
|
package/babel.config.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "11.0.0",
|
|
4
4
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
|
5
5
|
"author": "n1474335 <n1474335@gmail.com>",
|
|
6
6
|
"homepage": "https://gchq.github.io/CyberChef",
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"browserslist": [
|
|
37
37
|
"Chrome >= 50",
|
|
38
38
|
"Firefox >= 38",
|
|
39
|
-
"node >=
|
|
39
|
+
"node >= 24"
|
|
40
40
|
],
|
|
41
41
|
"devDependencies": {
|
|
42
42
|
"@babel/eslint-parser": "^7.28.6",
|
|
@@ -55,14 +55,14 @@
|
|
|
55
55
|
"chromedriver": "^146.0.6",
|
|
56
56
|
"cli-progress": "^3.12.0",
|
|
57
57
|
"colors": "^1.4.0",
|
|
58
|
-
"compression-webpack-plugin": "^
|
|
59
|
-
"copy-webpack-plugin": "^
|
|
58
|
+
"compression-webpack-plugin": "^12.0.0",
|
|
59
|
+
"copy-webpack-plugin": "^14.0.0",
|
|
60
60
|
"core-js": "^3.49.0",
|
|
61
|
-
"cspell": "^
|
|
62
|
-
"css-loader": "7.1.4",
|
|
61
|
+
"cspell": "^9.7.0",
|
|
62
|
+
"css-loader": "^7.1.4",
|
|
63
63
|
"eslint": "^9.39.4",
|
|
64
64
|
"eslint-plugin-jsdoc": "^50.8.0",
|
|
65
|
-
"globals": "^
|
|
65
|
+
"globals": "^17.4.0",
|
|
66
66
|
"grunt": "^1.6.2",
|
|
67
67
|
"grunt-chmod": "~1.1.1",
|
|
68
68
|
"grunt-concurrent": "^3.0.0",
|
|
@@ -87,8 +87,8 @@
|
|
|
87
87
|
"sitemap": "^8.0.3",
|
|
88
88
|
"terser": "^5.46.2",
|
|
89
89
|
"webpack": "^5.106.2",
|
|
90
|
-
"webpack-bundle-analyzer": "^
|
|
91
|
-
"webpack-dev-server": "5.0.4",
|
|
90
|
+
"webpack-bundle-analyzer": "^5.0.0",
|
|
91
|
+
"webpack-dev-server": "^5.0.4",
|
|
92
92
|
"webpack-node-externals": "^3.0.0",
|
|
93
93
|
"worker-loader": "^3.0.8"
|
|
94
94
|
},
|
|
@@ -164,11 +164,12 @@
|
|
|
164
164
|
"notepack.io": "^3.0.1",
|
|
165
165
|
"ntlm": "^0.1.3",
|
|
166
166
|
"nwmatcher": "^1.4.4",
|
|
167
|
-
"otpauth": "9.
|
|
167
|
+
"otpauth": "^9.5.0",
|
|
168
168
|
"path": "^0.12.7",
|
|
169
169
|
"popper.js": "^1.16.1",
|
|
170
170
|
"process": "^0.11.10",
|
|
171
171
|
"protobufjs": "^7.5.5",
|
|
172
|
+
"punycode.js": "^2.3.1",
|
|
172
173
|
"qr-image": "^3.2.0",
|
|
173
174
|
"reflect-metadata": "^0.2.2",
|
|
174
175
|
"rison": "^0.1.1",
|
|
@@ -194,18 +195,21 @@
|
|
|
194
195
|
"start": "npx grunt dev",
|
|
195
196
|
"build": "npx grunt prod",
|
|
196
197
|
"node": "npx grunt node",
|
|
197
|
-
"repl": "node --
|
|
198
|
-
"test": "npx grunt configTests && node --
|
|
198
|
+
"repl": "node --no-warnings src/node/repl.mjs",
|
|
199
|
+
"test": "npx grunt configTests && node --no-warnings --no-deprecation --openssl-legacy-provider tests/node/index.mjs && node --no-warnings --no-deprecation --openssl-legacy-provider --trace-uncaught tests/operations/index.mjs",
|
|
199
200
|
"testnodeconsumer": "npx grunt testnodeconsumer",
|
|
200
201
|
"testui": "npx grunt testui",
|
|
201
202
|
"testuidev": "npx nightwatch --env=dev",
|
|
202
203
|
"lint": "npx grunt lint",
|
|
203
204
|
"lint:grammar": "cspell ./src",
|
|
204
205
|
"postinstall": "npx grunt exec:fixCryptoApiImports && npx grunt exec:fixSnackbarMarkup",
|
|
205
|
-
"newop": "node
|
|
206
|
-
"minor": "node
|
|
206
|
+
"newop": "node src/core/config/scripts/newOperation.mjs",
|
|
207
|
+
"minor": "node src/core/config/scripts/newMinorVersion.mjs && npm version minor --git-tag-version=false && echo \"Updated to version v$(npm pkg get version | xargs), please create a pull request and once merged use 'npm run tag'\"",
|
|
207
208
|
"tag": "git tag -s \"v$(npm pkg get version | xargs)\" -m \"$(npm pkg get version | xargs)\" && echo \"Created v$(npm pkg get version | xargs), now check and push the tag\"",
|
|
208
209
|
"getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'",
|
|
209
210
|
"setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048"
|
|
211
|
+
},
|
|
212
|
+
"engines": {
|
|
213
|
+
"node": ">=24 <25"
|
|
210
214
|
}
|
|
211
215
|
}
|
package/src/core/ChefWorker.js
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import Chef from "./Chef.mjs";
|
|
10
|
-
import OperationConfig from "./config/OperationConfig.json"
|
|
10
|
+
import OperationConfig from "./config/OperationConfig.json" with { type: "json" };
|
|
11
11
|
import OpModules from "./config/modules/OpModules.mjs";
|
|
12
12
|
import loglevelMessagePrefix from "loglevel-message-prefix";
|
|
13
13
|
|
package/src/core/Recipe.mjs
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @license Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import OperationConfig from "./config/OperationConfig.json"
|
|
7
|
+
import OperationConfig from "./config/OperationConfig.json" with { type: "json" };
|
|
8
8
|
import OperationError from "./errors/OperationError.mjs";
|
|
9
9
|
import Operation from "./Operation.mjs";
|
|
10
10
|
import DishError from "./errors/DishError.mjs";
|
package/src/core/lib/Magic.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import OperationConfig from "../config/OperationConfig.json"
|
|
1
|
+
import OperationConfig from "../config/OperationConfig.json" with { type: "json" };
|
|
2
2
|
import Utils, { isWorkerEnvironment } from "../Utils.mjs";
|
|
3
3
|
import Recipe from "../Recipe.mjs";
|
|
4
4
|
import Dish from "../Dish.mjs";
|
|
@@ -77,84 +77,84 @@ class ShowBase64Offsets extends Operation {
|
|
|
77
77
|
staticSection = offset0.slice(0, -3);
|
|
78
78
|
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
79
79
|
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -2)) + "'>" +
|
|
80
|
-
staticSection + "</span>" +
|
|
81
|
-
"<span class='hl5'>" + offset0.substr(offset0.length - 3, 1) + "</span>" +
|
|
82
|
-
"<span class='hl3'>" + offset0.substr(offset0.length - 2) + "</span>";
|
|
80
|
+
Utils.escapeHtml(staticSection) + "</span>" +
|
|
81
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset0.substr(offset0.length - 3, 1)) + "</span>" +
|
|
82
|
+
"<span class='hl3'>" + Utils.escapeHtml(offset0.substr(offset0.length - 2)) + "</span>";
|
|
83
83
|
} else if (len0 % 4 === 3) {
|
|
84
84
|
staticSection = offset0.slice(0, -2);
|
|
85
85
|
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
86
86
|
Utils.escapeHtml(fromBase64(staticSection, alphabet).slice(0, -1)) + "'>" +
|
|
87
|
-
staticSection + "</span>" +
|
|
88
|
-
"<span class='hl5'>" + offset0.substr(offset0.length - 2, 1) + "</span>" +
|
|
89
|
-
"<span class='hl3'>" + offset0.substr(offset0.length - 1) + "</span>";
|
|
87
|
+
Utils.escapeHtml(staticSection) + "</span>" +
|
|
88
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset0.substr(offset0.length - 2, 1)) + "</span>" +
|
|
89
|
+
"<span class='hl3'>" + Utils.escapeHtml(offset0.substr(offset0.length - 1)) + "</span>";
|
|
90
90
|
} else {
|
|
91
91
|
staticSection = offset0;
|
|
92
92
|
offset0 = "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
93
93
|
Utils.escapeHtml(fromBase64(staticSection, alphabet)) + "'>" +
|
|
94
|
-
staticSection + "</span>";
|
|
94
|
+
Utils.escapeHtml(staticSection) + "</span>";
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (!showVariable) {
|
|
98
|
-
offset0 = staticSection;
|
|
98
|
+
offset0 = Utils.escapeHtml(staticSection);
|
|
99
99
|
}
|
|
100
100
|
|
|
101
101
|
|
|
102
102
|
// Highlight offset 1
|
|
103
|
-
padding = "<span class='hl3'>" + offset1.substr(0, 1) + "</span>" +
|
|
104
|
-
"<span class='hl5'>" + offset1.substr(1, 1) + "</span>";
|
|
103
|
+
padding = "<span class='hl3'>" + Utils.escapeHtml(offset1.substr(0, 1)) + "</span>" +
|
|
104
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset1.substr(1, 1)) + "</span>";
|
|
105
105
|
offset1 = offset1.substr(2);
|
|
106
106
|
if (len1 % 4 === 2) {
|
|
107
107
|
staticSection = offset1.slice(0, -3);
|
|
108
108
|
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
109
109
|
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -2)) + "'>" +
|
|
110
|
-
staticSection + "</span>" +
|
|
111
|
-
"<span class='hl5'>" + offset1.substr(offset1.length - 3, 1) + "</span>" +
|
|
112
|
-
"<span class='hl3'>" + offset1.substr(offset1.length - 2) + "</span>";
|
|
110
|
+
Utils.escapeHtml(staticSection) + "</span>" +
|
|
111
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset1.substr(offset1.length - 3, 1)) + "</span>" +
|
|
112
|
+
"<span class='hl3'>" + Utils.escapeHtml(offset1.substr(offset1.length - 2)) + "</span>";
|
|
113
113
|
} else if (len1 % 4 === 3) {
|
|
114
114
|
staticSection = offset1.slice(0, -2);
|
|
115
115
|
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
116
116
|
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1, -1)) + "'>" +
|
|
117
|
-
staticSection + "</span>" +
|
|
118
|
-
"<span class='hl5'>" + offset1.substr(offset1.length - 2, 1) + "</span>" +
|
|
119
|
-
"<span class='hl3'>" + offset1.substr(offset1.length - 1) + "</span>";
|
|
117
|
+
Utils.escapeHtml(staticSection) + "</span>" +
|
|
118
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset1.substr(offset1.length - 2, 1)) + "</span>" +
|
|
119
|
+
"<span class='hl3'>" + Utils.escapeHtml(offset1.substr(offset1.length - 1)) + "</span>";
|
|
120
120
|
} else {
|
|
121
121
|
staticSection = offset1;
|
|
122
122
|
offset1 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
123
123
|
Utils.escapeHtml(fromBase64("AA" + staticSection, alphabet).slice(1)) + "'>" +
|
|
124
|
-
staticSection + "</span>";
|
|
124
|
+
Utils.escapeHtml(staticSection) + "</span>";
|
|
125
125
|
}
|
|
126
126
|
|
|
127
127
|
if (!showVariable) {
|
|
128
|
-
offset1 = staticSection;
|
|
128
|
+
offset1 = Utils.escapeHtml(staticSection);
|
|
129
129
|
}
|
|
130
130
|
|
|
131
131
|
// Highlight offset 2
|
|
132
|
-
padding = "<span class='hl3'>" + offset2.substr(0, 2) + "</span>" +
|
|
133
|
-
"<span class='hl5'>" + offset2.substr(2, 1) + "</span>";
|
|
132
|
+
padding = "<span class='hl3'>" + Utils.escapeHtml(offset2.substr(0, 2)) + "</span>" +
|
|
133
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset2.substr(2, 1)) + "</span>";
|
|
134
134
|
offset2 = offset2.substr(3);
|
|
135
135
|
if (len2 % 4 === 2) {
|
|
136
136
|
staticSection = offset2.slice(0, -3);
|
|
137
137
|
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
138
138
|
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
|
139
|
-
staticSection + "</span>" +
|
|
140
|
-
"<span class='hl5'>" + offset2.substr(offset2.length - 3, 1) + "</span>" +
|
|
141
|
-
"<span class='hl3'>" + offset2.substr(offset2.length - 2) + "</span>";
|
|
139
|
+
Utils.escapeHtml(staticSection) + "</span>" +
|
|
140
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset2.substr(offset2.length - 3, 1)) + "</span>" +
|
|
141
|
+
"<span class='hl3'>" + Utils.escapeHtml(offset2.substr(offset2.length - 2)) + "</span>";
|
|
142
142
|
} else if (len2 % 4 === 3) {
|
|
143
143
|
staticSection = offset2.slice(0, -2);
|
|
144
144
|
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
145
145
|
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2, -2)) + "'>" +
|
|
146
|
-
staticSection + "</span>" +
|
|
147
|
-
"<span class='hl5'>" + offset2.substr(offset2.length - 2, 1) + "</span>" +
|
|
148
|
-
"<span class='hl3'>" + offset2.substr(offset2.length - 1) + "</span>";
|
|
146
|
+
Utils.escapeHtml(staticSection) + "</span>" +
|
|
147
|
+
"<span class='hl5'>" + Utils.escapeHtml(offset2.substr(offset2.length - 2, 1)) + "</span>" +
|
|
148
|
+
"<span class='hl3'>" + Utils.escapeHtml(offset2.substr(offset2.length - 1)) + "</span>";
|
|
149
149
|
} else {
|
|
150
150
|
staticSection = offset2;
|
|
151
151
|
offset2 = padding + "<span data-toggle='tooltip' data-placement='top' title='" +
|
|
152
152
|
Utils.escapeHtml(fromBase64("AAA" + staticSection, alphabet).slice(2)) + "'>" +
|
|
153
|
-
staticSection + "</span>";
|
|
153
|
+
Utils.escapeHtml(staticSection) + "</span>";
|
|
154
154
|
}
|
|
155
155
|
|
|
156
156
|
if (!showVariable) {
|
|
157
|
-
offset2 = staticSection;
|
|
157
|
+
offset2 = Utils.escapeHtml(staticSection);
|
|
158
158
|
}
|
|
159
159
|
|
|
160
160
|
return (showVariable ? "Characters highlighted in <span class='hl5'>green</span> could change if the input is surrounded by more data." +
|
package/src/node/NodeRecipe.mjs
CHANGED
|
@@ -88,16 +88,17 @@ class NodeRecipe {
|
|
|
88
88
|
* @param {NodeDish} dish
|
|
89
89
|
* @returns {NodeDish}
|
|
90
90
|
*/
|
|
91
|
-
execute(dish) {
|
|
92
|
-
|
|
93
|
-
|
|
91
|
+
async execute(dish) {
|
|
92
|
+
let prev = dish;
|
|
93
|
+
for (const curr of this.opList) {
|
|
94
94
|
if (Object.prototype.hasOwnProperty.call(curr, "op") &&
|
|
95
95
|
Object.prototype.hasOwnProperty.call(curr, "args")) {
|
|
96
|
-
|
|
96
|
+
prev = await curr.op(prev, curr.args);
|
|
97
|
+
} else {
|
|
98
|
+
prev = await curr(prev);
|
|
97
99
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
}, dish);
|
|
100
|
+
}
|
|
101
|
+
return prev;
|
|
101
102
|
}
|
|
102
103
|
}
|
|
103
104
|
|
package/src/node/api.mjs
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import NodeDish from "./NodeDish.mjs";
|
|
12
12
|
import NodeRecipe from "./NodeRecipe.mjs";
|
|
13
|
-
import OperationConfig from "../core/config/OperationConfig.json"
|
|
13
|
+
import OperationConfig from "../core/config/OperationConfig.json" with { type: "json" };
|
|
14
14
|
import { sanitise, removeSubheadingsFromArray, sentenceToCamelCase } from "./apiUtils.mjs";
|
|
15
15
|
import ExcludedOperationError from "../core/errors/ExcludedOperationError.mjs";
|
|
16
16
|
|
|
@@ -324,10 +324,10 @@ export function help(input) {
|
|
|
324
324
|
* @returns {NodeDish} of the result
|
|
325
325
|
* @throws {TypeError} if invalid recipe given.
|
|
326
326
|
*/
|
|
327
|
-
export function bake(input, recipeConfig) {
|
|
328
|
-
const recipe =
|
|
327
|
+
export async function bake(input, recipeConfig) {
|
|
328
|
+
const recipe = new NodeRecipe(recipeConfig);
|
|
329
329
|
const dish = ensureIsDish(input);
|
|
330
|
-
return recipe.execute(dish);
|
|
330
|
+
return await recipe.execute(dish);
|
|
331
331
|
}
|
|
332
332
|
|
|
333
333
|
|
package/src/web/index.js
CHANGED
|
@@ -17,8 +17,8 @@ import * as CanvasComponents from "../core/lib/CanvasComponents.mjs";
|
|
|
17
17
|
|
|
18
18
|
// CyberChef
|
|
19
19
|
import App from "./App.mjs";
|
|
20
|
-
import Categories from "../core/config/Categories.json"
|
|
21
|
-
import OperationConfig from "../core/config/OperationConfig.json"
|
|
20
|
+
import Categories from "../core/config/Categories.json" with { type: "json" };
|
|
21
|
+
import OperationConfig from "../core/config/OperationConfig.json" with { type: "json" };
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import sm from "sitemap";
|
|
2
|
-
import OperationConfig from "../../core/config/OperationConfig.json"
|
|
2
|
+
import OperationConfig from "../../core/config/OperationConfig.json" with { type: "json" };
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Generates an XML sitemap for all CyberChef operations and a number of recipes.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Polyfill for Node.js 22+ where globalThis.fetch is built-in but rejects
|
|
3
|
+
* bare filesystem paths. WASM libraries like argon2-browser call fetch() with
|
|
4
|
+
* an absolute path (e.g. "/path/to/argon2.wasm") expecting a browser-style
|
|
5
|
+
* fallback, but Node.js 22's fetch throws synchronously for non-URL strings.
|
|
6
|
+
*
|
|
7
|
+
* This wrapper intercepts such calls and serves the file via Node's fs module,
|
|
8
|
+
* returning a synthetic Response so the WASM module loads correctly.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { readFile } from "fs/promises";
|
|
12
|
+
|
|
13
|
+
if (globalThis.fetch) {
|
|
14
|
+
const originalFetch = globalThis.fetch;
|
|
15
|
+
globalThis.fetch = async function patchedFetch(url, options) {
|
|
16
|
+
const urlStr = typeof url === "string" ?
|
|
17
|
+
url :
|
|
18
|
+
url instanceof URL ?
|
|
19
|
+
url.href :
|
|
20
|
+
String(url);
|
|
21
|
+
// Intercept bare filesystem paths (absolute POSIX or Windows)
|
|
22
|
+
if (urlStr.startsWith("/") || /^[A-Za-z]:[/\\]/.test(urlStr)) {
|
|
23
|
+
const buffer = await readFile(urlStr);
|
|
24
|
+
return new Response(buffer, {
|
|
25
|
+
status: 200,
|
|
26
|
+
headers: { "Content-Type": "application/wasm" },
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
return originalFetch(url, options);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
@@ -9,7 +9,7 @@ import assert from "assert";
|
|
|
9
9
|
import chef from "cyberchef";
|
|
10
10
|
import { bake, toHex, reverse, unique, multiply } from "cyberchef";
|
|
11
11
|
|
|
12
|
-
const a = bake("Testing, 1 2 3", [
|
|
12
|
+
const a = await bake("Testing, 1 2 3", [
|
|
13
13
|
toHex,
|
|
14
14
|
reverse,
|
|
15
15
|
{
|
|
@@ -28,7 +28,7 @@ const a = bake("Testing, 1 2 3", [
|
|
|
28
28
|
|
|
29
29
|
assert.equal(a.value, "630957449041920");
|
|
30
30
|
|
|
31
|
-
const b = chef.bake("Testing, 1 2 3", [
|
|
31
|
+
const b = await chef.bake("Testing, 1 2 3", [
|
|
32
32
|
chef.toHex,
|
|
33
33
|
chef.reverse,
|
|
34
34
|
{
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import TestRegister from "../../lib/TestRegister.mjs";
|
|
2
|
-
import Categories from "../../../src/core/config/Categories.json"
|
|
3
|
-
import OperationConfig from "../../../src/core/config/OperationConfig.json"
|
|
2
|
+
import Categories from "../../../src/core/config/Categories.json" with { type: "json" };
|
|
3
|
+
import OperationConfig from "../../../src/core/config/OperationConfig.json" with { type: "json" };
|
|
4
4
|
import it from "../assertionHandler.mjs";
|
|
5
5
|
import assert from "assert";
|
|
6
6
|
|
|
@@ -170,77 +170,77 @@ TestRegister.addApiTests([
|
|
|
170
170
|
assert(chef.bake);
|
|
171
171
|
}),
|
|
172
172
|
|
|
173
|
-
it("chef.bake: should return NodeDish", () => {
|
|
174
|
-
const result = chef.bake("input", "to base 64");
|
|
173
|
+
it("chef.bake: should return NodeDish", async () => {
|
|
174
|
+
const result = await chef.bake("input", "to base 64");
|
|
175
175
|
assert(result instanceof NodeDish);
|
|
176
176
|
}),
|
|
177
177
|
|
|
178
|
-
it("chef.bake: should take an input and an op name and perform it", () => {
|
|
179
|
-
const result = chef.bake("some input", "to base 32");
|
|
178
|
+
it("chef.bake: should take an input and an op name and perform it", async () => {
|
|
179
|
+
const result = await chef.bake("some input", "to base 32");
|
|
180
180
|
assert.strictEqual(result.toString(), "ONXW2ZJANFXHA5LU");
|
|
181
181
|
}),
|
|
182
182
|
|
|
183
|
-
it("chef.bake: should complain if recipe isnt a valid object", () => {
|
|
184
|
-
assert.
|
|
183
|
+
it("chef.bake: should complain if recipe isnt a valid object", async () => {
|
|
184
|
+
await assert.rejects(() => chef.bake("some input", 3264), {
|
|
185
185
|
name: "TypeError",
|
|
186
186
|
message: "Recipe can only contain function names or functions"
|
|
187
187
|
});
|
|
188
188
|
}),
|
|
189
189
|
|
|
190
|
-
it("chef.bake: Should complain if string op is invalid", () => {
|
|
191
|
-
assert.
|
|
190
|
+
it("chef.bake: Should complain if string op is invalid", async () => {
|
|
191
|
+
await assert.rejects(() => chef.bake("some input", "not a valid operation"), {
|
|
192
192
|
name: "TypeError",
|
|
193
193
|
message: "Couldn't find an operation with name 'not a valid operation'."
|
|
194
194
|
});
|
|
195
195
|
}),
|
|
196
196
|
|
|
197
|
-
it("chef.bake: Should take an input and an operation and perform it", () => {
|
|
198
|
-
const result = chef.bake("https://google.com/search?q=help", chef.parseURI);
|
|
197
|
+
it("chef.bake: Should take an input and an operation and perform it", async () => {
|
|
198
|
+
const result = await chef.bake("https://google.com/search?q=help", chef.parseURI);
|
|
199
199
|
assert.strictEqual(result.toString(), "Protocol:\thttps:\nHostname:\tgoogle.com\nPath name:\t/search\nArguments:\n\tq = help\n");
|
|
200
200
|
}),
|
|
201
201
|
|
|
202
|
-
it("chef.bake: Should complain if an invalid operation is inputted", () => {
|
|
203
|
-
assert.
|
|
202
|
+
it("chef.bake: Should complain if an invalid operation is inputted", async () => {
|
|
203
|
+
await assert.rejects(() => chef.bake("https://google.com/search?q=help", () => {}), {
|
|
204
204
|
name: "TypeError",
|
|
205
205
|
message: "Inputted function not a Chef operation."
|
|
206
206
|
});
|
|
207
207
|
}),
|
|
208
208
|
|
|
209
|
-
it("chef.bake: accepts an array of operation names and performs them all in order", () => {
|
|
210
|
-
const result = chef.bake("https://google.com/search?q=that's a complicated question", ["URL encode", "URL decode", "Parse URI"]);
|
|
209
|
+
it("chef.bake: accepts an array of operation names and performs them all in order", async () => {
|
|
210
|
+
const result = await chef.bake("https://google.com/search?q=that's a complicated question", ["URL encode", "URL decode", "Parse URI"]);
|
|
211
211
|
assert.strictEqual(result.toString(), "Protocol:\thttps:\nHostname:\tgoogle.com\nPath name:\t/search\nArguments:\n\tq = that's a complicated question\n");
|
|
212
212
|
}),
|
|
213
213
|
|
|
214
|
-
it("chef.bake: forgiving with operation names", () =>{
|
|
215
|
-
const result = chef.bake("https://google.com/search?q=that's a complicated question", ["urlencode", "url decode", "parseURI"]);
|
|
214
|
+
it("chef.bake: forgiving with operation names", async () =>{
|
|
215
|
+
const result = await chef.bake("https://google.com/search?q=that's a complicated question", ["urlencode", "url decode", "parseURI"]);
|
|
216
216
|
assert.strictEqual(result.toString(), "Protocol:\thttps:\nHostname:\tgoogle.com\nPath name:\t/search\nArguments:\n\tq = that's a complicated question\n");
|
|
217
217
|
}),
|
|
218
218
|
|
|
219
|
-
it("chef.bake: forgiving with operation names", () =>{
|
|
220
|
-
const result = chef.bake("hello", ["to base 64"]);
|
|
219
|
+
it("chef.bake: forgiving with operation names", async () =>{
|
|
220
|
+
const result = await chef.bake("hello", ["to base 64"]);
|
|
221
221
|
assert.strictEqual(result.toString(), "aGVsbG8=");
|
|
222
222
|
}),
|
|
223
223
|
|
|
224
|
-
it("chef.bake: if recipe is empty array, return input as dish", () => {
|
|
225
|
-
const result = chef.bake("some input", []);
|
|
224
|
+
it("chef.bake: if recipe is empty array, return input as dish", async () => {
|
|
225
|
+
const result = await chef.bake("some input", []);
|
|
226
226
|
assert.strictEqual(result.toString(), "some input");
|
|
227
227
|
assert(result instanceof NodeDish, "Result is not instance of NodeDish");
|
|
228
228
|
}),
|
|
229
229
|
|
|
230
|
-
it("chef.bake: accepts an array of operations as recipe", () => {
|
|
231
|
-
const result = chef.bake("https://google.com/search?q=that's a complicated question", [chef.URLEncode, chef.URLDecode, chef.parseURI]);
|
|
230
|
+
it("chef.bake: accepts an array of operations as recipe", async () => {
|
|
231
|
+
const result = await chef.bake("https://google.com/search?q=that's a complicated question", [chef.URLEncode, chef.URLDecode, chef.parseURI]);
|
|
232
232
|
assert.strictEqual(result.toString(), "Protocol:\thttps:\nHostname:\tgoogle.com\nPath name:\t/search\nArguments:\n\tq = that's a complicated question\n");
|
|
233
233
|
}),
|
|
234
234
|
|
|
235
|
-
it("should complain if an invalid operation is inputted as part of array", () => {
|
|
236
|
-
assert.
|
|
235
|
+
it("should complain if an invalid operation is inputted as part of array", async () => {
|
|
236
|
+
await assert.rejects(() => chef.bake("something", [() => {}]), {
|
|
237
237
|
name: "TypeError",
|
|
238
238
|
message: "Inputted function not a Chef operation."
|
|
239
239
|
});
|
|
240
240
|
}),
|
|
241
241
|
|
|
242
|
-
it("chef.bake: should take single JSON object describing op and args OBJ", () => {
|
|
243
|
-
const result = chef.bake("some input", {
|
|
242
|
+
it("chef.bake: should take single JSON object describing op and args OBJ", async () => {
|
|
243
|
+
const result = await chef.bake("some input", {
|
|
244
244
|
op: chef.toHex,
|
|
245
245
|
args: {
|
|
246
246
|
Delimiter: "Colon"
|
|
@@ -249,23 +249,23 @@ TestRegister.addApiTests([
|
|
|
249
249
|
assert.strictEqual(result.toString(), "73:6f:6d:65:20:69:6e:70:75:74");
|
|
250
250
|
}),
|
|
251
251
|
|
|
252
|
-
it("chef.bake: should take single JSON object desribing op with optional args", () => {
|
|
253
|
-
const result = chef.bake("some input", {
|
|
252
|
+
it("chef.bake: should take single JSON object desribing op with optional args", async () => {
|
|
253
|
+
const result = await chef.bake("some input", {
|
|
254
254
|
op: chef.toHex,
|
|
255
255
|
});
|
|
256
256
|
assert.strictEqual(result.toString(), "73 6f 6d 65 20 69 6e 70 75 74");
|
|
257
257
|
}),
|
|
258
258
|
|
|
259
|
-
it("chef.bake: should take single JSON object describing op and args ARRAY", () => {
|
|
260
|
-
const result = chef.bake("some input", {
|
|
259
|
+
it("chef.bake: should take single JSON object describing op and args ARRAY", async () => {
|
|
260
|
+
const result = await chef.bake("some input", {
|
|
261
261
|
op: chef.toHex,
|
|
262
262
|
args: ["Colon"]
|
|
263
263
|
});
|
|
264
264
|
assert.strictEqual(result.toString(), "73:6f:6d:65:20:69:6e:70:75:74");
|
|
265
265
|
}),
|
|
266
266
|
|
|
267
|
-
it("chef.bake: should error if op in JSON is not chef op", () => {
|
|
268
|
-
assert.
|
|
267
|
+
it("chef.bake: should error if op in JSON is not chef op", async () => {
|
|
268
|
+
await assert.rejects(() => chef.bake("some input", {
|
|
269
269
|
op: () => {},
|
|
270
270
|
args: ["Colon"],
|
|
271
271
|
}), {
|
|
@@ -274,8 +274,8 @@ TestRegister.addApiTests([
|
|
|
274
274
|
});
|
|
275
275
|
}),
|
|
276
276
|
|
|
277
|
-
it("chef.bake: should take multiple ops in JSON object form, some ops by string", () => {
|
|
278
|
-
const result = chef.bake("some input", [
|
|
277
|
+
it("chef.bake: should take multiple ops in JSON object form, some ops by string", async () => {
|
|
278
|
+
const result = await chef.bake("some input", [
|
|
279
279
|
{
|
|
280
280
|
op: chef.toHex,
|
|
281
281
|
args: ["Colon"]
|
|
@@ -290,8 +290,8 @@ TestRegister.addApiTests([
|
|
|
290
290
|
assert.strictEqual(result.toString(), "67;63;72;66;146;72;66;144;72;66;65;72;62;60;72;66;71;72;66;145;72;67;60;72;67;65;72;67;64");
|
|
291
291
|
}),
|
|
292
292
|
|
|
293
|
-
it("chef.bake: should take multiple ops in JSON object form, some without args", () => {
|
|
294
|
-
const result = chef.bake("some input", [
|
|
293
|
+
it("chef.bake: should take multiple ops in JSON object form, some without args", async () => {
|
|
294
|
+
const result = await chef.bake("some input", [
|
|
295
295
|
{
|
|
296
296
|
op: chef.toHex,
|
|
297
297
|
},
|
|
@@ -305,8 +305,8 @@ TestRegister.addApiTests([
|
|
|
305
305
|
assert.strictEqual(result.toString(), "67;63;40;66;146;40;66;144;40;66;65;40;62;60;40;66;71;40;66;145;40;67;60;40;67;65;40;67;64");
|
|
306
306
|
}),
|
|
307
307
|
|
|
308
|
-
it("chef.bake: should handle op with multiple args", () => {
|
|
309
|
-
const result = chef.bake("some input", {
|
|
308
|
+
it("chef.bake: should handle op with multiple args", async () => {
|
|
309
|
+
const result = await chef.bake("some input", {
|
|
310
310
|
op: "to morse code",
|
|
311
311
|
args: {
|
|
312
312
|
formatOptions: "Dash/Dot",
|
|
@@ -317,13 +317,13 @@ TestRegister.addApiTests([
|
|
|
317
317
|
assert.strictEqual(result.toString(), "DotDotDot\\DashDashDash\\DashDash\\Dot,DotDot\\DashDot\\DotDashDashDot\\DotDotDash\\Dash");
|
|
318
318
|
}),
|
|
319
319
|
|
|
320
|
-
it("chef.bake: should take compact JSON format from Chef Website as recipe", () => {
|
|
321
|
-
const result = chef.bake("some input", [{"op": "To Morse Code", "args": ["Dash/Dot", "Backslash", "Comma"]}, {"op": "Hex to PEM", "args": ["SOMETHING"]}, {"op": "To Snake case", "args": [false]}]);
|
|
320
|
+
it("chef.bake: should take compact JSON format from Chef Website as recipe", async () => {
|
|
321
|
+
const result = await chef.bake("some input", [{"op": "To Morse Code", "args": ["Dash/Dot", "Backslash", "Comma"]}, {"op": "Hex to PEM", "args": ["SOMETHING"]}, {"op": "To Snake case", "args": [false]}]);
|
|
322
322
|
assert.strictEqual(result.toString(), "begin_something_anananaaaaak_da_aaak_da_aaaaananaaaaaaan_da_aaaaaaanan_da_aaak_end_something");
|
|
323
323
|
}),
|
|
324
324
|
|
|
325
|
-
it("chef.bake: should accept Clean JSON format from Chef website as recipe", () => {
|
|
326
|
-
const result = chef.bake("some input", [
|
|
325
|
+
it("chef.bake: should accept Clean JSON format from Chef website as recipe", async () => {
|
|
326
|
+
const result = await chef.bake("some input", [
|
|
327
327
|
{ "op": "To Morse Code",
|
|
328
328
|
"args": ["Dash/Dot", "Backslash", "Comma"] },
|
|
329
329
|
{ "op": "Hex to PEM",
|
|
@@ -334,8 +334,8 @@ TestRegister.addApiTests([
|
|
|
334
334
|
assert.strictEqual(result.toString(), "begin_something_anananaaaaak_da_aaak_da_aaaaananaaaaaaan_da_aaaaaaanan_da_aaak_end_something");
|
|
335
335
|
}),
|
|
336
336
|
|
|
337
|
-
it("chef.bake: should accept Clean JSON format from Chef website - args optional", () => {
|
|
338
|
-
const result = chef.bake("some input", [
|
|
337
|
+
it("chef.bake: should accept Clean JSON format from Chef website - args optional", async () => {
|
|
338
|
+
const result = await chef.bake("some input", [
|
|
339
339
|
{ "op": "To Morse Code" },
|
|
340
340
|
{ "op": "Hex to PEM",
|
|
341
341
|
"args": ["SOMETHING"] },
|
|
@@ -345,31 +345,28 @@ TestRegister.addApiTests([
|
|
|
345
345
|
assert.strictEqual(result.toString(), "begin_something_aaaaaaaaaaaaaa_end_something");
|
|
346
346
|
}),
|
|
347
347
|
|
|
348
|
-
it("chef.bake: should accept operation names from Chef Website which contain forward slash", () => {
|
|
349
|
-
const result = chef.bake("I'll have the test salmon", [
|
|
348
|
+
it("chef.bake: should accept operation names from Chef Website which contain forward slash", async () => {
|
|
349
|
+
const result = await chef.bake("I'll have the test salmon", [
|
|
350
350
|
{ "op": "Find / Replace",
|
|
351
351
|
"args": [{ "option": "Regex", "string": "test" }, "good", true, false, true, false]}
|
|
352
352
|
]);
|
|
353
353
|
assert.strictEqual(result.toString(), "I'll have the good salmon");
|
|
354
354
|
}),
|
|
355
355
|
|
|
356
|
-
it("chef.bake: should accept operation names from Chef Website which contain a hyphen", () => {
|
|
357
|
-
const result = chef.bake("I'll have the test salmon", [
|
|
356
|
+
it("chef.bake: should accept operation names from Chef Website which contain a hyphen", async () => {
|
|
357
|
+
const result = await chef.bake("I'll have the test salmon", [
|
|
358
358
|
{ "op": "Adler-32 Checksum",
|
|
359
359
|
"args": [] }
|
|
360
360
|
]);
|
|
361
361
|
assert.strictEqual(result.toString(), "6e4208f8");
|
|
362
362
|
}),
|
|
363
363
|
|
|
364
|
-
it("chef.bake: should accept operation names from Chef Website which contain a period", () => {
|
|
365
|
-
const result = chef.bake("30 13 02 01 05 16 0e 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f", [
|
|
364
|
+
it("chef.bake: should accept operation names from Chef Website which contain a period", async () => {
|
|
365
|
+
const result = await chef.bake("30 13 02 01 05 16 0e 41 6e 79 62 6f 64 79 20 74 68 65 72 65 3f", [
|
|
366
366
|
{ "op": "Parse ASN.1 hex string",
|
|
367
367
|
"args": [0, 32] }
|
|
368
368
|
]);
|
|
369
|
-
assert.strictEqual(result.toString(), `SEQUENCE
|
|
370
|
-
INTEGER 05
|
|
371
|
-
IA5String 'Anybody there?'
|
|
372
|
-
`);
|
|
369
|
+
assert.strictEqual(result.toString(), `SEQUENCE\n INTEGER 05\n IA5String 'Anybody there?'\n`);
|
|
373
370
|
}),
|
|
374
371
|
|
|
375
372
|
it("Excluded operations: throw a sensible error when you try and call one", () => {
|
|
@@ -381,16 +378,16 @@ TestRegister.addApiTests([
|
|
|
381
378
|
}
|
|
382
379
|
}),
|
|
383
380
|
|
|
384
|
-
it("chef.bake: cannot accept flowControl operations in recipe", () => {
|
|
385
|
-
assert.
|
|
381
|
+
it("chef.bake: cannot accept flowControl operations in recipe", async () => {
|
|
382
|
+
await assert.rejects(() => chef.bake("some input", "magic"), {
|
|
386
383
|
name: "TypeError",
|
|
387
384
|
message: "flowControl operations like Magic are not currently allowed in recipes for chef.bake in the Node API"
|
|
388
385
|
});
|
|
389
|
-
assert.
|
|
386
|
+
await assert.rejects(() => chef.bake("some input", magic), {
|
|
390
387
|
name: "TypeError",
|
|
391
388
|
message: "flowControl operations like Magic are not currently allowed in recipes for chef.bake in the Node API"
|
|
392
389
|
});
|
|
393
|
-
assert.
|
|
390
|
+
await assert.rejects(() => chef.bake("some input", ["to base 64", "magic"]), {
|
|
394
391
|
name: "TypeError",
|
|
395
392
|
message: "flowControl operations like Magic are not currently allowed in recipes for chef.bake in the Node API"
|
|
396
393
|
});
|
|
@@ -116,4 +116,15 @@ TestRegister.addTests([
|
|
|
116
116
|
},
|
|
117
117
|
],
|
|
118
118
|
},
|
|
119
|
+
{
|
|
120
|
+
name: "Show Base64 offsets: escapes static output",
|
|
121
|
+
input: "\x00\x10\x83\x10\x51\x87",
|
|
122
|
+
expectedOutput: "<script>\n<AQmsBRk66\n<ia1AEIM6",
|
|
123
|
+
recipeConfig: [
|
|
124
|
+
{
|
|
125
|
+
op: "Show Base64 offsets",
|
|
126
|
+
args: ["<script>ale(1)/.ABCDEFGHIJKLMNOPQRSTUVWXYZbdfghjkmnoquvwxyz023456", false, "Raw"],
|
|
127
|
+
},
|
|
128
|
+
],
|
|
129
|
+
},
|
|
119
130
|
]);
|