mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-11 16:51:31 -04:00
Linting and modifications
This commit is contained in:
commit
41d8c4af17
37 changed files with 1576 additions and 128 deletions
13
.travis.yml
13
.travis.yml
|
@ -2,6 +2,7 @@ language: node_js
|
|||
node_js:
|
||||
- lts/dubnium
|
||||
cache: npm
|
||||
os: linux
|
||||
addons:
|
||||
chrome: stable
|
||||
install: npm install
|
||||
|
@ -19,16 +20,16 @@ before_deploy:
|
|||
- grunt copy:ghPages
|
||||
deploy:
|
||||
- provider: pages
|
||||
skip_cleanup: true
|
||||
github_token: $GITHUB_TOKEN
|
||||
edge: true
|
||||
token: $GITHUB_TOKEN
|
||||
local_dir: build/prod/
|
||||
target_branch: gh-pages
|
||||
on:
|
||||
repo: gchq/CyberChef
|
||||
branch: master
|
||||
- provider: releases
|
||||
skip_cleanup: true
|
||||
api_key:
|
||||
edge: true
|
||||
token:
|
||||
secure: "HV1WSKv4l/0Y2bKKs1iBJocBcmLj08PCRUeEM/jTwA4jqJ8EiLHWiXtER/D5sEg2iibRVKd2OQjfrmS6bo4AiwdeVgAKmv0FtS2Jw+391N8Nd5AkEANHa5Om/IpHLTL2YRAjpJTsDpY72bMUTJIwjQA3TFJkgrpOw6KYfohOcgbxLpZ4XuNJRU3VL4Hsxdv5V9aOVmfFOmMOVPQlakXy7NgtW5POp1f2WJwgcZxylkR1CjwaqMyXmSoVl46pyH3tr5+dptsQoKSGdi6sIHGA60oDotFPcm+0ifa47wZw+vapuuDi4tdNxhrHGaDMG8xiE0WFDHwQUDlk2/+W7j9SEX0H3Em7us371JXRp56EDwEcDa34VpVkC6i8HGcHK55hnxVbMZXGf3qhOFD8wY7qMbjMRvIpucrMHBi86OfkDfv0vDj2LyvIl5APj/AX50BrE0tfH1MZbH26Jkx4NdlkcxQ14GumarmUqfmVvbX/fsoA6oUuAAE9ZgRRi3KHO4wci6KUcRfdm+XOeUkaBFsL86G3EEYIvrtBTuaypdz+Cx7nd1iPZyWMx5Y1gXnVzha4nBdV4+7l9JIsFggD8QVpw2uHXQiS1KXFjOeqA3DBD8tjMB7q26Fl2fD3jkOo4BTbQ2NrRIZUu/iL+fOmMPsyMt2qulB0yaSBCfkbEq8xrUA="
|
||||
file_glob: true
|
||||
file:
|
||||
|
@ -38,9 +39,9 @@ deploy:
|
|||
repo: gchq/CyberChef
|
||||
tags: true
|
||||
- provider: npm
|
||||
skip_cleanup: true
|
||||
edge: true
|
||||
email: "n1474335@gmail.com"
|
||||
api_key:
|
||||
api_token:
|
||||
secure: "UnDQL3Kh+GK2toL0TK3FObO0ujVssU3Eg4BBuYdjwLB81GhiGE5/DTh7THdZPOpbLo6wQeOwfZDuMeKC1OU+0Uf4NsdYFu1aq6xMO20qBQ4qUfgsyiK4Qgywj9gk0p1+OFZdGAZ/j1CNRAaF71XQIY6iV84c+SO4WoizXYrNT0Jh4sr2DA4/97G2xmJtPi0qOzYrJ09R56ZUozmqeik5G0pMRIuJRbpjS/7bZXV+N7WV0ombZc9RkUaetbabEVOLQ+Xx5YAIVq+VuEeMe9VBSnxY/FfCLmy1wJsjGzpLCyBI9nbrG4nw8Wgc2m8NfK9rcpIvBTGner9r2j60NVDkZ8kLZPrqXhq6AZMwa+oz6K5UQCqRo2RRQzSGwXxg67HY5Tcq+oNmjd+DqpPg4LZ3eGlluyP5XfG+hpSr9Ya4d8q8SrUWLxkoLHI6ZKMtoKFbTCSSQPiluW5hsZxjz3yDkkjsJw64M/EM8UyJrgaXqDklQu+7rBGKLfsK6os7RDiqjBWpQ7gwpo8HvY0O8yqEAabPz+QGkanpjcCOZCXFbSkzWxYy37RMAPu88iINVZVlZE4l+WJenCpZY95ueyy0mG9cyMSzVRPyX6A+/n4H6VMFPFjpGDLTD588ACEjY1lmHfS/eXwXJcgqPPD2gW0XdRdUheU/ssqlfCfGWQMTDXs="
|
||||
on:
|
||||
tags: true
|
||||
|
|
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -2,6 +2,12 @@
|
|||
All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
|
||||
|
||||
|
||||
### [9.13.0] - 2020-02-13
|
||||
- 'Rail Fence Cipher Encode' and 'Rail Fence Cipher Decode' operations added [@Flavsditz] | [#948]
|
||||
|
||||
### [9.12.0] - 2019-12-20
|
||||
- 'Normalise Unicode' operation added [@matthieuxyz] | [#912]
|
||||
|
||||
### [9.11.0] - 2019-11-06
|
||||
- Implemented CFB, OFB, and CTR modes for Blowfish operations [@cbeuw] | [#653]
|
||||
|
||||
|
@ -197,6 +203,8 @@ All major and minor version changes will be documented in this file. Details of
|
|||
|
||||
|
||||
|
||||
[9.13.0]: https://github.com/gchq/CyberChef/releases/tag/v9.13.0
|
||||
[9.12.0]: https://github.com/gchq/CyberChef/releases/tag/v9.12.0
|
||||
[9.11.0]: https://github.com/gchq/CyberChef/releases/tag/v9.11.0
|
||||
[9.10.0]: https://github.com/gchq/CyberChef/releases/tag/v9.10.0
|
||||
[9.9.0]: https://github.com/gchq/CyberChef/releases/tag/v9.9.0
|
||||
|
@ -281,6 +289,8 @@ All major and minor version changes will be documented in this file. Details of
|
|||
[@jarrodconnolly]: https://github.com/jarrodconnolly
|
||||
[@VirtualColossus]: https://github.com/VirtualColossus
|
||||
[@cbeuw]: https://github.com/cbeuw
|
||||
[@matthieuxyz]: https://github.com/matthieuxyz
|
||||
[@Flavsditz]: https://github.com/Flavsditz
|
||||
|
||||
[#95]: https://github.com/gchq/CyberChef/pull/299
|
||||
[#173]: https://github.com/gchq/CyberChef/pull/173
|
||||
|
@ -344,3 +354,5 @@ All major and minor version changes will be documented in this file. Details of
|
|||
[#632]: https://github.com/gchq/CyberChef/pull/632
|
||||
[#653]: https://github.com/gchq/CyberChef/pull/653
|
||||
[#865]: https://github.com/gchq/CyberChef/pull/865
|
||||
[#912]: https://github.com/gchq/CyberChef/pull/912
|
||||
[#948]: https://github.com/gchq/CyberChef/pull/948
|
||||
|
|
|
@ -219,6 +219,7 @@ module.exports = function (grunt) {
|
|||
options: {
|
||||
webpack: webpackConfig,
|
||||
host: "0.0.0.0",
|
||||
port: grunt.option("port") || 8080,
|
||||
disableHostCheck: true,
|
||||
overlay: true,
|
||||
inline: false,
|
||||
|
@ -275,7 +276,7 @@ module.exports = function (grunt) {
|
|||
connect: {
|
||||
prod: {
|
||||
options: {
|
||||
port: 8000,
|
||||
port: grunt.option("port") || 8000,
|
||||
base: "build/prod/"
|
||||
}
|
||||
}
|
||||
|
|
321
package-lock.json
generated
321
package-lock.json
generated
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.11.13",
|
||||
"version": "9.13.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@ -2514,6 +2514,38 @@
|
|||
"core-js": "^3.4.1"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.scandir": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz",
|
||||
"integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "2.0.3",
|
||||
"run-parallel": "^1.1.9"
|
||||
}
|
||||
},
|
||||
"@nodelib/fs.stat": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz",
|
||||
"integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==",
|
||||
"dev": true
|
||||
},
|
||||
"@nodelib/fs.walk": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz",
|
||||
"integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.scandir": "2.1.3",
|
||||
"fastq": "^1.6.0"
|
||||
}
|
||||
},
|
||||
"@testim/chrome-version": {
|
||||
"version": "1.0.7",
|
||||
"resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.0.7.tgz",
|
||||
"integrity": "sha512-8UT/J+xqCYfn3fKtOznAibsHpiuDshCb0fwgWxRazTT19Igp9ovoXMPhXyLD6m3CKQGTMHgqoxaFfMWaL40Rnw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/color-name": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
|
||||
|
@ -2868,6 +2900,24 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"aggregate-error": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz",
|
||||
"integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"clean-stack": "^2.0.0",
|
||||
"indent-string": "^4.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.5.5",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz",
|
||||
|
@ -4146,18 +4196,59 @@
|
|||
}
|
||||
},
|
||||
"chromedriver": {
|
||||
"version": "78.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-78.0.1.tgz",
|
||||
"integrity": "sha512-eOsyFk4xb9EECs1VMrDbxO713qN+Bu1XUE8K9AuePc3839TPdAegg72kpXSzkeNqRNZiHbnJUItIVCLFkDqceA==",
|
||||
"version": "80.0.1",
|
||||
"resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-80.0.1.tgz",
|
||||
"integrity": "sha512-VfRtZUpBUIjeypS+xM40+VD9g4Drv7L2VibG/4+0zX3mMx4KayN6gfKETycPfO6JwQXTLSxEr58fRcrsa8r5xQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"del": "^4.1.1",
|
||||
"@testim/chrome-version": "^1.0.7",
|
||||
"axios": "^0.19.2",
|
||||
"del": "^5.1.0",
|
||||
"extract-zip": "^1.6.7",
|
||||
"mkdirp": "^0.5.1",
|
||||
"request": "^2.88.0",
|
||||
"mkdirp": "^1.0.3",
|
||||
"tcp-port-used": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"array-union": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||
"dev": true
|
||||
},
|
||||
"axios": {
|
||||
"version": "0.19.2",
|
||||
"resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
|
||||
"integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"follow-redirects": "1.5.10"
|
||||
}
|
||||
},
|
||||
"del": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
|
||||
"integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"globby": "^10.0.1",
|
||||
"graceful-fs": "^4.2.2",
|
||||
"is-glob": "^4.0.1",
|
||||
"is-path-cwd": "^2.2.0",
|
||||
"is-path-inside": "^3.0.1",
|
||||
"p-map": "^3.0.0",
|
||||
"rimraf": "^3.0.0",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"dir-glob": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-type": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"extract-zip": {
|
||||
"version": "1.6.7",
|
||||
"resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
|
||||
|
@ -4168,7 +4259,94 @@
|
|||
"debug": "2.6.9",
|
||||
"mkdirp": "0.5.1",
|
||||
"yauzl": "2.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"globby": {
|
||||
"version": "10.0.2",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-10.0.2.tgz",
|
||||
"integrity": "sha512-7dUi7RvCoT/xast/o/dLN53oqND4yk0nsHkhRgn9w65C4PofCLOoJ39iSOg+qVDdWQPIEj+eszMHQ+aLVwwQSg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/glob": "^7.1.1",
|
||||
"array-union": "^2.1.0",
|
||||
"dir-glob": "^3.0.1",
|
||||
"fast-glob": "^3.0.3",
|
||||
"glob": "^7.1.3",
|
||||
"ignore": "^5.1.1",
|
||||
"merge2": "^1.2.3",
|
||||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"graceful-fs": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz",
|
||||
"integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"ignore": {
|
||||
"version": "5.1.4",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
|
||||
"integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
|
||||
"dev": true
|
||||
},
|
||||
"is-path-inside": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.2.tgz",
|
||||
"integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==",
|
||||
"dev": true
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.3.tgz",
|
||||
"integrity": "sha512-6uCP4Qc0sWsgMLy1EOqqS/3rjDHOEnsStVr/4vtAIK2Y5i2kA7lFFejYrpIyiN9w0pYf4ckeCYT9f1r1P9KX5g==",
|
||||
"dev": true
|
||||
},
|
||||
"p-map": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
|
||||
"integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"path-type": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"dev": true
|
||||
},
|
||||
"rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.3"
|
||||
}
|
||||
},
|
||||
"slash": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -4220,6 +4398,12 @@
|
|||
"source-map": "~0.6.0"
|
||||
}
|
||||
},
|
||||
"clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
||||
"dev": true
|
||||
},
|
||||
"cli-cursor": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
|
||||
|
@ -6709,6 +6893,73 @@
|
|||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-glob": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz",
|
||||
"integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
"glob-parent": "^5.1.0",
|
||||
"merge2": "^1.3.0",
|
||||
"micromatch": "^4.0.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"braces": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
|
||||
"integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
},
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true
|
||||
},
|
||||
"micromatch": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
|
||||
"integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"braces": "^3.0.1",
|
||||
"picomatch": "^2.0.5"
|
||||
}
|
||||
},
|
||||
"to-regex-range": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
|
@ -6720,6 +6971,15 @@
|
|||
"resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
|
||||
"integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
|
||||
},
|
||||
"fastq": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
|
||||
"integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"reusify": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"faye-websocket": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz",
|
||||
|
@ -10214,6 +10474,12 @@
|
|||
"integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
|
||||
"dev": true
|
||||
},
|
||||
"merge2": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
|
||||
"integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"methods": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
|
||||
|
@ -10778,9 +11044,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"nightwatch": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.3.2.tgz",
|
||||
"integrity": "sha512-1Lcte2Su/JrzET62va4oVLbSXwZkZaTmxTdjShylio3U+woY6U250iNuQz/bOkL+Qvuw+9Vfp+5T13yT0YfsKg==",
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/nightwatch/-/nightwatch-1.3.4.tgz",
|
||||
"integrity": "sha512-27zWPjmBsHu3IDKc6QTQdRKbTWx4WuTUXbCOT1Wa8Ovxbv+3TZ7GCd9Dt9wm14ElO9Db9/PKVk8JIWThkqGRZA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assertion-error": "^1.1.0",
|
||||
|
@ -11391,9 +11657,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "4.2.0",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.0.tgz",
|
||||
"integrity": "sha512-7kFQgnEaMdRtwf6uSfUnVr9gSGC7faurn+J/Mv90/W+iTtN0405/nLdopfMWwchyxhbGYl6TC4Sccn9TUkGAgg==",
|
||||
"version": "4.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz",
|
||||
"integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/color-name": "^1.1.1",
|
||||
|
@ -11945,6 +12211,12 @@
|
|||
"resolved": "https://registry.npmjs.org/phin/-/phin-2.9.3.tgz",
|
||||
"integrity": "sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA=="
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz",
|
||||
"integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==",
|
||||
"dev": true
|
||||
},
|
||||
"pify": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
|
||||
|
@ -13050,6 +13322,12 @@
|
|||
"integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
|
||||
"dev": true
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true
|
||||
},
|
||||
"revalidator": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/revalidator/-/revalidator-0.1.8.tgz",
|
||||
|
@ -13084,6 +13362,12 @@
|
|||
"is-promise": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"run-parallel": {
|
||||
"version": "1.1.9",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
|
||||
"integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
|
||||
"dev": true
|
||||
},
|
||||
"run-queue": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz",
|
||||
|
@ -14394,9 +14678,9 @@
|
|||
}
|
||||
},
|
||||
"terser": {
|
||||
"version": "4.5.1",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.5.1.tgz",
|
||||
"integrity": "sha512-lH9zLIbX8PRBEFCTvfHGCy0s9HEKnNso1Dx9swSopF3VUnFLB8DpQ61tHxoofovNC/sG0spajJM3EIIRSTByiQ==",
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/terser/-/terser-4.4.2.tgz",
|
||||
"integrity": "sha512-Uufrsvhj9O1ikwgITGsZ5EZS6qPokUOkCegS7fYOdGTv+OA90vndUbU6PEjr5ePqHfNUbGyMO7xyIZv2MhsALQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"commander": "^2.20.0",
|
||||
|
@ -14947,6 +15231,11 @@
|
|||
"normalize-path": "^2.1.1"
|
||||
}
|
||||
},
|
||||
"unorm": {
|
||||
"version": "1.6.0",
|
||||
"resolved": "https://registry.npmjs.org/unorm/-/unorm-1.6.0.tgz",
|
||||
"integrity": "sha512-b2/KCUlYZUeA7JFUuRJZPUtr4gZvBh7tavtv4fvk4+KV9pfGiR6CQAQAWl49ZpR3ts2dk4FYkP7EIgDJoiOLDA=="
|
||||
},
|
||||
"unpipe": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cyberchef",
|
||||
"version": "9.11.13",
|
||||
"version": "9.13.0",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
|
@ -43,7 +43,7 @@
|
|||
"babel-eslint": "^10.0.3",
|
||||
"babel-loader": "^8.0.6",
|
||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||
"chromedriver": "^78.0.1",
|
||||
"chromedriver": "^80.0.1",
|
||||
"colors": "^1.4.0",
|
||||
"copy-webpack-plugin": "^5.0.5",
|
||||
"css-loader": "^3.2.1",
|
||||
|
@ -65,7 +65,7 @@
|
|||
"html-webpack-plugin": "^3.2.0",
|
||||
"imports-loader": "^0.8.0",
|
||||
"mini-css-extract-plugin": "^0.8.0",
|
||||
"nightwatch": "^1.3.2",
|
||||
"nightwatch": "^1.3.4",
|
||||
"node-sass": "^4.13.0",
|
||||
"postcss-css-variables": "^0.14.0",
|
||||
"postcss-import": "^12.0.1",
|
||||
|
@ -147,6 +147,7 @@
|
|||
"ssdeep.js": "0.0.2",
|
||||
"tesseract.js": "^2.0.0-alpha.15",
|
||||
"ua-parser-js": "^0.7.20",
|
||||
"unorm": "^1.6.0",
|
||||
"utf8": "^3.0.0",
|
||||
"vkbeautify": "^0.99.3",
|
||||
"xmldom": "^0.1.27",
|
||||
|
|
|
@ -73,10 +73,10 @@ class Chef {
|
|||
// The threshold is specified in KiB.
|
||||
const threshold = (options.ioDisplayThreshold || 1024) * 1024;
|
||||
const returnType =
|
||||
this.dish.size > threshold ?
|
||||
Dish.ARRAY_BUFFER :
|
||||
this.dish.type === Dish.HTML ?
|
||||
Dish.HTML :
|
||||
this.dish.type === Dish.HTML ?
|
||||
Dish.HTML :
|
||||
this.dish.size > threshold ?
|
||||
Dish.ARRAY_BUFFER :
|
||||
Dish.STRING;
|
||||
|
||||
return {
|
||||
|
|
|
@ -113,6 +113,7 @@ class Ingredient {
|
|||
return data;
|
||||
}
|
||||
case "number":
|
||||
if (data === null) return data;
|
||||
number = parseFloat(data);
|
||||
if (isNaN(number)) {
|
||||
const sample = Utils.truncate(data.toString(), 10);
|
||||
|
|
|
@ -591,6 +591,44 @@ class Utils {
|
|||
return utf8 ? Utils.byteArrayToUtf8(arr) : Utils.byteArrayToChars(arr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the Shannon entropy for a given set of data.
|
||||
*
|
||||
* @param {Uint8Array|ArrayBuffer} input
|
||||
* @returns {number}
|
||||
*/
|
||||
static calculateShannonEntropy(data) {
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = new Uint8Array(data);
|
||||
}
|
||||
const prob = [],
|
||||
occurrences = new Array(256).fill(0);
|
||||
|
||||
// Count occurrences of each byte in the input
|
||||
let i;
|
||||
for (i = 0; i < data.length; i++) {
|
||||
occurrences[data[i]]++;
|
||||
}
|
||||
|
||||
// Store probability list
|
||||
for (i = 0; i < occurrences.length; i++) {
|
||||
if (occurrences[i] > 0) {
|
||||
prob.push(occurrences[i] / data.length);
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate Shannon entropy
|
||||
let entropy = 0,
|
||||
p;
|
||||
|
||||
for (i = 0; i < prob.length; i++) {
|
||||
p = prob[i];
|
||||
entropy += p * Math.log(p) / Math.log(2);
|
||||
}
|
||||
|
||||
return -entropy;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Parses CSV data and returns it as a two dimensional array or strings.
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
"URL Decode",
|
||||
"Escape Unicode Characters",
|
||||
"Unescape Unicode Characters",
|
||||
"Normalise Unicode",
|
||||
"To Quoted Printable",
|
||||
"From Quoted Printable",
|
||||
"To Punycode",
|
||||
|
@ -94,6 +95,8 @@
|
|||
"Affine Cipher Decode",
|
||||
"A1Z26 Cipher Encode",
|
||||
"A1Z26 Cipher Decode",
|
||||
"Rail Fence Cipher Encode",
|
||||
"Rail Fence Cipher Decode",
|
||||
"Atbash Cipher",
|
||||
"Substitute",
|
||||
"Derive PBKDF2 key",
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
*/
|
||||
|
||||
import DishType from "./DishType.mjs";
|
||||
import { isNodeEnvironment } from "../Utils.mjs";
|
||||
import Utils, { isNodeEnvironment } from "../Utils.mjs";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -16,13 +16,14 @@ class DishListFile extends DishType {
|
|||
/**
|
||||
* convert the given value to a ArrayBuffer
|
||||
*/
|
||||
static toArrayBuffer() {
|
||||
static async toArrayBuffer() {
|
||||
DishListFile.checkForValue(this.value);
|
||||
|
||||
if (isNodeEnvironment()) {
|
||||
this.value = this.value.map(file => Uint8Array.from(file.data));
|
||||
} else {
|
||||
this.value = await DishListFile.concatenateTypedArraysWithTypedElements(...this.value);
|
||||
}
|
||||
this.value = DishListFile.concatenateTypedArrays(...this.value).buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -33,6 +34,27 @@ class DishListFile extends DishType {
|
|||
this.value = [new File(this.value, "unknown")];
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates a list of typed elements together.
|
||||
*
|
||||
* @param {Uint8Array[]} arrays
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
static async concatenateTypedArraysWithTypedElements(...arrays) {
|
||||
let totalLength = 0;
|
||||
for (const arr of arrays) {
|
||||
totalLength += arr.size;
|
||||
}
|
||||
const myArray = new Uint8Array(totalLength);
|
||||
|
||||
let offset = 0;
|
||||
for (const arr of arrays) {
|
||||
const data = await Utils.readFile(arr);
|
||||
myArray.set(data, offset);
|
||||
offset += data.length;
|
||||
}
|
||||
return myArray;
|
||||
}
|
||||
|
||||
/**
|
||||
* Concatenates a list of Uint8Arrays together
|
||||
|
|
|
@ -164,3 +164,15 @@ export const IO_FORMAT = {
|
|||
"Simplified Chinese GB18030 (54936)": 54936,
|
||||
};
|
||||
|
||||
/**
|
||||
* Unicode Normalisation Forms
|
||||
*
|
||||
* @author Matthieu [m@tthieu.xyz]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Character encoding format mappings.
|
||||
*/
|
||||
export const UNICODE_NORMALISATION_FORMS = ["NFD", "NFC", "NFKD", "NFKC"];
|
||||
|
|
|
@ -280,7 +280,7 @@ export const FILE_SIGNATURES = {
|
|||
9: 0x0,
|
||||
10: [0x0, 0x1]
|
||||
},
|
||||
extractor: null
|
||||
extractor: extractICO
|
||||
},
|
||||
{
|
||||
name: "Radiance High Dynamic Range image",
|
||||
|
@ -1008,8 +1008,7 @@ export const FILE_SIGNATURES = {
|
|||
0: 0x7b,
|
||||
1: 0x5c,
|
||||
2: 0x72,
|
||||
3: 0x74,
|
||||
4: 0x66
|
||||
3: 0x74
|
||||
},
|
||||
extractor: extractRTF
|
||||
},
|
||||
|
@ -2933,6 +2932,32 @@ export function extractBMP(bytes, offset) {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* ICO extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {number} offset
|
||||
*/
|
||||
export function extractICO(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Move to number of files there are.
|
||||
stream.moveTo(4);
|
||||
|
||||
// Read the number of files stored in the ICO
|
||||
const numberFiles = stream.readInt(2, "le");
|
||||
|
||||
// Move forward to the last file header.
|
||||
stream.moveForwardsBy(8 + ((numberFiles-1) * 16));
|
||||
const fileSize = stream.readInt(4, "le");
|
||||
const fileOffset = stream.readInt(4, "le");
|
||||
|
||||
// Move to the end of the last file.
|
||||
stream.moveTo(fileOffset + fileSize);
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* WAV extractor.
|
||||
*
|
||||
|
@ -2947,7 +2972,7 @@ export function extractWAV(bytes, offset) {
|
|||
stream.moveTo(4);
|
||||
|
||||
// Move to file size.
|
||||
stream.moveTo(stream.readInt(4, "le") - 4);
|
||||
stream.moveTo(stream.readInt(4, "le"));
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
@ -3075,15 +3100,127 @@ export function extractSQLITE(bytes, offset) {
|
|||
export function extractPListXML(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
|
||||
// Find closing tag (</plist>)
|
||||
stream.continueUntil([0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e]);
|
||||
stream.moveForwardsBy(8);
|
||||
let braceCount = 0;
|
||||
|
||||
// Continue to the first (<plist).
|
||||
stream.continueUntil([0x3c, 0x70, 0x6c, 0x69, 0x73, 0x74]);
|
||||
stream.moveForwardsBy(6);
|
||||
braceCount++;
|
||||
|
||||
// While we have an unequal amount of braces.
|
||||
while (braceCount > 0 && stream.hasMore()) {
|
||||
if (stream.readInt(1) === 0x3c) {
|
||||
|
||||
// If we hit an <plist.
|
||||
if (stream.getBytes(5).join("") === [0x70, 0x6c, 0x69, 0x73, 0x74].join("")) {
|
||||
braceCount++;
|
||||
} else {
|
||||
stream.moveBackwardsBy(5);
|
||||
}
|
||||
|
||||
// If we hit an </plist>.
|
||||
if (stream.getBytes(7).join("") === [0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e].join("")) {
|
||||
braceCount--;
|
||||
} else {
|
||||
stream.moveBackwardsBy(7);
|
||||
}
|
||||
}
|
||||
}
|
||||
stream.consumeIf(0x0a);
|
||||
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* OLE2 extractor.
|
||||
*
|
||||
* @param {Uint8Array} bytes
|
||||
* @param {number} offset
|
||||
* @returns {Uint8Array}
|
||||
*/
|
||||
export function extractOLE2(bytes, offset) {
|
||||
const stream = new Stream(bytes.slice(offset));
|
||||
const entries = [
|
||||
[[0x52, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x74, 0x00, 0x20, 0x00, 0x45, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x72, 0x00, 0x79], 19, "Root Entry"],
|
||||
[[0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6b, 0x00, 0x62, 0x00, 0x6f, 0x00, 0x6f, 0x00, 0x6b], 15, "Workbook"],
|
||||
[[0x43, 0x00, 0x75, 0x00, 0x72, 0x00, 0x72, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x55, 0x00, 0x73, 0x00, 0x65, 0x00, 0x72], 23, "Current User"],
|
||||
[[0x50, 0x00, 0x6f, 0x00, 0x77, 0x00, 0x65, 0x00, 0x72, 0x00, 0x50, 0x00, 0x6f, 0x00, 0x69, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x20, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74], 37, "PowerPoint Document"],
|
||||
[[0x57, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x64, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74], 23, "WordDocument"],
|
||||
[[0x44, 0x00, 0x61, 0x00, 0x74, 0x00, 0x61], 7, "Data"],
|
||||
[[0x50, 0x00, 0x69, 0x00, 0x63, 0x00, 0x74, 0x00, 0x75, 0x00, 0x72, 0x00, 0x65, 0x00, 0x73], 15, "Pictures"],
|
||||
[[0x31, 0x00, 0x54, 0x00, 0x61, 0x00, 0x62, 0x00, 0x6c, 0x00, 0x65], 11, "1Table"],
|
||||
[[0x05, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e], 37, "SummaryInformation"],
|
||||
[[0x05, 0x00, 0x44, 0x00, 0x6f, 0x00, 0x63, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x65, 0x00, 0x6e, 0x00, 0x74, 0x00, 0x53, 0x00, 0x75, 0x00, 0x6d, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x72, 0x00, 0x79, 0x00, 0x49, 0x00, 0x6e, 0x00, 0x66, 0x00, 0x6f, 0x00, 0x72, 0x00, 0x6d, 0x00, 0x61, 0x00, 0x74, 0x00, 0x69, 0x00, 0x6f, 0x00, 0x6e], 53, "DocumentSummaryInformation"],
|
||||
[[0x43, 0x00, 0x6f, 0x00, 0x6d, 0x00, 0x70, 0x00, 0x4f, 0x00, 0x62, 0x00, 0x6a], 13, "Comp Obj"],
|
||||
[[0x01, 0x00], 2, "Entry"]
|
||||
];
|
||||
let endianness = "le";
|
||||
|
||||
// Move to endianess field.
|
||||
stream.moveForwardsBy(28);
|
||||
if (stream.readInt(2, endianness) === 0xfffe)
|
||||
endianness = "be";
|
||||
|
||||
// Calculate the size of the normal sectors.
|
||||
const sizeOfSector = 2 ** stream.readInt(2, endianness);
|
||||
|
||||
// Move to root directory offset field.
|
||||
stream.moveTo(48);
|
||||
|
||||
// Read root directory offset.
|
||||
const rootStuff = stream.readInt(4, endianness);
|
||||
|
||||
// Calculate root directory offset.
|
||||
let total = 512 + (rootStuff * sizeOfSector);
|
||||
stream.moveTo(total);
|
||||
|
||||
// While valid directory entries.
|
||||
let found = true;
|
||||
while (found) {
|
||||
found = false;
|
||||
|
||||
// Attempt to determine what directory entry it is.
|
||||
for (const element of entries) {
|
||||
|
||||
// If the byte pattern matches.
|
||||
if (stream.getBytes(element[1]).join("") === element[0].join("")) {
|
||||
stream.moveBackwardsBy(element[1]);
|
||||
found = true;
|
||||
|
||||
// Move forwards by the size of the comp obj.
|
||||
if (element[2] === "Comp Obj") {
|
||||
|
||||
// The size of the Comp Obj entry - 128. Since we add 128 later.
|
||||
total += 128 * 6;
|
||||
stream.moveTo(total);
|
||||
} else if (element[2] === "Entry") {
|
||||
|
||||
// If there is an entry move backwards by 126 to then move forwards by 128. Hence a total displacement of 2.
|
||||
stream.moveBackwardsBy(126);
|
||||
}
|
||||
break;
|
||||
}
|
||||
stream.moveBackwardsBy(element[1]);
|
||||
}
|
||||
|
||||
// If we have found a valid entry, move forwards by 128.
|
||||
if (found) {
|
||||
|
||||
// Every entry is at least 128 in size, some are bigger which is dealt with by the above if statement.
|
||||
total += 128;
|
||||
stream.moveForwardsBy(128);
|
||||
}
|
||||
}
|
||||
|
||||
// Round up to a multiple of 512.
|
||||
total = Math.ceil(total / 512) * 512;
|
||||
|
||||
stream.moveTo(total);
|
||||
return stream.carve();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* GZIP extractor.
|
||||
*
|
||||
|
|
|
@ -23,25 +23,39 @@ import Utils from "../Utils.mjs";
|
|||
*
|
||||
* // returns "0a:14:1e"
|
||||
* toHex([10,20,30], ":");
|
||||
*
|
||||
* // returns "0x0a,0x14,0x1e"
|
||||
* toHex([10,20,30], "0x", 2, ",")
|
||||
*/
|
||||
export function toHex(data, delim=" ", padding=2) {
|
||||
export function toHex(data, delim=" ", padding=2, extraDelim="", lineSize=0) {
|
||||
if (!data) return "";
|
||||
if (data instanceof ArrayBuffer) data = new Uint8Array(data);
|
||||
|
||||
let output = "";
|
||||
const prepend = (delim === "0x" || delim === "\\x");
|
||||
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
output += data[i].toString(16).padStart(padding, "0") + delim;
|
||||
const hex = data[i].toString(16).padStart(padding, "0");
|
||||
output += prepend ? delim + hex : hex + delim;
|
||||
|
||||
if (extraDelim) {
|
||||
output += extraDelim;
|
||||
}
|
||||
// Add LF after each lineSize amount of bytes but not at the end
|
||||
if ((i !== data.length - 1) && ((i + 1) % lineSize === 0)) {
|
||||
output += "\n";
|
||||
}
|
||||
}
|
||||
|
||||
// Add \x or 0x to beginning
|
||||
if (delim === "0x") output = "0x" + output;
|
||||
if (delim === "\\x") output = "\\x" + output;
|
||||
|
||||
if (delim.length)
|
||||
return output.slice(0, -delim.length);
|
||||
else
|
||||
// Remove the extraDelim at the end (if there is one)
|
||||
// and remove the delim at the end, but if it's prepended there's nothing to remove
|
||||
const rTruncLen = extraDelim.length + (prepend ? 0 : delim.length);
|
||||
if (rTruncLen) {
|
||||
// If rTruncLen === 0 then output.slice(0,0) will be returned, which is nothing
|
||||
return output.slice(0, -rTruncLen);
|
||||
} else {
|
||||
return output;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -87,7 +101,7 @@ export function toHexFast(data) {
|
|||
*/
|
||||
export function fromHex(data, delim="Auto", byteLen=2) {
|
||||
if (delim !== "None") {
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]/gi : Utils.regexRep(delim);
|
||||
const delimRegex = delim === "Auto" ? /[^a-f\d]|(0x)/gi : Utils.regexRep(delim);
|
||||
data = data.replace(delimRegex, "");
|
||||
}
|
||||
|
||||
|
@ -102,7 +116,7 @@ export function fromHex(data, delim="Auto", byteLen=2) {
|
|||
/**
|
||||
* To Hexadecimal delimiters.
|
||||
*/
|
||||
export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "\\x", "None"];
|
||||
export const TO_HEX_DELIM_OPTIONS = ["Space", "Percent", "Comma", "Semi-colon", "Colon", "Line feed", "CRLF", "0x", "0x with comma", "\\x", "None"];
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -458,7 +458,7 @@ class Magic {
|
|||
await recipe.execute(dish);
|
||||
// Return an empty buffer if the recipe did not run to completion
|
||||
if (recipe.lastRunOp === recipe.opList[recipe.opList.length - 1]) {
|
||||
return dish.get(Dish.ARRAY_BUFFER);
|
||||
return await dish.get(Dish.ARRAY_BUFFER);
|
||||
} else {
|
||||
return new ArrayBuffer();
|
||||
}
|
||||
|
|
|
@ -47,8 +47,8 @@ class Gunzip extends Operation {
|
|||
* @returns {File}
|
||||
*/
|
||||
run(input, args) {
|
||||
const gunzip = new Zlib.Gunzip(new Uint8Array(input));
|
||||
return new Uint8Array(gunzip.decompress()).buffer;
|
||||
const gzipObj = new Zlib.Gunzip(new Uint8Array(input));
|
||||
return new Uint8Array(gzipObj.decompress()).buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
|
||||
import Operation from "../Operation.mjs";
|
||||
import {COMPRESSION_TYPE, ZLIB_COMPRESSION_TYPE_LOOKUP} from "../lib/Zlib.mjs";
|
||||
import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min.js";
|
||||
import gzip from "zlibjs/bin/gzip.min.js";
|
||||
|
||||
const Zlib = zlibAndGzip.Zlib;
|
||||
const Zlib = gzip.Zlib;
|
||||
|
||||
/**
|
||||
* Gzip operation
|
||||
|
@ -73,12 +73,15 @@ class Gzip extends Operation {
|
|||
options.filename = filename;
|
||||
}
|
||||
if (comment.length) {
|
||||
options.flags.fcommenct = true;
|
||||
options.flags.comment = true;
|
||||
options.comment = comment;
|
||||
}
|
||||
|
||||
const gzip = new Zlib.Gzip(new Uint8Array(input), options);
|
||||
return new Uint8Array(gzip.compress()).buffer;
|
||||
const gzipObj = new Zlib.Gzip(new Uint8Array(input), options);
|
||||
const compressed = new Uint8Array(gzipObj.compress());
|
||||
if (options.flags.comment && !(compressed[3] & 0x10)) {
|
||||
compressed[3] |= 0x10;
|
||||
}
|
||||
return compressed.buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
62
src/core/operations/NormaliseUnicode.mjs
Normal file
62
src/core/operations/NormaliseUnicode.mjs
Normal file
|
@ -0,0 +1,62 @@
|
|||
/**
|
||||
* @author Matthieu [m@tthieu.xyz]
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
import {UNICODE_NORMALISATION_FORMS} from "../lib/ChrEnc.mjs";
|
||||
import unorm from "unorm";
|
||||
|
||||
/**
|
||||
* Normalise Unicode operation
|
||||
*/
|
||||
class NormaliseUnicode extends Operation {
|
||||
|
||||
/**
|
||||
* NormaliseUnicode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Normalise Unicode";
|
||||
this.module = "Encodings";
|
||||
this.description = "Transform Unicode characters to one of the Normalisation Forms";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Unicode_equivalence#Normal_forms";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Normal Form",
|
||||
type: "option",
|
||||
value: UNICODE_NORMALISATION_FORMS
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [normalForm] = args;
|
||||
|
||||
switch (normalForm) {
|
||||
case "NFD":
|
||||
return unorm.nfd(input);
|
||||
case "NFC":
|
||||
return unorm.nfc(input);
|
||||
case "NFKD":
|
||||
return unorm.nfkd(input);
|
||||
case "NFKC":
|
||||
return unorm.nfc(input);
|
||||
default:
|
||||
throw new OperationError("Unknown Normalisation Form");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default NormaliseUnicode;
|
88
src/core/operations/RailFenceCipherDecode.mjs
Normal file
88
src/core/operations/RailFenceCipherDecode.mjs
Normal file
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* @author Flavio Diez [flaviofdiez+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Rail Fence Cipher Decode operation
|
||||
*/
|
||||
class RailFenceCipherDecode extends Operation {
|
||||
|
||||
/**
|
||||
* RailFenceCipherDecode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Rail Fence Cipher Decode";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Decodes Strings that were created using the Rail fence Cipher provided a key and an offset";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Rail_fence_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "number",
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
name: "Offset",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key, offset] = args;
|
||||
|
||||
let cipher = input;
|
||||
|
||||
if (key < 2) {
|
||||
throw new OperationError("Key has to be bigger than 2");
|
||||
} else if (key > cipher.length) {
|
||||
throw new OperationError("Key should be smaller than the cipher's length");
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
throw new OperationError("Offset has to be a positive integer");
|
||||
}
|
||||
|
||||
const cycle = (key - 1) * 2;
|
||||
|
||||
const rest = cipher.length % key;
|
||||
|
||||
if (rest !== 0) {
|
||||
cipher = cipher + (" ".repeat(key - rest));
|
||||
}
|
||||
|
||||
const plaintext = new Array(cipher.length);
|
||||
|
||||
let j = 0;
|
||||
let x, y;
|
||||
|
||||
for (y = 0; y < key; y++) {
|
||||
for (x = 0; x < cipher.length; x++) {
|
||||
if ((y + x + offset) % cycle === 0 || (y - x - offset) % cycle === 0) {
|
||||
plaintext[x] = cipher[j++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return plaintext.join("").trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default RailFenceCipherDecode;
|
74
src/core/operations/RailFenceCipherEncode.mjs
Normal file
74
src/core/operations/RailFenceCipherEncode.mjs
Normal file
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* @author Flavio Diez [flaviofdiez+cyberchef@gmail.com]
|
||||
* @copyright Crown Copyright 2020
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* Rail Fence Cipher Encode operation
|
||||
*/
|
||||
class RailFenceCipherEncode extends Operation {
|
||||
|
||||
/**
|
||||
* RailFenceCipherEncode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Rail Fence Cipher Encode";
|
||||
this.module = "Ciphers";
|
||||
this.description = "Encodes Strings using the Rail fence Cipher provided a key and an offset";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Rail_fence_cipher";
|
||||
this.inputType = "string";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Key",
|
||||
type: "number",
|
||||
value: 2
|
||||
},
|
||||
{
|
||||
name: "Offset",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key, offset] = args;
|
||||
|
||||
const plaintext = input;
|
||||
if (key < 2) {
|
||||
throw new OperationError("Key has to be bigger than 2");
|
||||
} else if (key > plaintext.length) {
|
||||
throw new OperationError("Key should be smaller than the plain text's length");
|
||||
}
|
||||
|
||||
if (offset < 0) {
|
||||
throw new OperationError("Offset has to be a positive integer");
|
||||
}
|
||||
|
||||
const cycle = (key - 1) * 2;
|
||||
const rows = new Array(key).fill("");
|
||||
|
||||
for (let pos = 0; pos < plaintext.length; pos++) {
|
||||
const rowIdx = key - 1 - Math.abs(cycle / 2 - (pos + offset) % cycle);
|
||||
|
||||
rows[rowIdx] += plaintext[pos];
|
||||
}
|
||||
|
||||
return rows.join("").trim();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default RailFenceCipherEncode;
|
|
@ -1,10 +1,12 @@
|
|||
/**
|
||||
* @author masq [github.cyberchef@masq.cc]
|
||||
* @author n1073645
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation.mjs";
|
||||
import OperationError from "../errors/OperationError.mjs";
|
||||
|
||||
/**
|
||||
* To Case Insensitive Regex operation
|
||||
|
@ -32,7 +34,61 @@ class ToCaseInsensitiveRegex extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
return input.replace(/[a-z]/ig, m => `[${m.toLowerCase()}${m.toUpperCase()}]`);
|
||||
|
||||
/**
|
||||
* Simulates look behind behaviour since javascript doesn't support it.
|
||||
*
|
||||
* @param {string} input
|
||||
* @returns {string}
|
||||
*/
|
||||
function preProcess(input) {
|
||||
let result = "";
|
||||
for (let i = 0; i < input.length; i++) {
|
||||
const temp = input.charAt(i);
|
||||
if (temp.match(/[a-zA-Z]/g) && (input.charAt(i-1) !== "-") && (input.charAt(i+1) !== "-"))
|
||||
result += "[" + temp.toLowerCase() + temp.toUpperCase() + "]";
|
||||
else
|
||||
result += temp;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
try {
|
||||
RegExp(input);
|
||||
} catch (error) {
|
||||
throw new OperationError("Invalid Regular Expression (Please note this version of node does not support look behinds).");
|
||||
}
|
||||
|
||||
// Example: [test] -> [[tT][eE][sS][tT]]
|
||||
return preProcess(input)
|
||||
|
||||
// Example: [A-Z] -> [A-Za-z]
|
||||
.replace(/([A-Z]-[A-Z]|[a-z]-[a-z])/g, m => `${m[0].toUpperCase()}-${m[2].toUpperCase()}${m[0].toLowerCase()}-${m[2].toLowerCase()}`)
|
||||
|
||||
// Example: [H-d] -> [A-DH-dh-z]
|
||||
.replace(/[A-Z]-[a-z]/g, m => `A-${m[2].toUpperCase()}${m}${m[0].toLowerCase()}-z`)
|
||||
|
||||
// Example: [!-D] -> [!-Da-d]
|
||||
.replace(/\\?[ -@]-[A-Z]/g, m => `${m}a-${m[2].toLowerCase()}`)
|
||||
|
||||
// Example: [%-^] -> [%-^a-z]
|
||||
.replace(/\\?[ -@]-\\?[[-`]/g, m => `${m}a-z`)
|
||||
|
||||
// Example: [K-`] -> [K-`k-z]
|
||||
.replace(/[A-Z]-\\?[[-`]/g, m => `${m}${m[0].toLowerCase()}-z`)
|
||||
|
||||
// Example: [[-}] -> [[-}A-Z]
|
||||
.replace(/\\?[[-`]-\\?[{-~]/g, m => `${m}A-Z`)
|
||||
|
||||
// Example: [b-}] -> [b-}B-Z]
|
||||
.replace(/[a-z]-\\?[{-~]/g, m => `${m}${m[0].toUpperCase()}-Z`)
|
||||
|
||||
// Example: [<-j] -> [<-z]
|
||||
.replace(/\\?[ -@]-[a-z]/g, m => `${m[0]}-z`)
|
||||
|
||||
// Example: [^-j] -> [A-J^-j]
|
||||
.replace(/\\?[[-`]-[a-z]/g, m => `A-${m[2].toUpperCase()}${m}`);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,11 @@ class ToHex extends Operation {
|
|||
name: "Delimiter",
|
||||
type: "option",
|
||||
value: TO_HEX_DELIM_OPTIONS
|
||||
},
|
||||
{
|
||||
name: "Bytes per line",
|
||||
type: "number",
|
||||
value: 0
|
||||
}
|
||||
];
|
||||
}
|
||||
|
@ -40,8 +45,16 @@ class ToHex extends Operation {
|
|||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space");
|
||||
return toHex(new Uint8Array(input), delim, 2);
|
||||
let delim, comma;
|
||||
if (args[0] === "0x with comma") {
|
||||
delim = "0x";
|
||||
comma = ",";
|
||||
} else {
|
||||
delim = Utils.charRep(args[0] || "Space");
|
||||
}
|
||||
const lineSize = args[1];
|
||||
|
||||
return toHex(new Uint8Array(input), delim, 2, comma, lineSize);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -54,17 +67,31 @@ class ToHex extends Operation {
|
|||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlight(pos, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space"),
|
||||
len = delim === "\r\n" ? 1 : delim.length;
|
||||
|
||||
pos[0].start = pos[0].start * (2 + len);
|
||||
pos[0].end = pos[0].end * (2 + len) - len;
|
||||
|
||||
// 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
|
||||
if (delim === "0x" || delim === "\\x") {
|
||||
pos[0].start += 2;
|
||||
pos[0].end += 2;
|
||||
let delim, commaLen;
|
||||
if (args[0] === "0x with comma") {
|
||||
delim = "0x";
|
||||
commaLen = 1;
|
||||
} else {
|
||||
delim = Utils.charRep(args[0] || "Space");
|
||||
}
|
||||
|
||||
const lineSize = args[1],
|
||||
len = (delim === "\r\n" ? 1 : delim.length) + commaLen;
|
||||
|
||||
const countLF = function(p) {
|
||||
// Count the number of LFs from 0 upto p
|
||||
return (p / lineSize | 0) - (p >= lineSize && p % lineSize === 0);
|
||||
};
|
||||
|
||||
pos[0].start = pos[0].start * (2 + len) + countLF(pos[0].start);
|
||||
pos[0].end = pos[0].end * (2 + len) + countLF(pos[0].end);
|
||||
|
||||
// if the deliminators are not prepended, trim the trailing deliminator
|
||||
if (!(delim === "0x" || delim === "\\x")) {
|
||||
pos[0].end -= delim.length;
|
||||
}
|
||||
// if there is comma, trim the trailing comma
|
||||
pos[0].end -= commaLen;
|
||||
return pos;
|
||||
}
|
||||
|
||||
|
@ -78,20 +105,26 @@ class ToHex extends Operation {
|
|||
* @returns {Object[]} pos
|
||||
*/
|
||||
highlightReverse(pos, args) {
|
||||
const delim = Utils.charRep(args[0] || "Space"),
|
||||
len = delim === "\r\n" ? 1 : delim.length,
|
||||
width = len + 2;
|
||||
|
||||
// 0x and \x are added to the beginning if they are selected, so increment the positions accordingly
|
||||
if (delim === "0x" || delim === "\\x") {
|
||||
if (pos[0].start > 1) pos[0].start -= 2;
|
||||
else pos[0].start = 0;
|
||||
if (pos[0].end > 1) pos[0].end -= 2;
|
||||
else pos[0].end = 0;
|
||||
let delim, commaLen;
|
||||
if (args[0] === "0x with comma") {
|
||||
delim = "0x";
|
||||
commaLen = 1;
|
||||
} else {
|
||||
delim = Utils.charRep(args[0] || "Space");
|
||||
}
|
||||
|
||||
pos[0].start = pos[0].start === 0 ? 0 : Math.round(pos[0].start / width);
|
||||
pos[0].end = pos[0].end === 0 ? 0 : Math.ceil(pos[0].end / width);
|
||||
const lineSize = args[1],
|
||||
len = (delim === "\r\n" ? 1 : delim.length) + commaLen,
|
||||
width = len + 2;
|
||||
|
||||
const countLF = function(p) {
|
||||
// Count the number of LFs from 0 up to p
|
||||
const lineLength = width * lineSize;
|
||||
return (p / lineLength | 0) - (p >= lineLength && p % lineLength === 0);
|
||||
};
|
||||
|
||||
pos[0].start = pos[0].start === 0 ? 0 : Math.round((pos[0].start - countLF(pos[0].start)) / width);
|
||||
pos[0].end = pos[0].end === 0 ? 0 : Math.ceil((pos[0].end - countLF(pos[0].end)) / width);
|
||||
return pos;
|
||||
}
|
||||
}
|
||||
|
|
2
src/core/vendor/gost/gostEngine.mjs
vendored
2
src/core/vendor/gost/gostEngine.mjs
vendored
|
@ -383,7 +383,7 @@ if (root.importScripts) {
|
|||
* method with data parameter: algorithm, method and arg.<br>
|
||||
* Call method execute and postMessage() results to onmessage event handler
|
||||
* in the main process.<br>
|
||||
* If error occured onerror event handler executed in main process.
|
||||
* If error occurred onerror event handler executed in main process.
|
||||
*
|
||||
* @memberOf gostEngine
|
||||
* @name onmessage
|
||||
|
|
|
@ -197,6 +197,7 @@ class Manager {
|
|||
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
||||
this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter);
|
||||
this.addDynamicListener("#output-file-download", "click", this.output.downloadFile, this.output);
|
||||
this.addDynamicListener("#output-file-show-all", "click", this.output.showAllFile, this.output);
|
||||
this.addDynamicListener("#output-file-slice i", "click", this.output.displayFileSlice, this.output);
|
||||
document.getElementById("show-file-overlay").addEventListener("click", this.output.showFileOverlayClick.bind(this.output));
|
||||
this.addDynamicListener(".extract-file,.extract-file i", "click", this.output.extractFileClick, this.output);
|
||||
|
|
|
@ -355,15 +355,17 @@
|
|||
<div class="card-body">
|
||||
Size: <span id="output-file-size"></span><br>
|
||||
<button id="output-file-download" type="button" class="btn btn-primary btn-outline">Download</button>
|
||||
<button id="output-file-show-all" type="button" class="btn btn-warning btn-outline" data-toggle="tooltip" title="Warning: This could crash your browser. Use at your own risk.">Show all</button>
|
||||
<div class="input-group">
|
||||
<span class="input-group-btn">
|
||||
<button id="output-file-slice" type="button" class="btn btn-secondary bmd-btn-icon" title="View slice">
|
||||
<span class="input-group-prepend">
|
||||
<button id="output-file-slice" type="button" class="btn btn-secondary bmd-btn-icon" data-toggle="tooltip" title="View slice">
|
||||
<i class="material-icons">search</i>
|
||||
</button>
|
||||
</span>
|
||||
<input type="number" class="form-control" id="output-file-slice-from" placeholder="From" value="0" step="1024" min="0">
|
||||
<input type="number" class="form-control" id="output-file-slice-from" placeholder="From" value="0" step="128" min="0">
|
||||
<div class="input-group-addon">to</div>
|
||||
<input type="number" class="form-control" id="output-file-slice-to" placeholder="To" value="2048" step="1024" min="0">
|
||||
<input type="number" class="form-control" id="output-file-slice-to" placeholder="To" value="256" step="128" min="0">
|
||||
<div class="input-group-addon">KiB</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -489,6 +491,15 @@
|
|||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group option-item">
|
||||
<label for="preserveCR" class="bmd-label-floating"> Preserve carriage returns (0x0d)</label>
|
||||
<select class="form-control" option="preserveCR" id="preserveCR" data-toggle="tooltip" data-placement="bottom" data-offset="-10%" data-html="true" title="HTML textareas don't support carriage returns, so if we want to preserve them in our input, we have to disable editing.<br><br>The default option is to only do this for high-entropy inputs, but you can force the choice using this dropdown.">
|
||||
<option value="entropy">For high-entropy inputs</option>
|
||||
<option value="always">Always</option>
|
||||
<option value="never">Never</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="form-group option-item">
|
||||
<label for="errorTimeout" class="bmd-label-floating">Operation error timeout in ms (0 for never)</label>
|
||||
<input type="number" class="form-control" option="errorTimeout" id="errorTimeout">
|
||||
|
@ -573,13 +584,6 @@
|
|||
Keep the current tab in sync between the input and output
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="checkbox option-item">
|
||||
<label for="preserveCR" data-toggle="tooltip" data-placement="right" data-html="true" title="As HTML textareas don't support carriage returns, editing input must be turned off to preserve them.<br><br>When this option is enabled, editing is disabled for pasted text that contains carriage returns. Otherwise, editing will remain enabled but carriage returns will not be preserved.">
|
||||
<input type="checkbox" option="preserveCR" id="preserveCR">
|
||||
Preserve carriage returns when pasting an input
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="button" class="btn btn-secondary" id="reset-options">Reset options to default</button>
|
||||
|
|
|
@ -49,13 +49,12 @@ function main() {
|
|||
attemptHighlight: true,
|
||||
theme: "classic",
|
||||
useMetaKey: false,
|
||||
ioDisplayThreshold: 512,
|
||||
ioDisplayThreshold: 2048,
|
||||
logLevel: "info",
|
||||
autoMagic: true,
|
||||
imagePreview: true,
|
||||
syncTabs: true,
|
||||
preserveCR: true,
|
||||
userSetCR: false
|
||||
preserveCR: "entropy"
|
||||
};
|
||||
|
||||
document.removeEventListener("DOMContentLoaded", main, false);
|
||||
|
|
|
@ -98,6 +98,11 @@
|
|||
.io-card.card input[type=number] {
|
||||
padding-right: 6px;
|
||||
padding-left: 6px;
|
||||
height: unset;
|
||||
}
|
||||
|
||||
.io-card.card .input-group {
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
#files .card-header .float-right a:hover {
|
||||
|
|
|
@ -767,7 +767,9 @@ class InputWaiter {
|
|||
// and manually fire inputChange()
|
||||
inputText.value = val;
|
||||
inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length);
|
||||
this.debounceInputChange(e);
|
||||
// Don't debounce here otherwise the keyup event for the Ctrl key will cancel an autobake
|
||||
// (at least for large inputs)
|
||||
this.inputChange(e, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -858,31 +860,29 @@ class InputWaiter {
|
|||
if (input.indexOf("\r") < 0) return false;
|
||||
|
||||
const optionsStr = "This behaviour can be changed in the <a href='#' onclick='document.getElementById(\"options\").click()'>Options pane</a>";
|
||||
if (!this.app.options.userSetCR) {
|
||||
// User has not set a CR preference yet
|
||||
let preserve = await new Promise(function(resolve, reject) {
|
||||
this.app.confirm(
|
||||
"Carriage Return Detected",
|
||||
"A <a href='https://wikipedia.org/wiki/Carriage_return'>carriage return</a> (<code>\\r</code>, <code>0x0d</code>) was detected in your input. As HTML textareas <a href='https://html.spec.whatwg.org/multipage/form-elements.html#the-textarea-element'>can't display carriage returns</a>, editing must be turned off to preserve them. <br>Alternatively, you can enable editing but your carriage returns will not be preserved.<br><br>This preference will be saved but can be toggled in the options pane.",
|
||||
"Preserve Carriage Returns",
|
||||
"Enable Editing", resolve, this);
|
||||
}.bind(this));
|
||||
if (preserve === undefined) {
|
||||
// The confirm pane was closed without picking a specific choice
|
||||
this.app.alert(`Not preserving carriage returns.\n${optionsStr}`, 5000);
|
||||
preserve = false;
|
||||
}
|
||||
this.manager.options.updateOption("preserveCR", preserve);
|
||||
this.manager.options.updateOption("userSetCR", true);
|
||||
} else {
|
||||
if (this.app.options.preserveCR) {
|
||||
this.app.alert(`A carriage return (\\r, 0x0d) was detected in your input, so editing has been disabled to preserve it.<br>${optionsStr}`, 10000);
|
||||
} else {
|
||||
this.app.alert(`A carriage return (\\r, 0x0d) was detected in your input. Editing is remaining enabled, but carriage returns will not be preserved.<br>${optionsStr}`, 10000);
|
||||
}
|
||||
const preserveStr = `A carriage return (\\r, 0x0d) was detected in your input. To preserve it, editing has been disabled.<br>${optionsStr}`;
|
||||
const dontPreserveStr = `A carriage return (\\r, 0x0d) was detected in your input. It has not been preserved.<br>${optionsStr}`;
|
||||
|
||||
switch (this.app.options.preserveCR) {
|
||||
case "always":
|
||||
this.app.alert(preserveStr, 6000);
|
||||
return true;
|
||||
case "never":
|
||||
this.app.alert(dontPreserveStr, 6000);
|
||||
return false;
|
||||
}
|
||||
|
||||
return this.app.options.preserveCR;
|
||||
// Only preserve for high-entropy inputs
|
||||
const data = Utils.strToArrayBuffer(input);
|
||||
const entropy = Utils.calculateShannonEntropy(data);
|
||||
|
||||
if (entropy > 6) {
|
||||
this.app.alert(preserveStr, 6000);
|
||||
return true;
|
||||
}
|
||||
|
||||
this.app.alert(dontPreserveStr, 6000);
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -1122,8 +1122,8 @@ class OutputWaiter {
|
|||
showFileOverlay = document.getElementById("show-file-overlay"),
|
||||
sliceFromEl = document.getElementById("output-file-slice-from"),
|
||||
sliceToEl = document.getElementById("output-file-slice-to"),
|
||||
sliceFrom = parseInt(sliceFromEl.value, 10),
|
||||
sliceTo = parseInt(sliceToEl.value, 10),
|
||||
sliceFrom = parseInt(sliceFromEl.value, 10) * 1024,
|
||||
sliceTo = parseInt(sliceToEl.value, 10) * 1024,
|
||||
output = this.outputs[this.manager.tabs.getActiveOutputTab()].data;
|
||||
|
||||
let str;
|
||||
|
@ -1137,6 +1137,39 @@ class OutputWaiter {
|
|||
showFileOverlay.style.display = "block";
|
||||
outputText.value = Utils.printable(str, true);
|
||||
|
||||
outputText.style.display = "block";
|
||||
outputHtml.style.display = "none";
|
||||
outputFile.style.display = "none";
|
||||
outputHighlighter.display = "block";
|
||||
inputHighlighter.display = "block";
|
||||
|
||||
this.toggleLoader(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handler for showing an entire file at user's discretion (even if it's way too big)
|
||||
*/
|
||||
async showAllFile() {
|
||||
document.querySelector("#output-loader .loading-msg").textContent = "Loading entire file at user instruction. This may cause a crash...";
|
||||
this.toggleLoader(true);
|
||||
const outputText = document.getElementById("output-text"),
|
||||
outputHtml = document.getElementById("output-html"),
|
||||
outputFile = document.getElementById("output-file"),
|
||||
outputHighlighter = document.getElementById("output-highlighter"),
|
||||
inputHighlighter = document.getElementById("input-highlighter"),
|
||||
showFileOverlay = document.getElementById("show-file-overlay"),
|
||||
output = this.outputs[this.manager.tabs.getActiveOutputTab()].data;
|
||||
|
||||
let str;
|
||||
if (output.type === "ArrayBuffer") {
|
||||
str = Utils.arrayBufferToStr(output.result);
|
||||
} else {
|
||||
str = Utils.arrayBufferToStr(await this.getDishBuffer(output.dish));
|
||||
}
|
||||
|
||||
outputText.classList.remove("blur");
|
||||
showFileOverlay.style.display = "none";
|
||||
outputText.value = Utils.printable(str, true);
|
||||
|
||||
outputText.style.display = "block";
|
||||
outputHtml.style.display = "none";
|
||||
|
|
|
@ -51,6 +51,7 @@ class RecipeWaiter {
|
|||
}
|
||||
}.bind(this),
|
||||
onSort: function(evt) {
|
||||
this.updateZIndices();
|
||||
if (evt.from.id === "rec-list") {
|
||||
document.dispatchEvent(this.manager.statechange);
|
||||
}
|
||||
|
@ -149,6 +150,19 @@ class RecipeWaiter {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets the z-index property on each operation to make sure that operations higher in the list
|
||||
* have a higher index, meaning dropdowns are not hidden underneath subsequent operations.
|
||||
*/
|
||||
updateZIndices() {
|
||||
const operations = document.getElementById("rec-list").children;
|
||||
for (let i = 0; i < operations.length; i++) {
|
||||
const operation = operations[i];
|
||||
operation.style.zIndex = 100 + operations.length - i;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for favourite dragover events.
|
||||
* If the element being dragged is an operation, displays a visual cue so that the user knows it can
|
||||
|
@ -466,6 +480,7 @@ class RecipeWaiter {
|
|||
log.debug(`'${e.target.querySelector(".op-title").textContent}' added to recipe`);
|
||||
|
||||
this.triggerArgEvents(e.target);
|
||||
this.updateZIndices();
|
||||
window.dispatchEvent(this.manager.statechange);
|
||||
}
|
||||
|
||||
|
|
|
@ -187,8 +187,8 @@ TestRegister.addApiTests([
|
|||
const dish = new Dish([file1, file2], Dish.LIST_FILE);
|
||||
|
||||
dish.get(Dish.ARRAY_BUFFER);
|
||||
assert.deepStrictEqual(dish.value, new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b]).buffer);
|
||||
assert.strictEqual(dish.value.byteLength, 11);
|
||||
assert.deepStrictEqual(dish.value, [new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]), new Uint8Array([0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b])]);
|
||||
assert.strictEqual(dish.value.length, 2);
|
||||
|
||||
dish.get(Dish.LIST_FILE);
|
||||
const dataArray = new Uint8Array(dish.value[0].data);
|
||||
|
|
|
@ -41,8 +41,11 @@ import "./tests/DateTime.mjs";
|
|||
import "./tests/ExtractEmailAddresses.mjs";
|
||||
import "./tests/Fork.mjs";
|
||||
import "./tests/FromDecimal.mjs";
|
||||
import "./tests/Gzip.mjs";
|
||||
import "./tests/Gunzip.mjs";
|
||||
import "./tests/Hash.mjs";
|
||||
import "./tests/HaversineDistance.mjs";
|
||||
import "./tests/Hex.mjs";
|
||||
import "./tests/Hexdump.mjs";
|
||||
import "./tests/Image.mjs";
|
||||
import "./tests/IndexOfCoincidence.mjs";
|
||||
|
@ -57,6 +60,7 @@ import "./tests/MS.mjs";
|
|||
import "./tests/Magic.mjs";
|
||||
import "./tests/MorseCode.mjs";
|
||||
import "./tests/NetBIOS.mjs";
|
||||
import "./tests/NormaliseUnicode.mjs";
|
||||
import "./tests/OTP.mjs";
|
||||
import "./tests/PGP.mjs";
|
||||
import "./tests/PHP.mjs";
|
||||
|
|
|
@ -418,4 +418,114 @@ TestRegister.addTests([
|
|||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: normal",
|
||||
input: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe",
|
||||
expectedOutput: "Cryptography is THE Art of Writing or solving codes",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [2, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: key has to be bigger than 2",
|
||||
input: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe",
|
||||
expectedOutput: "Key has to be bigger than 2",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [1, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: key has to be smaller than input's length",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Key should be smaller than the cipher's length",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [22, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: offset should be positive",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Offset has to be a positive integer",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [2, -1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Decode: Normal with Offset non-null",
|
||||
input: "51746026813793592840",
|
||||
expectedOutput: "12345678901234567890",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Decode",
|
||||
"args": [4, 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: normal",
|
||||
input: "Cryptography is THE Art of Writing or solving codes",
|
||||
expectedOutput: "Cytgah sTEAto rtn rsligcdsrporpyi H r fWiigo ovn oe",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [2, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: key has to be bigger than 2",
|
||||
input: "Cryptography is THE Art of Writing or solving codes",
|
||||
expectedOutput: "Key has to be bigger than 2",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [1, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: key has to be smaller than input's length",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Key should be smaller than the plain text's length",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [22, 0]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: offset should be positive",
|
||||
input: "shortinput",
|
||||
expectedOutput: "Offset has to be a positive integer",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [2, -1]
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Rail Fence Cipher Encode: Normal with Offset non-null",
|
||||
input: "12345678901234567890",
|
||||
expectedOutput: "51746026813793592840",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Rail Fence Cipher Encode",
|
||||
"args": [4, 2]
|
||||
}
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
|
58
tests/operations/tests/Gunzip.mjs
Normal file
58
tests/operations/tests/Gunzip.mjs
Normal file
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Gunzip Tests.
|
||||
*
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Gunzip: No comment, no checksum and no filename",
|
||||
input: "1f8b0800f7c8f85d00ff0dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
expectedOutput: "The quick brown fox jumped over the slow dog",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gunzip: No comment, no checksum and filename",
|
||||
input: "1f8b080843c9f85d00ff66696c656e616d65000dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
expectedOutput: "The quick brown fox jumped over the slow dog",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gunzip: Has a comment, no checksum and has a filename",
|
||||
input: "1f8b08186fc9f85d00ff66696c656e616d6500636f6d6d656e74000dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
expectedOutput: "The quick brown fox jumped over the slow dog",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Hex",
|
||||
args: ["None"]
|
||||
},
|
||||
{
|
||||
op: "Gunzip",
|
||||
args: []
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
89
tests/operations/tests/Gzip.mjs
Normal file
89
tests/operations/tests/Gzip.mjs
Normal file
|
@ -0,0 +1,89 @@
|
|||
/**
|
||||
* Gzip Tests.
|
||||
*
|
||||
* @author n1073645 [n1073645@gmail.com]
|
||||
*
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Gzip: No comment, no checksum and no filename",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "0dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "", "", false]
|
||||
},
|
||||
{
|
||||
op: "Drop bytes",
|
||||
args: [0, 10, false]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: No comment, no checksum and has a filename",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "636f6d6d656e74000dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "comment", "", false]
|
||||
},
|
||||
{
|
||||
op: "Drop bytes",
|
||||
args: [0, 10, false]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: Has a comment, no checksum and no filename",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "636f6d6d656e74000dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "", "comment", false]
|
||||
},
|
||||
{
|
||||
op: "Drop bytes",
|
||||
args: [0, 10, false]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Gzip: Has a comment, no checksum and has a filename",
|
||||
input: "The quick brown fox jumped over the slow dog",
|
||||
expectedOutput: "66696c656e616d6500636f6d6d656e74000dc9dd0180200804e0556ea8262848fb3dc588c6a7e76faa8aeedb726036c68d951f76bf9a0af8aae1f97d9c0c084b02509cbf8c2c000000",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Gzip",
|
||||
args: ["Dynamic Huffman Coding", "filename", "comment", false]
|
||||
},
|
||||
{
|
||||
op: "Drop bytes",
|
||||
args: [0, 10, false]
|
||||
},
|
||||
{
|
||||
op: "To Hex",
|
||||
args: ["None"]
|
||||
}
|
||||
]
|
||||
},
|
||||
]);
|
97
tests/operations/tests/Hex.mjs
Normal file
97
tests/operations/tests/Hex.mjs
Normal file
|
@ -0,0 +1,97 @@
|
|||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "ASCII to Hex stream",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "6162657279737477797468",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"None",
|
||||
0
|
||||
]
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ASCII to Hex with colon deliminator ",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "61:62:65:72:79:73:74:77:79:74:68",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"Colon",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ASCII to 0x Hex with comma",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "0x61,0x62,0x65,0x72,0x79,0x73,0x74,0x77,0x79,0x74,0x68",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"0x with comma",
|
||||
0
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "ASCII to 0x Hex with comma and line breaks",
|
||||
input: "aberystwyth",
|
||||
expectedOutput: "0x61,0x62,0x65,0x72,\n0x79,0x73,0x74,0x77,\n0x79,0x74,0x68",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "To Hex",
|
||||
"args": [
|
||||
"0x with comma",
|
||||
4
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Hex stream to UTF-8",
|
||||
input: "e69591e69591e5ada9e5ad90",
|
||||
expectedOutput: "救救孩子",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": [
|
||||
"Auto"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
},
|
||||
{
|
||||
name: "Multiline 0x hex to ASCII",
|
||||
input: "0x49,0x20,0x73,0x61,0x77,0x20,0x6d,0x79,0x73,0x65,0x6c,0x66,0x20,0x73,0x69,\
|
||||
0x74,0x74,0x69,0x6e,0x67,0x20,0x69,0x6e,0x20,0x74,0x68,0x65,0x20,0x63,0x72,\
|
||||
0x6f,0x74,0x63,0x68,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x74,0x68,0x69,\
|
||||
0x73,0x20,0x66,0x69,0x67,0x20,0x74,0x72,0x65,0x65,0x2c,0x20,0x73,0x74,0x61,\
|
||||
0x72,0x76,0x69,0x6e,0x67,0x20,0x74,0x6f,0x20,0x64,0x65,0x61,0x74,0x68,0x2c,\
|
||||
0x20,0x6a,0x75,0x73,0x74,0x20,0x62,0x65,0x63,0x61,0x75,0x73,0x65,0x20,0x49,\
|
||||
0x20,0x63,0x6f,0x75,0x6c,0x64,0x6e,0x27,0x74,0x20,0x6d,0x61,0x6b,0x65,0x20,\
|
||||
0x75,0x70,0x20,0x6d,0x79,0x20,0x6d,0x69,0x6e,0x64,0x20,0x77,0x68,0x69,0x63,\
|
||||
0x68,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x66,0x69,0x67,0x73,0x20,0x49,\
|
||||
0x20,0x77,0x6f,0x75,0x6c,0x64,0x20,0x63,0x68,0x6f,0x6f,0x73,0x65,0x2e",
|
||||
expectedOutput: "I saw myself sitting in the crotch of the this fig tree, starving to death, just because I couldn't make up my mind which of the figs I would choose.",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "From Hex",
|
||||
"args": [
|
||||
"Auto"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
}
|
||||
]);
|
54
tests/operations/tests/NormaliseUnicode.mjs
Normal file
54
tests/operations/tests/NormaliseUnicode.mjs
Normal file
|
@ -0,0 +1,54 @@
|
|||
/**
|
||||
* Text Encoding Brute Force tests.
|
||||
*
|
||||
* @author Matthieu [m@tthieux.xyz]
|
||||
*
|
||||
* @copyright Crown Copyright 2019
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../lib/TestRegister.mjs";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Normalise Unicode - NFD",
|
||||
input: "\u00c7\u0043\u0327\u2160",
|
||||
expectedMatch: /C\u0327C\u0327\u2160/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Normalise Unicode",
|
||||
args: ["NFD"],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Normalise Unicode - NFC",
|
||||
input: "\u00c7\u0043\u0327\u2160",
|
||||
expectedMatch: /\u00C7\u00C7\u2160/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Normalise Unicode",
|
||||
args: ["NFC"],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Normalise Unicode - NFKD",
|
||||
input: "\u00c7\u0043\u0327\u2160",
|
||||
expectedMatch: /C\u0327C\u0327I/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Normalise Unicode",
|
||||
args: ["NFKD"],
|
||||
},
|
||||
],
|
||||
}, {
|
||||
name: "Normalise Unicode - NFKC",
|
||||
input: "\u00c7\u0043\u0327\u2160",
|
||||
expectedMatch: /\u00C7\u00C7\u2160/,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "Normalise Unicode",
|
||||
args: ["NFKC"],
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
|
@ -53,4 +53,136 @@ TestRegister.addTests([
|
|||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [A-Z] -> [A-Za-z]",
|
||||
input: "[A-Z]",
|
||||
expectedOutput: "[A-Za-z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [a-z] -> [A-Za-z]",
|
||||
input: "[a-z]",
|
||||
expectedOutput: "[A-Za-z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [H-d] -> [A-DH-dh-z]",
|
||||
input: "[H-d]",
|
||||
expectedOutput: "[A-DH-dh-z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [!-D] -> [!-Da-d]",
|
||||
input: "[!-D]",
|
||||
expectedOutput: "[!-Da-d]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [%-^] -> [%-^a-z]",
|
||||
input: "[%-^]",
|
||||
expectedOutput: "[%-^a-z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [K-`] -> [K-`k-z]",
|
||||
input: "[K-`]",
|
||||
expectedOutput: "[K-`k-z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [[-}] -> [[-}A-Z]",
|
||||
input: "[[-}]",
|
||||
expectedOutput: "[[-}A-Z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [b-}] -> [b-}B-Z]",
|
||||
input: "[b-}]",
|
||||
expectedOutput: "[b-}B-Z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [<-j] -> [<-z]",
|
||||
input: "[<-j]",
|
||||
expectedOutput: "[<-z]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: [^-j] -> [A-J^-j]",
|
||||
input: "[^-j]",
|
||||
expectedOutput: "[A-J^-j]",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: not simple test",
|
||||
input: "Mozilla[A-Z0-9]+[A-Z]Mozilla[0-9whatA-Z][H-d][!-H][a-~](.)+",
|
||||
expectedOutput: "[mM][oO][zZ][iI][lL][lL][aA][A-Za-z0-9]+[A-Za-z][mM][oO][zZ][iI][lL][lL][aA][0-9[wW][hH][aA][tT]A-Za-z][A-DH-dh-z][!-Ha-h][a-~A-Z](.)+",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Case Insensitive Regex: erroneous test",
|
||||
input: "Mozilla[A-Z",
|
||||
expectedOutput: "Invalid Regular Expression (Please note this version of node does not support look behinds).",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Case Insensitive Regex",
|
||||
args: [],
|
||||
},
|
||||
],
|
||||
}
|
||||
]);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue