Merge branch 'master' into fix-jwt

This commit is contained in:
GCHQDeveloper581 2026-06-13 08:38:04 +01:00 committed by GitHub
commit 2cbe0d7575
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
38 changed files with 2189 additions and 1572 deletions

View File

@ -15,6 +15,8 @@ updates:
day: 'friday'
time: '03:00'
timezone: Europe/London
cooldown:
default-days: 2
commit-message:
prefix: 'chore (deps): '
ignore:
@ -39,9 +41,12 @@ updates:
versions: [ '>=2.0.0' ]
- dependency-name: 'jimp'
versions: [ '1.6.1' ]
- dependency-name: 'jq-web'
versions: [ '>=0.6.0' ]
groups:
#
# Grouping so we don't get a seperate PR for every patch version.
# Grouping so patch version updates are batched together in a single PR
# and similarly with minor version updates
#
patch-updates:
applies-to: version-updates
@ -49,6 +54,12 @@ updates:
- '*'
update-types:
- 'patch'
minor-updates:
applies-to: version-updates
patterns:
- '*'
update-types:
- 'minor'
# Versioning on Github Actions
- package-ecosystem: "github-actions"
@ -60,8 +71,14 @@ updates:
day: 'friday'
time: '03:00'
timezone: Europe/London
cooldown:
default-days: 4
commit-message:
prefix: 'chore (deps): '
groups:
actions-dependencies:
patterns:
- "*"
- package-ecosystem: docker
directory: /
@ -70,3 +87,11 @@ updates:
day: 'friday'
time: '03:00'
timezone: Europe/London
cooldown:
default-days: 4
commit-message:
prefix: 'chore (deps): '
groups:
docker-dependencies:
patterns:
- "*"

View File

@ -16,7 +16,7 @@ jobs:
pages: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set node version
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0

View File

@ -12,7 +12,7 @@ jobs:
main:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set node version
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@ -64,7 +64,7 @@ jobs:
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Production Image Build
if: success()

View File

@ -22,7 +22,7 @@ jobs:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set node version
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
@ -64,7 +64,7 @@ jobs:
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
- name: Set up QEMU
uses: docker/setup-qemu-action@ce360397dd3f832beb865e1373c09c0e9f86d70a # v4.0.0
uses: docker/setup-qemu-action@06116385d9baf250c9f4dcb4858b16962ea869c3 # v4.1.0
- name: Image Metadata
id: image-metadata
@ -110,7 +110,7 @@ jobs:
needs: main
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3
- name: Set node version
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0

1
.gitignore vendored
View File

@ -10,6 +10,7 @@ src/core/config/OperationConfig.json
src/core/operations/index.mjs
src/node/config/OperationConfig.json
src/node/index.mjs
tests/operations/index.mjs
**/*.DS_Store
tests/browser/output/*
.node-version

View File

@ -4,7 +4,7 @@
# Modifier --platform=$BUILDPLATFORM limits the platform to "BUILDPLATFORM" during buildx multi-platform builds
# This is because npm "chromedriver" package is not compatiable with all platforms
# For more info see: https://docs.docker.com/build/building/multi-platform/#cross-compilation
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:d1b3b4da11eefd5941e7f0b9cf17783fc99d9c6fc34884a665f40a06dbdfc94f AS builder
FROM --platform=$BUILDPLATFORM node:24-alpine@sha256:fb71d01345f11b708a3553c66e7c74074f2d506400ea81973343d915cb64eef0 AS builder
WORKDIR /app
@ -27,7 +27,7 @@ RUN npm run build
#########################################
# Package static build files into nginx #
#########################################
FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:b9f7ba14f1f7bd3d40d7753584048f92c3aef9ccf5fab14efe4451a8d4c04d63 AS cyberchef
FROM nginxinc/nginx-unprivileged:stable-alpine@sha256:37f356a5eba5d187365b4f59cd6cc29f1f922ad18146d554b576a80983377e6a AS cyberchef
LABEL maintainer="GCHQ <oss@gchq.gov.uk>"

View File

@ -144,7 +144,8 @@ module.exports = function (grunt) {
new BundleAnalyzerPlugin({
analyzerMode: "static",
reportFilename: "BundleAnalyzerReport.html",
openAnalyzer: false
openAnalyzer: false,
excludeAssets: /.*Worker.js/
}),
]
};

View File

@ -72,6 +72,7 @@ You can use as many operations as you like in simple or complex ways. Some examp
- [Carry out different operations on data of different types][8]
- [Use parts of the input as arguments to operations][9]
- [Perform AES decryption, extracting the IV from the beginning of the cipher stream][10]
- [A simpler way to perform the same AES Decryption][13]
- [Automagically detect several layers of nested encoding][12]
@ -147,6 +148,7 @@ CyberChef is released under the [Apache 2.0 Licence](https://www.apache.org/lice
[7]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)From_UNIX_Timestamp('Seconds%20(s)')&input=OTc4MzQ2ODAwCjEwMTI2NTEyMDAKMTA0NjY5NjQwMAoxMDgxMDg3MjAwCjExMTUzMDUyMDAKMTE0OTYwOTYwMA
[8]: https://gchq.github.io/CyberChef/#recipe=Fork('%5C%5Cn','%5C%5Cn',false)Conditional_Jump('1',false,'base64',10)To_Hex('Space')Return()Label('base64')To_Base64('A-Za-z0-9%2B/%3D')&input=U29tZSBkYXRhIHdpdGggYSAxIGluIGl0ClNvbWUgZGF0YSB3aXRoIGEgMiBpbiBpdA
[9]: https://gchq.github.io/CyberChef/#recipe=Register('key%3D(%5B%5C%5Cda-f%5D*)',true,false)Find_/_Replace(%7B'option':'Regex','string':'.*data%3D(.*)'%7D,'$1',true,false,true)RC4(%7B'option':'Hex','string':'$R0'%7D,'Hex','Latin1')&input=aHR0cDovL21hbHdhcmV6LmJpei9iZWFjb24ucGhwP2tleT0wZTkzMmE1YyZkYXRhPThkYjdkNWViZTM4NjYzYTU0ZWNiYjMzNGUzZGIxMQ
[10]: https://gchq.github.io/CyberChef/#recipe=Register('(.%7B32%7D)',true,false)Drop_bytes(0,32,false)AES_Decrypt(%7B'option':'Hex','string':'1748e7179bd56570d51fa4ba287cc3e5'%7D,%7B'option':'Hex','string':'$R0'%7D,'CTR','Hex','Raw',%7B'option':'Hex','string':''%7D)&input=NTFlMjAxZDQ2MzY5OGVmNWY3MTdmNzFmNWI0NzEyYWYyMGJlNjc0YjNiZmY1M2QzODU0NjM5NmVlNjFkYWFjNDkwOGUzMTljYTNmY2Y3MDg5YmZiNmIzOGVhOTllNzgxZDI2ZTU3N2JhOWRkNmYzMTFhMzk0MjBiODk3OGU5MzAxNGIwNDJkNDQ3MjZjYWVkZjU0MzZlYWY2NTI0MjljMGRmOTRiNTIxNjc2YzdjMmNlODEyMDk3YzI3NzI3M2M3YzcyY2Q4OWFlYzhkOWZiNGEyNzU4NmNjZjZhYTBhZWUyMjRjMzRiYTNiZmRmN2FlYjFkZGQ0Nzc2MjJiOTFlNzJjOWU3MDlhYjYwZjhkYWY3MzFlYzBjYzg1Y2UwZjc0NmZmMTU1NGE1YTNlYzI5MWNhNDBmOWU2MjlhODcyNTkyZDk4OGZkZDgzNDUzNGFiYTc5YzFhZDE2NzY3NjlhN2MwMTBiZjA0NzM5ZWNkYjY1ZDk1MzAyMzcxZDYyOWQ5ZTM3ZTdiNGEzNjFkYTQ2OGYxZWQ1MzU4OTIyZDJlYTc1MmRkMTFjMzY2ZjMwMTdiMTRhYTAxMWQyYWYwM2M0NGY5NTU3OTA5OGExNWUzY2Y5YjQ0ODZmOGZmZTljMjM5ZjM0ZGU3MTUxZjZjYTY1MDBmZTRiODUwYzNmMWMwMmU4MDFjYWYzYTI0NDY0NjE0ZTQyODAxNjE1YjhmZmFhMDdhYzgyNTE0OTNmZmRhN2RlNWRkZjMzNjg4ODBjMmI5NWIwMzBmNDFmOGYxNTA2NmFkZDA3MWE2NmNmNjBlNWY0NmYzYTIzMGQzOTdiNjUyOTYzYTIxYTUzZg
[10]: https://gchq.github.io/CyberChef/#recipe=Register('(.%7B32%7D)',true,false,false)Drop_bytes(0,32,false)AES_Decrypt(%7B'option':'Hex','string':'1748e7179bd56570d51fa4ba287cc3e5'%7D,%7B'option':'Hex','string':'$R0'%7D,16,'CTR','Hex','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D,'Off')&input=NTFlMjAxZDQ2MzY5OGVmNWY3MTdmNzFmNWI0NzEyYWYyMGJlNjc0YjNiZmY1M2QzODU0NjM5NmVlNjFkYWFjNDkwOGUzMTljYTNmY2Y3MDg5YmZiNmIzOGVhOTllNzgxZDI2ZTU3N2JhOWRkNmYzMTFhMzk0MjBiODk3OGU5MzAxNGIwNDJkNDQ3MjZjYWVkZjU0MzZlYWY2NTI0MjljMGRmOTRiNTIxNjc2YzdjMmNlODEyMDk3YzI3NzI3M2M3YzcyY2Q4OWFlYzhkOWZiNGEyNzU4NmNjZjZhYTBhZWUyMjRjMzRiYTNiZmRmN2FlYjFkZGQ0Nzc2MjJiOTFlNzJjOWU3MDlhYjYwZjhkYWY3MzFlYzBjYzg1Y2UwZjc0NmZmMTU1NGE1YTNlYzI5MWNhNDBmOWU2MjlhODcyNTkyZDk4OGZkZDgzNDUzNGFiYTc5YzFhZDE2NzY3NjlhN2MwMTBiZjA0NzM5ZWNkYjY1ZDk1MzAyMzcxZDYyOWQ5ZTM3ZTdiNGEzNjFkYTQ2OGYxZWQ1MzU4OTIyZDJlYTc1MmRkMTFjMzY2ZjMwMTdiMTRhYTAxMWQyYWYwM2M0NGY5NTU3OTA5OGExNWUzY2Y5YjQ0ODZmOGZmZTljMjM5ZjM0ZGU3MTUxZjZjYTY1MDBmZTRiODUwYzNmMWMwMmU4MDFjYWYzYTI0NDY0NjE0ZTQyODAxNjE1YjhmZmFhMDdhYzgyNTE0OTNmZmRhN2RlNWRkZjMzNjg4ODBjMmI5NWIwMzBmNDFmOGYxNTA2NmFkZDA3MWE2NmNmNjBlNWY0NmYzYTIzMGQzOTdiNjUyOTYzYTIxYTUzZg
[11]: https://gchq.github.io/CyberChef/#recipe=XOR(%7B'option':'Hex','string':'3a'%7D,'Standard',false)To_Hexdump(16,false,false)&input=VGhlIGFuc3dlciB0byB0aGUgdWx0aW1hdGUgcXVlc3Rpb24gb2YgbGlmZSwgdGhlIFVuaXZlcnNlLCBhbmQgZXZlcnl0aGluZyBpcyA0Mi4
[12]: https://gchq.github.io/CyberChef/#recipe=Magic(3,false,false)&input=V1VhZ3dzaWFlNm1QOGdOdENDTFVGcENwQ0IyNlJtQkRvREQ4UGFjZEFtekF6QlZqa0syUXN0RlhhS2hwQzZpVVM3UkhxWHJKdEZpc29SU2dvSjR3aGptMWFybTg2NHFhTnE0UmNmVW1MSHJjc0FhWmM1VFhDWWlmTmRnUzgzZ0RlZWpHWDQ2Z2FpTXl1QlY2RXNrSHQxc2NnSjg4eDJ0TlNvdFFEd2JHWTFtbUNvYjJBUkdGdkNLWU5xaU45aXBNcTFaVTFtZ2tkYk51R2NiNzZhUnRZV2hDR1VjOGc5M1VKdWRoYjhodHNoZVpud1RwZ3FoeDgzU1ZKU1pYTVhVakpUMnptcEM3dVhXdHVtcW9rYmRTaTg4WXRrV0RBYzFUb291aDJvSDRENGRkbU5LSldVRHBNd21uZ1VtSzE0eHdtb21jY1BRRTloTTE3MkFQblNxd3hkS1ExNzJSa2NBc3lzbm1qNWdHdFJtVk5OaDJzMzU5d3I2bVMyUVJQ
[13]: https://gchq.github.io/CyberChef/#recipe=AES_Decrypt(%7B'option':'Hex','string':'1748e7179bd56570d51fa4ba287cc3e5'%7D,%7B'option':'Hex','string':'$R0'%7D,16,'CTR','Hex','Raw',%7B'option':'Hex','string':''%7D,%7B'option':'Hex','string':''%7D,'From%20start')&input=NTFlMjAxZDQ2MzY5OGVmNWY3MTdmNzFmNWI0NzEyYWYyMGJlNjc0YjNiZmY1M2QzODU0NjM5NmVlNjFkYWFjNDkwOGUzMTljYTNmY2Y3MDg5YmZiNmIzOGVhOTllNzgxZDI2ZTU3N2JhOWRkNmYzMTFhMzk0MjBiODk3OGU5MzAxNGIwNDJkNDQ3MjZjYWVkZjU0MzZlYWY2NTI0MjljMGRmOTRiNTIxNjc2YzdjMmNlODEyMDk3YzI3NzI3M2M3YzcyY2Q4OWFlYzhkOWZiNGEyNzU4NmNjZjZhYTBhZWUyMjRjMzRiYTNiZmRmN2FlYjFkZGQ0Nzc2MjJiOTFlNzJjOWU3MDlhYjYwZjhkYWY3MzFlYzBjYzg1Y2UwZjc0NmZmMTU1NGE1YTNlYzI5MWNhNDBmOWU2MjlhODcyNTkyZDk4OGZkZDgzNDUzNGFiYTc5YzFhZDE2NzY3NjlhN2MwMTBiZjA0NzM5ZWNkYjY1ZDk1MzAyMzcxZDYyOWQ5ZTM3ZTdiNGEzNjFkYTQ2OGYxZWQ1MzU4OTIyZDJlYTc1MmRkMTFjMzY2ZjMwMTdiMTRhYTAxMWQyYWYwM2M0NGY5NTU3OTA5OGExNWUzY2Y5YjQ0ODZmOGZmZTljMjM5ZjM0ZGU3MTUxZjZjYTY1MDBmZTRiODUwYzNmMWMwMmU4MDFjYWYzYTI0NDY0NjE0ZTQyODAxNjE1YjhmZmFhMDdhYzgyNTE0OTNmZmRhN2RlNWRkZjMzNjg4ODBjMmI5NWIwMzBmNDFmOGYxNTA2NmFkZDA3MWE2NmNmNjBlNWY0NmYzYTIzMGQzOTdiNjUyOTYzYTIxYTUzZg

View File

@ -2,25 +2,15 @@
## Supported Versions
CyberChef is supported on a best endeavours basis. Patches will be applied to
the latest version rather than retroactively to older versions. To ensure you
are using the most secure version of CyberChef, please make sure you have the
[latest release](https://github.com/gchq/CyberChef/releases/latest). The
official [live demo](https://gchq.github.io/CyberChef/) is always up to date.
CyberChef is supported on a best endeavours basis.
Patches will be applied to the latest version rather than retroactively to older versions.
To ensure you are using the most secure version of CyberChef, please make sure you have the [latest release](https://github.com/gchq/CyberChef/releases/latest). [The official website](https://gchq.github.io/CyberChef/) is always up to date.
## Reporting a Vulnerability
In most scenarios, the most appropriate way to report a vulnerability is to
[raise a new issue](https://github.com/gchq/CyberChef/issues/new/choose)
describing the problem in as much detail as possible, ideally with examples.
This will obviously be public. If you feel that the vulnerability is
significant enough to warrant a private disclosure, please email
[oss@gchq.gov.uk](mailto:oss@gchq.gov.uk) and
[n1474335@gmail.com](mailto:n1474335@gmail.com).
If you discover a vulnerability in CyberChef, please do not publicly disclose it, and do not create a GitHub issue.
Disclosures of vulnerabilities in CyberChef are always welcomed. Whilst we aim
to write clean and secure code free from bugs, we recognise that this is an open
source project written by analysts in their spare time, relying on dozens of
open source libraries that are modified and updated on a regular basis. We hope
that the community will continue to support us as we endeavour to maintain and
develop this tool together.
Instead, send an email as soon as possible to [CyberChefSecurity@gchq.gov.uk](mailto:CyberChefSecurity@gchq.gov.uk).
The report will be acknowledged and actioned urgently by the CyberChef maintainers.
If you do not receive a timely acknowledgement, please notify [oss@gchq.gov.uk](mailto:oss@gchq.gov.uk) and [CyberChef@gchq.gov.uk](mailto:CyberChef@gchq.gov.uk) of your vulnerability report.

2148
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -2,7 +2,7 @@
"name": "cyberchef",
"version": "11.0.0",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"author": "GCHQ <CyberChef@gchq.gov.uk>",
"homepage": "https://gchq.github.io/CyberChef",
"copyright": "Crown copyright 2016",
"license": "Apache-2.0",
@ -39,17 +39,17 @@
"node >= 24"
],
"devDependencies": {
"@babel/eslint-parser": "^7.28.6",
"@babel/eslint-parser": "^7.29.7",
"@babel/plugin-syntax-import-assertions": "^7.28.6",
"@babel/plugin-transform-runtime": "^7.29.0",
"@babel/preset-env": "^7.29.5",
"@babel/runtime": "^7.29.2",
"@babel/plugin-transform-runtime": "^7.29.7",
"@babel/preset-env": "^7.29.7",
"@babel/runtime": "^7.29.7",
"@codemirror/commands": "^6.10.3",
"@codemirror/language": "^6.12.3",
"@codemirror/search": "^6.7.0",
"@codemirror/state": "^6.5.4",
"@codemirror/view": "^6.43.0",
"@puppeteer/browsers": "3.0.3",
"@codemirror/view": "^6.43.1",
"@puppeteer/browsers": "3.0.4",
"autoprefixer": "^10.5.0",
"babel-loader": "^10.1.1",
"base64-loader": "^1.0.0",
@ -59,7 +59,7 @@
"compression-webpack-plugin": "^12.0.0",
"copy-webpack-plugin": "^14.0.0",
"core-js": "^3.49.0",
"cspell": "^9.7.0",
"cspell": "^10.0.1",
"css-loader": "^7.1.4",
"eslint": "^9.39.4",
"eslint-plugin-jsdoc": "^50.8.0",
@ -71,23 +71,23 @@
"grunt-contrib-connect": "^5.0.1",
"grunt-contrib-copy": "~1.0.0",
"grunt-contrib-watch": "^1.1.0",
"grunt-eslint": "^25.0.0",
"grunt-eslint": "^26.0.0",
"grunt-exec": "~3.0.0",
"grunt-webpack": "^6.0.0",
"grunt-webpack": "^8.0.0",
"grunt-zip": "^1.0.0",
"html-webpack-plugin": "^5.6.7",
"imports-loader": "^5.0.0",
"mini-css-extract-plugin": "2.10.2",
"modify-source-webpack-plugin": "^4.1.0",
"nightwatch": "^3.15.0",
"nightwatch": "^3.16.0",
"postcss": "^8.5.15",
"postcss-css-variables": "^0.19.0",
"postcss-import": "^16.1.1",
"postcss-loader": "^8.2.1",
"prompt": "^1.3.0",
"sitemap": "^8.0.3",
"terser": "^5.46.2",
"webpack": "^5.107.1",
"sitemap": "^9.0.1",
"terser": "^5.48.0",
"webpack": "^5.107.2",
"webpack-bundle-analyzer": "^5.3.0",
"webpack-dev-server": "^5.2.4",
"webpack-node-externals": "^3.0.0",
@ -105,7 +105,7 @@
"assert": "^2.1.0",
"avsc": "^5.7.9",
"bcryptjs": "^3.0.3",
"bignumber.js": "^9.3.1",
"bignumber.js": "^11.1.3",
"blakejs": "^1.2.1",
"bootstrap": "4.6.2",
"bootstrap-colorpicker": "^3.4.0",
@ -113,7 +113,7 @@
"browserify-zlib": "^0.2.0",
"bson": "^7.2.0",
"buffer": "^6.0.3",
"cbor": "9.0.2",
"cbor": "10.0.12",
"chi-squared": "^1.1.0",
"codepage": "^1.15.0",
"crypto-api": "^0.8.5",
@ -122,8 +122,8 @@
"ctph.js": "0.0.5",
"d3": "7.9.0",
"d3-hexbin": "^0.2.2",
"diff": "^5.2.2",
"dompurify": "^3.4.5",
"diff": "^9.0.0",
"dompurify": "^3.4.8",
"es6-promisify": "^7.0.0",
"escodegen": "^2.1.0",
"esprima": "^4.0.1",
@ -143,7 +143,7 @@
"js-sha3": "^0.9.3",
"jsesc": "^3.1.0",
"json5": "^2.2.3",
"jsonata": "^2.1.0",
"jsonata": "^2.2.1",
"jsonpath-plus": "^10.4.0",
"jsonwebtoken": "9.0.3",
"jsqr": "^1.4.0",
@ -156,7 +156,7 @@
"loglevel-message-prefix": "^3.0.0",
"lz-string": "^1.5.0",
"lz4js": "^0.2.0",
"markdown-it": "^14.1.1",
"markdown-it": "^14.2.0",
"moment": "^2.30.1",
"moment-timezone": "^0.6.2",
"ngeohash": "^0.6.3",
@ -170,7 +170,7 @@
"path": "^0.12.7",
"popper.js": "^1.16.1",
"process": "^0.11.10",
"protobufjs": "^7.6.1",
"protobufjs": "^8.6.2",
"punycode.js": "^2.3.1",
"qr-image": "^3.2.0",
"reflect-metadata": "^0.2.2",
@ -179,11 +179,11 @@
"snackbarjs": "^1.1.0",
"sortablejs": "^1.15.7",
"split.js": "^1.6.5",
"sql-formatter": "^15.8.0",
"sql-formatter": "^15.8.1",
"ssdeep.js": "0.0.3",
"stream-browserify": "^3.0.0",
"tesseract.js": "^6.0.1",
"ua-parser-js": "^1.0.41",
"tesseract.js": "^7.0.0",
"ua-parser-js": "^2.0.10",
"unorm": "^1.6.0",
"url": "^0.11.4",
"utf8": "^3.0.0",

View File

@ -49,6 +49,7 @@
"Escape Unicode Characters",
"Unescape Unicode Characters",
"Normalise Unicode",
"Escape Smart Characters",
"To Quoted Printable",
"From Quoted Printable",
"To Punycode",
@ -118,6 +119,7 @@
"GOST Verify",
"GOST Key Wrap",
"GOST Key Unwrap",
"ROR13",
"ROT13",
"ROT13 Brute Force",
"ROT47",
@ -239,6 +241,7 @@
"Bit shift right",
"Rotate left",
"Rotate right",
"ROR13",
"ROT13",
"ROT8000"
]
@ -304,6 +307,7 @@
"Diff",
"Remove whitespace",
"Remove null bytes",
"Remove ANSI Escape Codes",
"To Upper case",
"To Lower case",
"Swap case",

View File

@ -58,3 +58,66 @@ fs.writeFileSync(
code
);
console.log("Written operation index.");
// find all test files
const testsDir = path.join(process.cwd() + "/tests/operations/tests/");
const testObjs = [];
fs.readdirSync(testsDir).forEach(file => {
if (!file.endsWith(".mjs")) return;
testObjs.push(file.split(".mjs")[0]);
});
// Construct test index file
code = `/**
* THIS FILE IS AUTOMATICALLY GENERATED BY src/core/config/scripts/generateOpsIndex.mjs
*
* @author john [john19696@protonmail.com]
* @author tlwr [toby@toby.codes]
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright ${new Date().getUTCFullYear()}
* @license Apache-2.0
*/
import {
setLongTestFailure,
logTestReport,
} from "../lib/utils.mjs";
import "../lib/wasmFetchPolyfill.mjs";
import TestRegister from "../lib/TestRegister.mjs";
`;
testObjs.forEach(obj => {
if (obj !== "SplitColourChannels")
code += `import "./tests/${obj}.mjs";\n`;
else
code += `// Cannot test operations that use the File type yet
// import "./tests/SplitColourChannels.mjs";\n`;
});
code += `
const testStatus = {
allTestsPassing: true,
counts: {
total: 0,
}
};
setLongTestFailure();
const logOpsTestReport = logTestReport.bind(null, testStatus);
(async function() {
const results = await TestRegister.runTests();
logOpsTestReport(results);
})();
`;
// Write tests file
fs.writeFileSync(
path.join(testsDir, "../index.mjs"),
code
);
console.log("Written operation tests index.");

View File

@ -23,7 +23,7 @@ if (!fs.existsSync(dir)) {
console.log("Example> node --experimental-modules src/core/config/scripts/newOperation.mjs");
process.exit(1);
}
const testDir = path.join(process.cwd() + "/tests/operations/tests/");
const ioTypes = ["string", "byteArray", "number", "html", "ArrayBuffer", "BigNumber", "JSON", "File", "List<File>"];
const schema = {
@ -123,6 +123,30 @@ prompt.get(schema, (err, result) => {
return txt.charAt(0).toUpperCase() + txt.substr(1);
}).replace(/[\s-()./]/g, "");
const testTemplate = `/**
* ${moduleName} tests
*
* @author ${result.authorName} [${result.authorEmail}]
* @copyright Crown Copyright ${(new Date()).getFullYear()}
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "${result.opName}: test",
input: "Example input",
expectedOutput: "Expected output",
recipeConfig: [
{
op: "${result.opName}",
args: [],
},
],
},
]);
`;
const template = `/**
* @author ${result.authorName} [${result.authorEmail}]
@ -218,13 +242,16 @@ export default ${moduleName};
}
fs.writeFileSync(filename, template);
const testFilename = path.join(testDir, `./${moduleName}.mjs`);
fs.writeFileSync(testFilename, testTemplate);
console.log(`\nOperation template written to ${colors.green(filename)}`);
console.log(`\nOperation test template written to ${colors.green(testFilename)}`);
console.log(`\nNext steps:
1. Add your operation to ${colors.green("src/core/config/Categories.json")}
2. Write your operation code.
3. Write tests in ${colors.green("tests/operations/tests/")}
2. Write your operation code in ${colors.green(filename)}
3. Write your operation test code in ${colors.green(testFilename)}
4. Run ${colors.cyan("npm run lint")} and ${colors.cyan("npm run test")}
5. Submit a Pull Request to get your operation added to the official CyberChef repository.`);
});

View File

@ -39,41 +39,46 @@ class AESDecrypt extends Operation {
"value": "",
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
},
{
"name": "IV Length",
"type": "number",
"value": 16
},
{
"name": "Mode",
"type": "argSelector",
"value": [
{
name: "CBC",
off: [5, 6]
off: [6, 7]
},
{
name: "CFB",
off: [5, 6]
off: [6, 7]
},
{
name: "OFB",
off: [5, 6]
off: [6, 7]
},
{
name: "CTR",
off: [5, 6]
off: [6, 7]
},
{
name: "GCM",
on: [5, 6]
on: [6, 7]
},
{
name: "ECB",
off: [5, 6]
off: [6, 7]
},
{
name: "CBC/NoPadding",
off: [5, 6]
off: [6, 7]
},
{
name: "ECB/NoPadding",
off: [5, 6]
off: [6, 7]
}
]
},
@ -98,6 +103,26 @@ class AESDecrypt extends Operation {
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
},
{
"name": "IV from input",
"type": "argSelector",
"value": [
{
name: "Off",
on: [1],
off: [2]
},
{
name: "From start",
on: [2],
off: [1]
}, {
name: "From end",
on: [2],
off: [1]
}
]
}
];
}
@ -110,14 +135,18 @@ class AESDecrypt extends Operation {
* @throws {OperationError} if cannot decrypt input or invalid key length
*/
run(input, args) {
let iv;
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteString(args[1].string, args[1].option),
mode = args[2].split("/")[0],
noPadding = args[2].endsWith("NoPadding"),
inputType = args[3],
outputType = args[4],
gcmTag = Utils.convertToByteString(args[5].string, args[5].option),
aad = Utils.convertToByteString(args[6].string, args[6].option);
ivLength = args[2],
mode = args[3].split("/")[0],
noPadding = args[3].endsWith("NoPadding"),
inputType = args[4],
outputType = args[5],
gcmTag = Utils.convertToByteString(args[6].string, args[6].option),
aad = Utils.convertToByteString(args[7].string, args[7].option),
ivFromInput = args[8];
if ([16, 24, 32].indexOf(key.length) < 0) {
throw new OperationError(`Invalid key length: ${key.length} bytes
@ -130,11 +159,27 @@ The following algorithms will be used based on the size of the key:
input = Utils.convertToByteString(input, inputType);
if (ivFromInput !== "Off") {
if (input.length <= ivLength) {
throw new OperationError(`Input is too short to contain an IV of ${ivLength} bytes.`);
}
if (ivFromInput === "From start") {
iv = input.substr(0, ivLength);
input = input.substr(ivLength);
} else {
iv = input.substr(input.length - ivLength);
input = input.substr(0, input.length - ivLength);
}
} else {
iv = Utils.convertToByteString(args[1].string, args[1].option);
}
const decipher = forge.cipher.createDecipher("AES-" + mode, key);
/* Allow for a "no padding" mode */
if (noPadding) {
decipher.mode.unpad = function(output, options) {
decipher.mode.unpad = function (output, options) {
return true;
};
}

View File

@ -8,6 +8,7 @@ import Operation from "../Operation.mjs";
import Utils from "../Utils.mjs";
import forge from "node-forge";
import OperationError from "../errors/OperationError.mjs";
import { toHexFast } from "../lib/Hex.mjs";
/**
* AES Encrypt operation
@ -92,6 +93,11 @@ class AESEncrypt extends Operation {
"type": "toggleString",
"value": "",
"toggleValues": ["Hex", "UTF8", "Latin1", "Base64"]
},
{
"name": "Include IV in output",
"type": "option",
"value": ["Off", "Prepend", "Append"]
}
];
}
@ -107,10 +113,11 @@ class AESEncrypt extends Operation {
const key = Utils.convertToByteString(args[0].string, args[0].option),
iv = Utils.convertToByteString(args[1].string, args[1].option),
mode = args[2].split("/")[0],
noPadding = args[2].endsWith("NoPadding"),
noPadding = args[2].endsWith("NoPadding"),
inputType = args[3],
outputType = args[4],
aad = Utils.convertToByteString(args[5].string, args[5].option);
aad = Utils.convertToByteString(args[5].string, args[5].option),
includeIV = args[6];
if ([16, 24, 32].indexOf(key.length) < 0) {
throw new OperationError(`Invalid key length: ${key.length} bytes
@ -133,26 +140,34 @@ The following algorithms will be used based on the size of the key:
additionalData: mode === "GCM" ? aad : undefined
});
if (noPadding) {
cipher.mode.pad = function(output, options) {
cipher.mode.pad = function (output, options) {
return true;
};
}
cipher.update(forge.util.createBuffer(input));
cipher.finish();
let output = cipher.output.getBytes();
if (includeIV === "Prepend") {
output = iv + output;
} else if (includeIV === "Append") {
output = output + iv;
}
if (outputType === "Hex") {
output = toHexFast(Utils.strToByteArray(output));
if (mode === "GCM") {
return cipher.output.toHex() + "\n\n" +
return output + "\n\n" +
"Tag: " + cipher.mode.tag.toHex();
}
return cipher.output.toHex();
} else {
if (mode === "GCM") {
return cipher.output.getBytes() + "\n\n" +
"Tag: " + cipher.mode.tag.getBytes();
}
return cipher.output.getBytes();
} else if (mode === "GCM") {
return output + "\n\n" +
"Tag: " + cipher.mode.tag.getBytes();
}
return output;
}
}

View File

@ -5,6 +5,7 @@
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import cptable from "codepage";
import {CHR_ENC_CODE_PAGES} from "../lib/ChrEnc.mjs";
@ -48,6 +49,9 @@ class DecodeText extends Operation {
*/
run(input, args) {
const format = CHR_ENC_CODE_PAGES[args[0]];
if (!format) {
throw new OperationError("Invalid encoding");
}
return cptable.utils.decode(format, new Uint8Array(input));
}

View File

@ -5,6 +5,7 @@
*/
import Operation from "../Operation.mjs";
import OperationError from "../errors/OperationError.mjs";
import cptable from "codepage";
import {CHR_ENC_CODE_PAGES} from "../lib/ChrEnc.mjs";
@ -48,6 +49,9 @@ class EncodeText extends Operation {
*/
run(input, args) {
const format = CHR_ENC_CODE_PAGES[args[0]];
if (!format) {
throw new OperationError("Invalid encoding");
}
const encoded = cptable.utils.encode(format, input);
return new Uint8Array(encoded).buffer;
}

View File

@ -0,0 +1,129 @@
/**
* @author HarelKatz [github.com/HarelKatz]
* @copyright Crown Copyright 2026
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
/**
* Escape Smart Characters operation
*/
class EscapeSmartCharacters extends Operation {
/**
* EscapeSmartCharacters constructor
*/
constructor() {
super();
this.name = "Escape Smart Characters";
this.module = "Default";
this.description = "Converts smart (typographic) Unicode characters — e.g. smart quotes, em/en dashes, ellipses, ©, ®, ™, arrows — into their plain ASCII equivalents.<br><br>Characters with no ASCII mapping (e.g. <code>☣</code>) are handled according to the 'Unmappable characters' option.<br><br>e.g. <code>“Hello” — world…</code> becomes <code>\"Hello\" -- world...</code>";
this.infoURL = "";
this.inputType = "string";
this.outputType = "string";
this.args = [
{
name: "Unmappable characters",
type: "option",
value: ["Include", "Remove", "Replace with '.'"]
}
];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const [unmappable] = args;
let result = "";
for (const ch of input) {
if (ch.codePointAt(0) < 128) {
result += ch;
} else if (Object.prototype.hasOwnProperty.call(SMART_MAP, ch)) {
result += SMART_MAP[ch];
} else {
switch (unmappable) {
case "Remove":
break;
case "Replace with '.'":
result += ".";
break;
case "Include":
default:
result += ch;
break;
}
}
}
return result;
}
}
const SMART_MAP = {
// Smart double quotes
"“": "\"", // “ left double quotation mark
"”": "\"", // ” right double quotation mark
"„": "\"", // „ double low-9 quotation mark
"‟": "\"", // ‟ double high-reversed-9 quotation mark
"″": "\"", // ″ double prime
// Smart single quotes / apostrophes
"": "'", // left single quotation mark
"": "'", // right single quotation mark / apostrophe
"": "'", // single low-9 quotation mark
"": "'", // single high-reversed-9 quotation mark
"": "'", // prime
// Dashes & hyphens
"": "-", // hyphen
"": "-", // non-breaking hyphen
"": "-", // figure dash
"": "-", // en dash
"—": "--", // — em dash
"―": "--", // ― horizontal bar
// Ellipsis
"…": "...", // …
// Trademark / copyright symbols
"©": "(c)", // ©
"®": "(r)", // ®
"™": "(tm)", // ™
// Arrows
"←": "<--", // ←
"→": "-->", // →
"↑": "^", // ↑
"↓": "v", // ↓
"↔": "<->", // ↔
"⇐": "<==", // ⇐
"⇒": "==>", // ⇒
"⇔": "<=>", // ⇔
// Guillemets
"«": "<<", // «
"»": ">>", // »
"": "<", //
"": ">", //
// Math & misc symbols
"×": "x", // ×
"÷": "/", // ÷
"±": "+/-", // ±
"•": "*", // •
"·": ".", // ·
// Non-ASCII spaces
"\u00A0": " ", // NBSP
"\u2002": " ", // en space
"\u2003": " ", // em space
"\u2009": " ", // thin space
"\u200A": " " // hair space
};
export default EscapeSmartCharacters;

View File

@ -5,7 +5,7 @@
*/
import Operation from "../Operation.mjs";
import UAParser from "ua-parser-js";
import { UAParser } from "ua-parser-js";
/**
* Parse User Agent operation

View File

@ -0,0 +1,83 @@
/**
* ROR13 Hash operation (Windows API hashing convention)
* @author fufu_btw
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
/**
* Implements a ROR13 hash used for API name hashing techniques.
*/
class ROR13 extends Operation {
/**
* Constructor
*/
constructor() {
super();
this.name = "ROR13";
this.module = "Default";
this.description = "Computes a ROR13 hash used in API hashing techniques.";
this.infoURL = "";
this.inputType = "byteArray";
this.outputType = "string";
this.args = [];
}
/**
* Rotate right (32-bit)
*
* @param {number} value - input value
* @param {number} bits - rotation bits
* @returns {number} rotated value
*/
ror(value, bits) {
return ((value >>> bits) | (value << (32 - bits))) >>> 0;
}
/**
* Execute ROR13 hash
*
* @param {byteArray} input - input bytes
* @param {Object[]} args - operation arguments
* @returns {string} hex hash
*/
run(input, args) {
let hash = 0;
for (let i = 0; i < input.length; i++) {
const chr = input[i] & 0xFF;
hash = this.ror(hash, 13);
hash = (hash + chr) >>> 0;
}
return "0x" + hash.toString(16).padStart(8, "0").toUpperCase();
}
/**
* Highlight input
*
* @param {Object[]} pos
* @param {Object[]} args
* @returns {Object[]}
*/
highlight(pos, args) {
return pos;
}
/**
* Reverse highlight
*
* @param {Object[]} pos
* @param {Object[]} args
* @returns {Object[]}
*/
highlightReverse(pos, args) {
return pos;
}
}
export default ROR13;

View File

@ -0,0 +1,41 @@
/**
* @author Louis-Ladd [lewisharshman1@gmail.com]
* @copyright Crown Copyright 2025
* @license Apache-2.0
*/
import Operation from "../Operation.mjs";
/**
* Remove ANSI Escape Codes operation
*/
class RemoveANSIEscapeCodes extends Operation {
/**
* RemoveANSIEscapeCodes constructor
*/
constructor() {
super();
this.name = "Remove ANSI Escape Codes";
this.module = "Default";
this.description = "Removes ANSI Escape Codes.";
this.infoURL = "https://wikipedia.org/wiki/ANSI_escape_code";
this.inputType = "string";
this.outputType = "string";
this.args = [];
}
/**
* @param {string} input
* @param {Object[]} args
* @returns {string}
*/
run(input, args) {
const ansiRegex = /\x1B\[[0-?]*[ -/]*[@-~]/g;
return input.replace(ansiRegex, "");
}
}
export default RemoveANSIEscapeCodes;

View File

@ -166,6 +166,7 @@ class HTMLIngredient {
id="${this.id}"
tabindex="${this.tabIndex}"
arg-name="${this.name}"
data-target="${this.target}"
${this.disabled ? "disabled" : ""}>`;
for (i = 0; i < this.value.length; i++) {
if ((m = this.value[i].name.match(/\[([a-z0-9 -()^]+)\]/i))) {

View File

@ -1,4 +1,4 @@
import sm from "sitemap";
import { SitemapStream, streamToPromise } from "sitemap";
import OperationConfig from "../../core/config/OperationConfig.json" with { type: "json" };
/**
@ -11,7 +11,7 @@ import OperationConfig from "../../core/config/OperationConfig.json" with { type
const baseUrl = "https://gchq.github.io/CyberChef/";
const smStream = new sm.SitemapStream({});
const smStream = new SitemapStream({});
smStream.write({
url: baseUrl,
@ -28,6 +28,6 @@ for (const op in OperationConfig) {
}
smStream.end();
sm.streamToPromise(smStream).then(
streamToPromise(smStream).then(
(buffer) => console.log(buffer.toString()), // eslint-disable-line no-console
);

View File

@ -487,11 +487,19 @@ class RecipeWaiter {
* @param {HTMLElement} op
*/
triggerArgEvents(op) {
// Trigger populateOption and argSelector events
// Trigger argSelector events and populateOption events only where the target is empty.
// When loading a saved recipe, arguments are populated before this method is called, so
// re-triggering populateOption events would overwrite saved custom values with defaults.
const args = op.querySelectorAll(".arg");
const triggerableOptions = op.querySelectorAll(".populate-option, .arg-selector");
const evt = new Event("change", {bubbles: true});
if (triggerableOptions.length) {
for (const el of triggerableOptions) {
if (el.classList.contains("populate-option")) {
const target = args[el.getAttribute("data-target")];
if (target && target.value !== "") continue;
}
el.dispatchEvent(evt);
}
}

View File

@ -30,8 +30,8 @@ module.exports = {
testOp(browser, "A1Z26 Cipher Decode", "20 5 19 20 15 21 20 16 21 20", "testoutput");
testOp(browser, "A1Z26 Cipher Encode", "test input", "20 5 19 20 9 14 16 21 20");
testOp(browser, "ADD", "test input", "Ê»ÉÊv¿ÄÆËÊ", [{ "option": "Hex", "string": "56" }]);
testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }]);
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex"]);
testOp(browser, "AES Decrypt", "b443f7f7c16ac5396a34273f6f639caa", "test output", [{ "option": "Hex", "string": "00112233445566778899aabbccddeeff" }, { "option": "Hex", "string": "00000000000000000000000000000000" }, 16, "CBC", "Hex", "Raw", { "option": "Hex", "string": "" }, { "option": "Hex", "string": "" }, "Off"]);
testOp(browser, "AES Encrypt", "test input", "e42eb8fbfb7a98fff061cd2c1a794d92", [{"option": "Hex", "string": "00112233445566778899aabbccddeeff"}, {"option": "Hex", "string": "00000000000000000000000000000000"}, "CBC", "Raw", "Hex", "Off"]);
testOp(browser, "AND", "test input", "4$04 $044", [{ "option": "Hex", "string": "34" }]);
testOp(browser, "Add line numbers", "test input", "1 test input");
testOp(browser, ["From Hex", "Add Text To Image", "SHA2"], Images.PNG_HEX, "50cdf8ea483c55564a091650c2bccb4586f919b721e5fe9d6a61660505b4346d6ebdb2ef0cf075a7728cd84cb26ea3e477b5bd86a94a49a27d79423994afb60a", [[], ["Chef", "Center", "Middle", 0, 0, 16, "Roboto"], []]);
@ -80,8 +80,8 @@ module.exports = {
testOpHtml(browser, "Bombe", "XTSYN WAEUG EZALY NRQIM AMLZX MFUOD AWXLY LZCUZ QOQBQ JLCPK NDDRW F", "table tr:last-child td:first-child", "ECG", ["3-rotor", "LEYJVCNIXWPBQMDRTAKZGFUHOS", "BDFHJLCPRTXVZNYEIWGAKMUSQO<W", "AJDKSIRUXBLHWTMCQGZNPYFVOE<F", "ESOVPZJAYQUIRHXLNFTGKDCMWB<K", "AY BR CU DH EQ FS GL IP JX KN MO TZ VW", "HELLO CYBER CHEFU SER", 0, true]);
testOp(browser, ["Bzip2 Compress", "To Hex"], "test input", "42 5a 68 39 31 41 59 26 53 59 cf 96 82 1d 00 00 03 91 80 40 00 02 21 4e 00 20 00 21 90 c2 10 c0 88 33 92 8e df 17 72 45 38 50 90 cf 96 82 1d");
testOp(browser, ["From Hex", "Bzip2 Decompress"], "425a68393141592653597b0884b7000003038000008200ce00200021a647a4218013709517c5dc914e14241ec2212dc0", "test_output", [[], [true]]);
// testOp(browser, "CBOR Decode", "test input", "test output");
// testOp(browser, "CBOR Encode", "test input", "test output");
testOp(browser, ["From Hex", "CBOR Decode"], "f9 3e 00", "1.5");
testOp(browser, ["CBOR Encode", "To Hex"], "1.5", "f9 3e 00");
testOp(browser, "CRC Checksum", "test input", "77c7", ["CRC-16"]);
testOp(browser, "CRC Checksum", "test input", "29822bc8", ["CRC-32"]);
testOp(browser, "CRC Checksum", "test input", "9d", ["CRC-8"]);
@ -278,11 +278,11 @@ module.exports = {
testOpHtml(browser, "Parse UDP", "04 89 00 35 00 2c 01 01", "tr:last-child td:last-child", "0x0101");
// testOp(browser, "Parse UNIX file permissions", "test input", "test_output");
// testOp(browser, "Parse URI", "test input", "test_output");
// testOp(browser, "Parse User Agent", "test input", "test_output");
testOp(browser, "Parse User Agent", "Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:47.0) Gecko/20100101 Firefox/47.0 ", /Architecture: amd64/);
// testOp(browser, "Parse X.509 certificate", "test input", "test_output");
testOpFile(browser, "Play Media", "files/mp3example.mp3", "audio", "");
// testOp(browser, "Power Set", "test input", "test_output");
// testOp(browser, "Protobuf Decode", "test input", "test_output");
testOp(browser, ["From Hex", "Protobuf Decode"], "0d1c0000001203596f751a024d65202b2a0a0a066162633132331200", /"1": "abc123"/, [[], ["", false, false]]);
// testOp(browser, "Pseudo-Random Number Generator", "test input", "test_output");
// testOp(browser, "RC2 Decrypt", "test input", "test_output");
// testOp(browser, "RC2 Encrypt", "test input", "test_output");

View File

@ -0,0 +1,48 @@
/**
* Regression tests for recipe loading behaviour.
*
* @author C85297 [95289555+C85297@users.noreply.github.com]
* @copyright Crown Copyright
* @license Apache-2.0
*/
const utils = require("./browserUtils.js");
module.exports = {
before: browser => {
browser
.resizeWindow(1280, 800)
.url(browser.launchUrl)
.useCss()
.waitForElementNotPresent("#preloader", 10000);
},
"Recipe load preserves populated arguments": browser => {
const inputFormat = "HH:mm:ss a MMM DD, YYYY ";
const input = "10:20:30 pm Sep 26, 2019 ";
utils.loadRecipe(
browser,
"Translate DateTime Format",
input,
[
"Standard date and time",
inputFormat,
"UTC",
"DD/MM/YYYY HH:mm:ss",
"UTC"
]
);
browser.execute(() => {
return Array.from(document.querySelectorAll("#rec-list li.operation .arg"))
.map(arg => arg.value);
}, [], function({value}) {
browser.expect(value[1]).to.equal(inputFormat);
});
},
after: browser => {
browser.end();
}
};

View File

@ -79,7 +79,46 @@ TestRegister.addApiTests([
string: "some iv some iv1",
option: "utf8",
},
ivLength: 16,
mode: "OFB",
inputType: "Hex",
outputType: "Raw",
gcmTag: {
option: "Hex",
string: ""
},
aad: {
option: "Hex",
string: ""
},
ivFromInput: "Off"
});
assert.equal(result.toString(), "a slightly longer sampleinput?");
}),
it("AES decrypt: IV from input", () => {
const result = AESDecrypt("4a123af235a507bbc9d5871721d61b98504d569a9a5a7847e2d78315fec7736f6d6520697620736f6d6520697631", {
key: {
string: "some longer key1",
option: "utf8",
},
iv: {
string: "",
option: "Hex",
},
ivLength: 16,
mode: "OFB",
inputType: "Hex",
outputType: "Raw",
gcmTag: {
option: "Hex",
string: ""
},
aad: {
option: "Hex",
string: ""
},
ivFromInput: "From end"
});
assert.equal(result.toString(), "a slightly longer sampleinput?");
}),

View File

@ -1,215 +0,0 @@
/* eslint no-console: 0 */
/**
* Test Runner
*
* For running the tests in the test register.
*
* @author tlwr [toby@toby.codes]
* @author n1474335 [n1474335@gmail.com]
* @copyright Crown Copyright 2017
* @license Apache-2.0
*/
import "../lib/wasmFetchPolyfill.mjs";
import { setLongTestFailure, logTestReport } from "../lib/utils.mjs";
import TestRegister from "../lib/TestRegister.mjs";
import "./tests/A1Z26CipherDecode.mjs";
import "./tests/AESKeyWrap.mjs";
import "./tests/AnalyseUUID.mjs";
import "./tests/AlternatingCaps.mjs";
import "./tests/AvroToJSON.mjs";
import "./tests/BaconCipher.mjs";
import "./tests/Base32.mjs";
import "./tests/Base45.mjs";
import "./tests/Base58.mjs";
import "./tests/Base62.mjs";
import "./tests/Base64.mjs";
import "./tests/Base85.mjs";
import "./tests/Base92.mjs";
import "./tests/BCD.mjs";
import "./tests/Bech32.mjs";
import "./tests/BitwiseOp.mjs";
import "./tests/BLAKE2b.mjs";
import "./tests/BLAKE2s.mjs";
import "./tests/BLAKE3.mjs";
import "./tests/Bombe.mjs";
import "./tests/BSON.mjs";
import "./tests/ByteRepr.mjs";
import "./tests/CaesarBoxCipher.mjs";
import "./tests/CaretMdecode.mjs";
import "./tests/CartesianProduct.mjs";
import "./tests/CBORDecode.mjs";
import "./tests/CBOREncode.mjs";
import "./tests/CetaceanCipherDecode.mjs";
import "./tests/CetaceanCipherEncode.mjs";
import "./tests/ChaCha.mjs";
import "./tests/ChangeIPFormat.mjs";
import "./tests/CharEnc.mjs";
import "./tests/Charts.mjs";
import "./tests/Ciphers.mjs";
import "./tests/CipherSaber2.mjs";
import "./tests/CMAC.mjs";
import "./tests/Code.mjs";
import "./tests/Colossus.mjs";
import "./tests/Comment.mjs";
import "./tests/Compress.mjs";
import "./tests/ConditionalJump.mjs";
import "./tests/ConvertCoordinateFormat.mjs";
import "./tests/ConvertLeetSpeak.mjs";
import "./tests/ConvertToNATOAlphabet.mjs";
import "./tests/CRCChecksum.mjs";
import "./tests/Crypt.mjs";
import "./tests/CSV.mjs";
import "./tests/DateTime.mjs";
import "./tests/DefangIP.mjs";
import "./tests/DisassembleARM.mjs";
import "./tests/DropNthBytes.mjs";
import "./tests/ECDSA.mjs";
import "./tests/ELFInfo.mjs";
import "./tests/Enigma.mjs";
import "./tests/ExtractAudioMetadata.mjs";
import "./tests/ExtractEmailAddresses.mjs";
import "./tests/ExtractHashes.mjs";
import "./tests/ExtractIPAddresses.mjs";
import "./tests/Fernet.mjs";
import "./tests/Float.mjs";
import "./tests/FileTree.mjs";
import "./tests/FletcherChecksum.mjs";
import "./tests/Fork.mjs";
import "./tests/FromDecimal.mjs";
import "./tests/GenerateAllChecksums.mjs";
import "./tests/GenerateAllHashes.mjs";
import "./tests/GenerateDeBruijnSequence.mjs";
import "./tests/GenerateQRCode.mjs";
import "./tests/GetAllCasings.mjs";
import "./tests/GOST.mjs";
import "./tests/Gunzip.mjs";
import "./tests/Gzip.mjs";
import "./tests/Hash.mjs";
import "./tests/HASSH.mjs";
import "./tests/HaversineDistance.mjs";
import "./tests/Hex.mjs";
import "./tests/Hexdump.mjs";
import "./tests/HKDF.mjs";
import "./tests/Image.mjs";
import "./tests/IndexOfCoincidence.mjs";
import "./tests/JA3Fingerprint.mjs";
import "./tests/JA4.mjs";
import "./tests/JA3SFingerprint.mjs";
import "./tests/Jsonata.mjs";
import "./tests/JSONBeautify.mjs";
import "./tests/JSONMinify.mjs";
import "./tests/JSONtoCSV.mjs";
import "./tests/Jump.mjs";
import "./tests/JWK.mjs";
import "./tests/JWTDecode.mjs";
import "./tests/JWTSign.mjs";
import "./tests/JWTVerify.mjs";
import "./tests/LevenshteinDistance.mjs";
import "./tests/Lorenz.mjs";
import "./tests/LS47.mjs";
import "./tests/LuhnChecksum.mjs";
import "./tests/LZNT1Decompress.mjs";
import "./tests/LZString.mjs";
import "./tests/Magic.mjs";
import "./tests/Media.mjs";
import "./tests/MIMEDecoding.mjs";
import "./tests/Modhex.mjs";
import "./tests/MorseCode.mjs";
import "./tests/MS.mjs";
import "./tests/MultipleBombe.mjs";
import "./tests/MurmurHash3.mjs";
import "./tests/NetBIOS.mjs";
import "./tests/NormaliseUnicode.mjs";
import "./tests/NTLM.mjs";
import "./tests/OTP.mjs";
import "./tests/ParseEthernetFrame.mjs";
import "./tests/ParseIPv4Header.mjs";
import "./tests/ParseIPRange.mjs";
import "./tests/ParseObjectIDTimestamp.mjs";
import "./tests/ParseQRCode.mjs";
import "./tests/ParseSSHHostKey.mjs";
import "./tests/ParseTCP.mjs";
import "./tests/ParseTLSRecord.mjs";
import "./tests/ParseTLV.mjs";
import "./tests/ParseUDP.mjs";
import "./tests/PEMtoHex.mjs";
import "./tests/PGP.mjs";
import "./tests/PHP.mjs";
import "./tests/ParityBit.mjs";
import "./tests/PHPSerialize.mjs";
import "./tests/PowerSet.mjs";
import "./tests/Protobuf.mjs";
import "./tests/PubKeyFromCert.mjs";
import "./tests/PubKeyFromPrivKey.mjs";
import "./tests/Rabbit.mjs";
import "./tests/RAKE.mjs";
import "./tests/Regex.mjs";
import "./tests/Register.mjs";
import "./tests/RegularExpression.mjs";
import "./tests/RenderMarkdown.mjs";
import "./tests/RisonEncodeDecode.mjs";
import "./tests/Rotate.mjs";
import "./tests/RSA.mjs";
import "./tests/Salsa20.mjs";
import "./tests/XSalsa20.mjs";
import "./tests/SeqUtils.mjs";
import "./tests/SetDifference.mjs";
import "./tests/SetIntersection.mjs";
import "./tests/SetUnion.mjs";
import "./tests/Shuffle.mjs";
import "./tests/SIGABA.mjs";
import "./tests/SM2.mjs";
import "./tests/SM4.mjs";
import "./tests/RC6.mjs";
// import "./tests/SplitColourChannels.mjs"; // Cannot test operations that use the File type yet
import "./tests/SQLBeautify.mjs";
import "./tests/StrUtils.mjs";
import "./tests/StripIPv4Header.mjs";
import "./tests/StripTCPHeader.mjs";
import "./tests/StripUDPHeader.mjs";
import "./tests/Subsection.mjs";
import "./tests/SwapCase.mjs";
import "./tests/SymmetricDifference.mjs";
import "./tests/TakeNthBytes.mjs";
import "./tests/Template.mjs";
import "./tests/TextEncodingBruteForce.mjs";
import "./tests/TextIntegerConverter.mjs";
import "./tests/ToFromInsensitiveRegex.mjs";
import "./tests/TranslateDateTimeFormat.mjs";
import "./tests/Typex.mjs";
import "./tests/UnescapeString.mjs";
import "./tests/Unicode.mjs";
import "./tests/Wrap.mjs";
import "./tests/URLEncodeDecode.mjs";
import "./tests/RSA.mjs";
import "./tests/CBOREncode.mjs";
import "./tests/CBORDecode.mjs";
import "./tests/JA3Fingerprint.mjs";
import "./tests/JA3SFingerprint.mjs";
import "./tests/HASSH.mjs";
import "./tests/JSONtoYAML.mjs";
// Cannot test operations that use the File type yet
// import "./tests/SplitColourChannels.mjs";
import "./tests/YARA.mjs";
import "./tests/ParseCSR.mjs";
import "./tests/XXTEA.mjs";
const testStatus = {
allTestsPassing: true,
counts: {
total: 0,
},
};
setLongTestFailure();
const logOpsTestReport = logTestReport.bind(null, testStatus);
(async function () {
const results = await TestRegister.runTests();
logOpsTestReport(results);
})();

View File

@ -68,6 +68,32 @@ TestRegister.addTests([
},
],
},
{
name: "Encode text: empty encoding",
input: "hello",
expectedOutput: "Invalid encoding",
recipeConfig: [
{
"op": "Encode text",
"args": [""]
},
],
},
{
name: "Decode text: empty encoding",
input: "68 65 6c 6c 6f",
expectedOutput: "Invalid encoding",
recipeConfig: [
{
"op": "From Hex",
"args": ["Space"]
},
{
"op": "Decode text",
"args": [""]
},
],
},
{
name: "Generate Base64 Windows PowerShell",
input: "ZABpAHIAIAAiAGMAOgBcAHAAcgBvAGcAcgBhAG0AIABmAGkAbABlAHMAIgAgAA==",

View File

@ -74,7 +74,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""},
"CBC", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -90,7 +91,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00000000000000000000000000000000"},
"CBC", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -106,7 +108,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00000000000000000000000000000000"},
"CTR", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -122,7 +125,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
"CBC", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -138,7 +142,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
"CFB", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -154,7 +159,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
"OFB", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -170,7 +176,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
"CTR", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -186,7 +193,8 @@ The following algorithms will be used based on the size of the key:
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
"ECB", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -204,7 +212,8 @@ Tag: 16a3e732a605cc9ca29108f742ca0743`,
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
"GCM", "Raw", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -222,7 +231,8 @@ Tag: 3b5378917f67b0aade9891fc6c291646`,
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "ffeeddccbbaa99887766554433221100"},
"GCM", "Raw", "Hex",
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -238,7 +248,8 @@ Tag: 3b5378917f67b0aade9891fc6c291646`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CBC", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -254,7 +265,8 @@ Tag: 3b5378917f67b0aade9891fc6c291646`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CFB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -270,7 +282,8 @@ Tag: 3b5378917f67b0aade9891fc6c291646`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"OFB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -286,7 +299,8 @@ Tag: 3b5378917f67b0aade9891fc6c291646`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CTR", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -304,7 +318,8 @@ Tag: 70fad2ca19412c20f40fd06918736e56`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -322,7 +337,8 @@ Tag: 61cc4b70809452b0b3e38f913fa0a109`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -338,7 +354,8 @@ Tag: 61cc4b70809452b0b3e38f913fa0a109`,
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -354,7 +371,8 @@ Tag: 61cc4b70809452b0b3e38f913fa0a109`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CBC", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -370,7 +388,8 @@ Tag: 61cc4b70809452b0b3e38f913fa0a109`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CFB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -386,7 +405,8 @@ Tag: 61cc4b70809452b0b3e38f913fa0a109`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"OFB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -402,7 +422,8 @@ Tag: 61cc4b70809452b0b3e38f913fa0a109`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CTR", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -420,7 +441,8 @@ Tag: 86db597d5302595223cadbd990f1309b`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -438,7 +460,8 @@ Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -454,7 +477,8 @@ Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -470,7 +494,8 @@ Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CBC", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -486,7 +511,8 @@ Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CFB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -502,7 +528,8 @@ Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"OFB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -518,7 +545,8 @@ Tag: aeedf3e6ca4201577c0cf3e9ce58159d`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"CTR", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -536,7 +564,8 @@ Tag: 821b1e5f32dad052e502775a523d957a`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -554,7 +583,8 @@ Tag: a8f04c4d93bbef82bef61a103371aef9`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -570,7 +600,46 @@ Tag: a8f04c4d93bbef82bef61a103371aef9`,
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
},
{
name: "AES Encrypt: AES-256-GCM, Binary, AAD, prepend IV to output",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: `1748e7179bd56570d51fa4ba287cc3e51287f188ad4d7ab0d9ff69b3c29cb11f861389532d8cb9337181da2e8cfc74a84927e8c0dd7a28a32fd485afe694259a63c199b199b95edd87c7aa95329feac340f2b78b72956a85f367044d821766b1b7135815571df44900695f1518cf3ae38ecb650f
Tag: a8f04c4d93bbef82bef61a103371aef9`,
recipeConfig: [
{
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "UTF8", "string": "additional data"},
"Prepend"
]
}
],
},
{
name: "AES Encrypt: AES-256-GCM, Binary, AAD, append IV to output",
input: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
expectedOutput: `1287f188ad4d7ab0d9ff69b3c29cb11f861389532d8cb9337181da2e8cfc74a84927e8c0dd7a28a32fd485afe694259a63c199b199b95edd87c7aa95329feac340f2b78b72956a85f367044d821766b1b7135815571df44900695f1518cf3ae38ecb650f1748e7179bd56570d51fa4ba287cc3e5
Tag: a8f04c4d93bbef82bef61a103371aef9`,
recipeConfig: [
{
"op": "AES Encrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
"GCM", "Hex", "Hex",
{"option": "UTF8", "string": "additional data"},
"Append"
]
}
],
@ -776,9 +845,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""},
16,
"CBC", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -793,9 +864,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00000000000000000000000000000000"},
16,
"CBC", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -810,9 +883,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00000000000000000000000000000000"},
16,
"CTR", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -827,9 +902,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
16,
"CBC", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -844,9 +921,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
16,
"CFB", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -861,9 +940,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
16,
"OFB", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -878,9 +959,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
16,
"CTR", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -895,9 +978,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
16,
"ECB", "Hex", "Raw",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -912,9 +997,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": ""},
16,
"GCM", "Hex", "Raw",
{"option": "Hex", "string": "16a3e732a605cc9ca29108f742ca0743"},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -929,9 +1016,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "00112233445566778899aabbccddeeff"},
{"option": "Hex", "string": "ffeeddccbbaa99887766554433221100"},
16,
"GCM", "Hex", "Raw",
{"option": "Hex", "string": "3b5378917f67b0aade9891fc6c291646"},
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -946,9 +1035,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CBC", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -963,9 +1054,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CFB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -980,9 +1073,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"OFB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -997,9 +1092,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CTR", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1014,9 +1111,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "70fad2ca19412c20f40fd06918736e56"},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1031,9 +1130,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "61cc4b70809452b0b3e38f913fa0a109"},
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -1048,9 +1149,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "51e201d463698ef5f717f71f5b4712af"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1065,9 +1168,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CBC", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1082,9 +1187,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CFB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1099,9 +1206,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"OFB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1116,9 +1225,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CTR", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1133,9 +1244,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "86db597d5302595223cadbd990f1309b"},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1150,9 +1263,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "aeedf3e6ca4201577c0cf3e9ce58159d"},
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -1167,9 +1282,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "6801ed503c9d96ee5f9d78b07ab1b295dba3c2adf81c7816"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1184,9 +1301,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CBC", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1201,9 +1320,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CFB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1218,9 +1339,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"OFB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1235,9 +1358,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"CTR", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1252,9 +1377,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "821b1e5f32dad052e502775a523d957a"},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
@ -1269,9 +1396,11 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "a8f04c4d93bbef82bef61a103371aef9"},
{"option": "UTF8", "string": "additional data"}
{"option": "UTF8", "string": "additional data"},
"Off"
]
}
],
@ -1286,9 +1415,106 @@ The following algorithms will be used based on the size of the key:
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": "1748e7179bd56570d51fa4ba287cc3e5"},
16,
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""}
{"option": "Hex", "string": ""},
"Off"
]
}
],
},
{
name: "AES Decrypt: IV from input, with too short input",
input: "1748e7179bd56570d51fa4ba287cc3e5",
expectedOutput: "Input is too short to contain an IV of 16 bytes.",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": ""},
16,
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""},
"From start"
]
}
],
},
{
name: "AES Decrypt: AES-256-ECB with IV from input start, Binary",
input: "1748e7179bd56570d51fa4ba287cc3e57e8521ba3f356ef692a51841807e141464aadc07bbc0ef2b628b8745bae356d245682a220688afca7be987b60cb120681ed42680ee93a67065619a3beaac11111a6cd88a6afa9e367722cb57df343f8548f2d691b295184da4ed5f3b763aaa8558502cb348ab58e81986337096e90caa",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": ""},
16,
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""},
"From start"
]
}
],
},
{
name: "AES Decrypt: AES-256-ECB with IV from input end, Binary",
input: "7e8521ba3f356ef692a51841807e141464aadc07bbc0ef2b628b8745bae356d245682a220688afca7be987b60cb120681ed42680ee93a67065619a3beaac11111a6cd88a6afa9e367722cb57df343f8548f2d691b295184da4ed5f3b763aaa8558502cb348ab58e81986337096e90caa1748e7179bd56570d51fa4ba287cc3e5",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": ""},
16,
"ECB", "Hex", "Hex",
{"option": "Hex", "string": ""},
{"option": "Hex", "string": ""},
"From end"
]
}
],
},
{
name: "AES Decrypt: AES-256-GCM with IV from input start, Binary, AAD",
input: "1748e7179bd56570d51fa4ba287cc3e51287f188ad4d7ab0d9ff69b3c29cb11f861389532d8cb9337181da2e8cfc74a84927e8c0dd7a28a32fd485afe694259a63c199b199b95edd87c7aa95329feac340f2b78b72956a85f367044d821766b1b7135815571df44900695f1518cf3ae38ecb650f",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": ""},
16,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "a8f04c4d93bbef82bef61a103371aef9"},
{"option": "UTF8", "string": "additional data"},
"From start"
]
}
],
},
{
name: "AES Decrypt: AES-256-GCM with 12-byte IV from input start, Binary, AAD",
input: "1748e7179bd56570d51fa4ba623c81f4605da9ac3df29c67c43abe4aad5230dca82a98ab31f042fe871b81a0a1e8b8af41044d46f627828e7d11eca2d04ac27f4e7c7c9a20da87854df9868a2ddbd67d85f7db92f9ff1272cfb7955a2d279dbe715965011fddf6e730e79e7b22f89817",
expectedOutput: "7a0e643132750e96d805d11e9e48e281fa39a41039286423cc1c045e5442b40bf1c3f2822bded3f9c8ef11cb25da64dda9c7ab87c246bd305385150c98f31465c2a6180fe81d31ea289b916504d5a12e1de26cb10adba84a0cb0c86f94bc14bc554f3018",
recipeConfig: [
{
"op": "AES Decrypt",
"args": [
{"option": "Hex", "string": "2d767f6e9333d1c77581946e160b2b7368c2cdd5e2b80f04ca09d64e02afbfe1"},
{"option": "Hex", "string": ""},
12,
"GCM", "Hex", "Hex",
{"option": "Hex", "string": "c311c9144f8ae145ec46e2c69179a4b7"},
{"option": "UTF8", "string": "additional data"},
"From start"
]
}
],

View File

@ -0,0 +1,132 @@
/**
* Escape Smart Characters tests
*
* @author HarelKatz [github.com/HarelKatz]
* @copyright Crown Copyright 2026
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
"name": "Escape Smart Characters: smart quotes and apostrophes",
"input": "“Hello,” she said, yes.",
"expectedOutput": "\"Hello,\" she said, 'yes.'",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: em dash, en dash and ellipsis",
"input": "page 13 — wait…",
"expectedOutput": "page 1-3 -- wait...",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: trademark symbols",
"input": "Foo© Bar® Baz™",
"expectedOutput": "Foo(c) Bar(r) Baz(tm)",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: arrows and guillemets",
"input": "← → ↔ ⇒ « »",
"expectedOutput": "<-- --> <-> ==> << >>",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: math and misc",
"input": "3 × 4 ÷ 2 = 6, ±0.5 • item",
"expectedOutput": "3 x 4 / 2 = 6, +/-0.5 * item",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: NBSP becomes regular space",
"input": "a bc",
"expectedOutput": "a b c",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: unmappable Include preserves char",
"input": "warning: ☣ hazard",
"expectedOutput": "warning: ☣ hazard",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: unmappable Remove drops char",
"input": "warning: ☣ hazard",
"expectedOutput": "warning: hazard",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Remove"]
}
]
},
{
"name": "Escape Smart Characters: unmappable Replace substitutes dot",
"input": "warning: ☣ hazard",
"expectedOutput": "warning: . hazard",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Replace with '.'"]
}
]
},
{
"name": "Escape Smart Characters: pure ASCII passes through",
"input": "hello world! 123",
"expectedOutput": "hello world! 123",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
},
{
"name": "Escape Smart Characters: empty input",
"input": "",
"expectedOutput": "",
"recipeConfig": [
{
"op": "Escape Smart Characters",
"args": ["Include"]
}
]
}
]);

View File

@ -14,15 +14,18 @@ const validTokenSha256 = "eyJyb2xlIjoic3VwZXJ1c2VyIiwidXNlciI6ImFkbWluIn0.aab3Ew
const validKey = "mysecretkey";
const wrongKey = "notTheKey";
const outputObject = {
user: "admin",
role: "superuser",
};
const outputObject = `{
"role": "superuser",
"user": "admin"
}`;
const outputVerify = {
valid: true,
payload: outputObject,
};
const outputVerify = `{
"valid": true,
"payload": {
"role": "superuser",
"user": "admin"
}
}`;
TestRegister.addTests([
{

View File

@ -12,7 +12,7 @@ TestRegister.addTests([
{
name: "IPv6 Transition: IPv4 to IPv6",
input: "198.51.100.7",
expectedOutput: "6to4: 2002:c633:6407::/48\nIPv4 Mapped: ::ffff:c633:6407\nIPv4 Translated: ::ffff:0:c633:6407\nNat 64: 64:ff9b::c633:6407",
expectedOutput: "6to4: 2002:c633:6407::/48\nIPv4 Mapped: ::ffff:c633:6407\nIPv4 Translated: ::ffff:0:c633:6407\nNat 64: 64:ff9b::c633:6407\n",
recipeConfig: [
{
op: "IPv6 Transition Addresses",
@ -22,7 +22,7 @@ TestRegister.addTests([
}, {
name: "IPv6 Transition: IPv4 /24 Range to IPv6",
input: "198.51.100.0/24",
expectedOutput: "6to4: 2002:c633:6400::/40\nIPv4 Mapped: ::ffff:c633:6400/120\nIPv4 Translated: ::ffff:0:c633:6400/120\nNat 64: 64:ff9b::c633:6400/120",
expectedOutput: "6to4: 2002:c633:6400::/40\nIPv4 Mapped: ::ffff:c633:6400/120\nIPv4 Translated: ::ffff:0:c633:6400/120\nNat 64: 64:ff9b::c633:6400/120\n",
recipeConfig: [
{
op: "IPv6 Transition Addresses",
@ -32,7 +32,7 @@ TestRegister.addTests([
}, {
name: "IPv6 Transition: IPv4 to IPv6 Remove headers",
input: "198.51.100.7",
expectedOutput: "2002:c633:6407::/48\n::ffff:c633:6407\n::ffff:0:c633:6407\n64:ff9b::c633:6407",
expectedOutput: "2002:c633:6407::/48\n::ffff:c633:6407\n::ffff:0:c633:6407\n64:ff9b::c633:6407\n",
recipeConfig: [
{
op: "IPv6 Transition Addresses",
@ -42,7 +42,7 @@ TestRegister.addTests([
}, {
name: "IPv6 Transition: IPv6 to IPv4",
input: "64:ff9b::c633:6407",
expectedOutput: "IPv4: 198.51.100.7",
expectedOutput: "IPv4: 198.51.100.7\n",
recipeConfig: [
{
op: "IPv6 Transition Addresses",

View File

@ -51,16 +51,16 @@ const OUT_CRL_PEM_RSA = `Certificate Revocation List (CRL):
DirName:/C=UK/ST=London/O=BB/CN=Test Root CA
serial:37:5D:4B:F6:BD:7C:11:7C:CC:46:1A:FF:D7:2F:2C:26:F8:1E:4B:3D
X509v3 CRL Distribution Points:
Full Name:
URI:http://example.com/full-crl
Full Name:
URI:ldap://example.com/full-crl
Full Name:
IP:127.0.0.1
Full Name:
URI:http://example.com/full-crl
Full Name:
URI:ldap://example.com/full-crl
Full Name:
IP:127.0.0.1
X509v3 CRL Number:
1E3C
issuerAltName:
Unsupported CRL extension. Try openssl CLI.
X509v3 Issuer Alternative Name:
Revoked Certificates:
Serial Number: 1000
Revocation Date: Sun, 25 Aug 2024 03:23:08 GMT
@ -143,16 +143,16 @@ const OUT_CRL_PEM_RSA_CRL_REASON_AND_INVALIDITY_DATE = `Certificate Revocation L
DirName:/C=UK/ST=London/O=BB/CN=Test Root CA
serial:37:5D:4B:F6:BD:7C:11:7C:CC:46:1A:FF:D7:2F:2C:26:F8:1E:4B:3D
X509v3 CRL Distribution Points:
Full Name:
URI:http://example.com/full-crl
Full Name:
URI:ldap://example.com/full-crl
Full Name:
IP:127.0.0.1
Full Name:
URI:http://example.com/full-crl
Full Name:
URI:ldap://example.com/full-crl
Full Name:
IP:127.0.0.1
X509v3 CRL Number:
1E3D
issuerAltName:
Unsupported CRL extension. Try openssl CLI.
X509v3 Issuer Alternative Name:
Revoked Certificates:
Serial Number: 1000
Revocation Date: Sun, 25 Aug 2024 12:08:48 GMT

View File

@ -0,0 +1,45 @@
/**
* ROR13 tests.
*
* @author fufu_btw [contact@fufu.red]
* @copyright Crown Copyright 2026
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
name: "ROR13: AddConsoleAliasW",
input: "AddConsoleAliasW",
expectedOutput: "0x9916128C",
recipeConfig: [
{
op: "ROR13",
args: []
},
],
},
{
name: "ROR13 Hash: LoadLibraryA",
input: "LoadLibraryA",
expectedOutput: "0xEC0E4E8E",
recipeConfig: [
{
op: "ROR13",
args: []
},
],
},
{
name: "ROR13 Hash: CloseHandle",
input: "CloseHandle",
expectedOutput: "0x0FFD97FB",
recipeConfig: [
{
op: "ROR13",
args: []
},
],
},
]);

View File

@ -59,6 +59,7 @@ TestRegister.addTests([
"option": "Hex",
"string": "$R0"
},
16,
"CTR", "Hex", "Raw",
{
"option": "Hex",
@ -67,7 +68,8 @@ TestRegister.addTests([
{
"option": "Hex",
"string": ""
}
},
"Off"
]
}
]

View File

@ -0,0 +1,62 @@
/**
* @author Louis-Ladd [lewisharshman1@gmail.com]
* @copyright Crown Copyright 2025
* @license Apache-2.0
*/
import TestRegister from "../../lib/TestRegister.mjs";
TestRegister.addTests([
{
"name": "Remove ANSI Escape Codes: text using x1b escape code",
"input": "\x1b[31mHello, \x1b[31mWorld!",
"expectedOutput": "Hello, World!",
"recipeConfig": [
{
"op": "Remove ANSI Escape Codes",
"args": [],
},
],
},
{
"name": "Remove ANSI Escape Codes: text with incomplete codes",
"input": "\x1b[31 Hello, World!",
"expectedOutput": "ello, World!",
"recipeConfig": [
{
"op": "Remove ANSI Escape Codes",
"args": [],
},
],
},
{
"name": "Remove ANSI Escape Codes: cursor commands and clear screen",
"input": "\x1b[2J\x1b[H\x1b[3BHello, World!",
"expectedOutput": "Hello, World!",
"recipeConfig": [
{
"op": "Remove ANSI Escape Codes",
"args": [],
},
],
},
{
"name": "Remove ANSI Escape Codes: text containing javascript escape representation of ansi escape codes",
// input/output expressed in hex to avoid accidental interpretation of Javascript escapes and to make the test case explicit
"input": "5c 30 33 33 5b 33 32 3b 31 3b 33 3b 34 3b 39 6d 48 65 6c 6c 6f 2c 20 5c 30 33 33 5b 33 32 3b 31 3b 33 3b 34 3b 39 6d 57 6f 72 6c 64 21",
"expectedOutput": "5c 30 33 33 5b 33 32 3b 31 3b 33 3b 34 3b 39 6d 48 65 6c 6c 6f 2c 20 5c 30 33 33 5b 33 32 3b 31 3b 33 3b 34 3b 39 6d 57 6f 72 6c 64 21",
"recipeConfig": [
{
"op": "From Hex",
"args": ["Auto"]
},
{
"op": "Remove ANSI Escape Codes",
"args": []
},
{
"op": "To Hex",
"args": ["Space", 0]
}
],
},
]);