mirror of
https://github.com/gchq/CyberChef
synced 2026-01-06 10:33:18 +00:00
Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
118f0130d8 | ||
|
|
e77d3a4b7d | ||
|
|
bf0bd620f1 | ||
|
|
62edd76d7e | ||
|
|
cef6585cab | ||
|
|
481241b88d | ||
|
|
93c0c7cc10 | ||
|
|
01d9536bbd | ||
|
|
24a7c75926 | ||
|
|
c2eea7a9f7 | ||
|
|
e2812cadb5 | ||
|
|
cde958af16 | ||
|
|
bf70589b3c | ||
|
|
78d1114869 | ||
|
|
ab83caa77b | ||
|
|
42dd03bb84 | ||
|
|
cb09949fb9 | ||
|
|
0c6eac3b21 | ||
|
|
5e771c521c | ||
|
|
b8afbf7458 | ||
|
|
be59efbd6b | ||
|
|
99ccd06f23 | ||
|
|
f4d75f88a9 | ||
|
|
9112bd4936 | ||
|
|
3e513efd59 | ||
|
|
4100a22c7f | ||
|
|
71078d9332 | ||
|
|
72ba579e1e | ||
|
|
5fd2512a9b | ||
|
|
3a1a6a94d2 | ||
|
|
928178716a | ||
|
|
08419a20c0 | ||
|
|
60506ee2d1 | ||
|
|
6e411c9dd9 | ||
|
|
86db43e6dd | ||
|
|
252ac0bdaa | ||
|
|
4d8b1721bc | ||
|
|
fd390bc61b | ||
|
|
813a151524 | ||
|
|
c06502cd76 | ||
|
|
974ce1fd12 | ||
|
|
d2dc50fe8e | ||
|
|
ec50105e34 | ||
|
|
86ebed132d | ||
|
|
47ccafcbb2 | ||
|
|
798f013219 | ||
|
|
61e6423d95 | ||
|
|
44c2b71e6c | ||
|
|
b806be3f49 | ||
|
|
2750284eea | ||
|
|
5366f1a2eb | ||
|
|
b459c15d74 | ||
|
|
8a02b35d7d | ||
|
|
d4441823aa | ||
|
|
13e9a4f0da | ||
|
|
33471a33d6 | ||
|
|
8e5aa2c393 | ||
|
|
1118ff598d | ||
|
|
09e93b4639 | ||
|
|
d16bbe1e7e | ||
|
|
4814922e67 | ||
|
|
81d1007bb7 | ||
|
|
610d46a1a4 | ||
|
|
f7acef4642 | ||
|
|
fd5b6c5243 | ||
|
|
a8917e4713 | ||
|
|
04036e001e | ||
|
|
725b0d42f8 | ||
|
|
071c1bdea6 | ||
|
|
7386c145ef | ||
|
|
25ca8d85a6 | ||
|
|
c60ed2c403 | ||
|
|
7d41d4d030 | ||
|
|
6d77fe6eb3 | ||
|
|
40d3c8b071 | ||
|
|
02ec4a3bfd | ||
|
|
7a4ebbf47e | ||
|
|
2e7ce477d7 | ||
|
|
c1a22ef639 | ||
|
|
0a7b78b7ee | ||
|
|
e1cb62848c | ||
|
|
acf5c733c2 | ||
|
|
7c25e29515 | ||
|
|
7c72871c02 | ||
|
|
ddb77c6ab3 | ||
|
|
8502fd246d | ||
|
|
30c6917914 | ||
|
|
33464b3388 | ||
|
|
2205637ad6 | ||
|
|
149198ef1c | ||
|
|
2c40353180 | ||
|
|
69c6c3e790 |
@@ -47,6 +47,7 @@
|
|||||||
"block-spacing": "error",
|
"block-spacing": "error",
|
||||||
"array-bracket-spacing": "error",
|
"array-bracket-spacing": "error",
|
||||||
"comma-spacing": "error",
|
"comma-spacing": "error",
|
||||||
|
"spaced-comment": ["error", "always", { "exceptions": ["/"] } ],
|
||||||
"comma-style": "error",
|
"comma-style": "error",
|
||||||
"computed-property-spacing": "error",
|
"computed-property-spacing": "error",
|
||||||
"no-trailing-spaces": "warn",
|
"no-trailing-spaces": "warn",
|
||||||
|
|||||||
114
Gruntfile.js
114
Gruntfile.js
@@ -26,7 +26,7 @@ module.exports = function (grunt) {
|
|||||||
grunt.registerTask("prod",
|
grunt.registerTask("prod",
|
||||||
"Creates a production-ready build. Use the --msg flag to add a compile message.",
|
"Creates a production-ready build. Use the --msg flag to add a compile message.",
|
||||||
[
|
[
|
||||||
"eslint", "clean:prod", "clean:config", "exec:generateConfig", "webpack:web",
|
"eslint", "clean:prod", "clean:config", "exec:generateConfig", "findModules", "webpack:web",
|
||||||
"copy:standalone", "zip:standalone", "clean:standalone", "chmod"
|
"copy:standalone", "zip:standalone", "clean:standalone", "chmod"
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@@ -58,6 +58,19 @@ module.exports = function (grunt) {
|
|||||||
grunt.registerTask("tests", "test");
|
grunt.registerTask("tests", "test");
|
||||||
grunt.registerTask("lint", "eslint");
|
grunt.registerTask("lint", "eslint");
|
||||||
|
|
||||||
|
grunt.registerTask("findModules",
|
||||||
|
"Finds all generated modules and updates the entry point list for Webpack",
|
||||||
|
function(arg1, arg2) {
|
||||||
|
const moduleEntryPoints = listEntryModules();
|
||||||
|
|
||||||
|
grunt.log.writeln(`Found ${Object.keys(moduleEntryPoints).length} modules.`);
|
||||||
|
|
||||||
|
grunt.config.set("webpack.web.entry",
|
||||||
|
Object.assign({
|
||||||
|
main: "./src/web/index.js"
|
||||||
|
}, moduleEntryPoints));
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
// Load tasks provided by each plugin
|
// Load tasks provided by each plugin
|
||||||
grunt.loadNpmTasks("grunt-eslint");
|
grunt.loadNpmTasks("grunt-eslint");
|
||||||
@@ -83,7 +96,53 @@ module.exports = function (grunt) {
|
|||||||
PKG_VERSION: JSON.stringify(pkg.version),
|
PKG_VERSION: JSON.stringify(pkg.version),
|
||||||
},
|
},
|
||||||
moduleEntryPoints = listEntryModules(),
|
moduleEntryPoints = listEntryModules(),
|
||||||
nodeConsumerTestPath = "~/tmp-cyberchef";
|
nodeConsumerTestPath = "~/tmp-cyberchef",
|
||||||
|
/**
|
||||||
|
* Configuration for Webpack production build. Defined as a function so that it
|
||||||
|
* can be recalculated when new modules are generated.
|
||||||
|
*/
|
||||||
|
webpackProdConf = () => {
|
||||||
|
return {
|
||||||
|
mode: "production",
|
||||||
|
target: "web",
|
||||||
|
entry: Object.assign({
|
||||||
|
main: "./src/web/index.js"
|
||||||
|
}, moduleEntryPoints),
|
||||||
|
output: {
|
||||||
|
path: __dirname + "/build/prod",
|
||||||
|
filename: chunkData => {
|
||||||
|
return chunkData.chunk.name === "main" ? "assets/[name].js": "[name].js";
|
||||||
|
},
|
||||||
|
globalObject: "this"
|
||||||
|
},
|
||||||
|
resolve: {
|
||||||
|
alias: {
|
||||||
|
"./config/modules/OpModules.mjs": "./config/modules/Default.mjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.DefinePlugin(BUILD_CONSTANTS),
|
||||||
|
new HtmlWebpackPlugin({
|
||||||
|
filename: "index.html",
|
||||||
|
template: "./src/web/html/index.html",
|
||||||
|
chunks: ["main"],
|
||||||
|
compileTime: compileTime,
|
||||||
|
version: pkg.version,
|
||||||
|
minify: {
|
||||||
|
removeComments: true,
|
||||||
|
collapseWhitespace: true,
|
||||||
|
minifyJS: true,
|
||||||
|
minifyCSS: true
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
new BundleAnalyzerPlugin({
|
||||||
|
analyzerMode: "static",
|
||||||
|
reportFilename: "BundleAnalyzerReport.html",
|
||||||
|
openAnalyzer: false
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -154,48 +213,7 @@ module.exports = function (grunt) {
|
|||||||
},
|
},
|
||||||
webpack: {
|
webpack: {
|
||||||
options: webpackConfig,
|
options: webpackConfig,
|
||||||
web: () => {
|
web: webpackProdConf(),
|
||||||
return {
|
|
||||||
mode: "production",
|
|
||||||
target: "web",
|
|
||||||
entry: Object.assign({
|
|
||||||
main: "./src/web/index.js"
|
|
||||||
}, moduleEntryPoints),
|
|
||||||
output: {
|
|
||||||
path: __dirname + "/build/prod",
|
|
||||||
filename: chunkData => {
|
|
||||||
return chunkData.chunk.name === "main" ? "assets/[name].js": "[name].js";
|
|
||||||
},
|
|
||||||
globalObject: "this"
|
|
||||||
},
|
|
||||||
resolve: {
|
|
||||||
alias: {
|
|
||||||
"./config/modules/OpModules.mjs": "./config/modules/Default.mjs"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
new webpack.DefinePlugin(BUILD_CONSTANTS),
|
|
||||||
new HtmlWebpackPlugin({
|
|
||||||
filename: "index.html",
|
|
||||||
template: "./src/web/html/index.html",
|
|
||||||
chunks: ["main"],
|
|
||||||
compileTime: compileTime,
|
|
||||||
version: pkg.version,
|
|
||||||
minify: {
|
|
||||||
removeComments: true,
|
|
||||||
collapseWhitespace: true,
|
|
||||||
minifyJS: true,
|
|
||||||
minifyCSS: true
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
new BundleAnalyzerPlugin({
|
|
||||||
analyzerMode: "static",
|
|
||||||
reportFilename: "BundleAnalyzerReport.html",
|
|
||||||
openAnalyzer: false
|
|
||||||
}),
|
|
||||||
]
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
"webpack-dev-server": {
|
"webpack-dev-server": {
|
||||||
options: {
|
options: {
|
||||||
@@ -345,7 +363,8 @@ module.exports = function (grunt) {
|
|||||||
command: "git gc --prune=now --aggressive"
|
command: "git gc --prune=now --aggressive"
|
||||||
},
|
},
|
||||||
sitemap: {
|
sitemap: {
|
||||||
command: "node --experimental-modules --no-warnings --no-deprecation src/web/static/sitemap.mjs > build/prod/sitemap.xml"
|
command: "node --experimental-modules --no-warnings --no-deprecation src/web/static/sitemap.mjs > build/prod/sitemap.xml",
|
||||||
|
sync: true
|
||||||
},
|
},
|
||||||
generateConfig: {
|
generateConfig: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
@@ -354,7 +373,8 @@ module.exports = function (grunt) {
|
|||||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
|
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
|
||||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
|
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
|
||||||
"echo '--- Config scripts finished. ---\n'"
|
"echo '--- Config scripts finished. ---\n'"
|
||||||
])
|
]),
|
||||||
|
sync: true
|
||||||
},
|
},
|
||||||
generateNodeIndex: {
|
generateNodeIndex: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
@@ -362,6 +382,7 @@ module.exports = function (grunt) {
|
|||||||
"node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
|
"node --experimental-modules --no-warnings --no-deprecation src/node/config/scripts/generateNodeIndex.mjs",
|
||||||
"echo '--- Node index generated. ---\n'"
|
"echo '--- Node index generated. ---\n'"
|
||||||
]),
|
]),
|
||||||
|
sync: true
|
||||||
},
|
},
|
||||||
opTests: {
|
opTests: {
|
||||||
command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
|
command: "node --experimental-modules --no-warnings --no-deprecation tests/operations/index.mjs"
|
||||||
@@ -381,6 +402,7 @@ module.exports = function (grunt) {
|
|||||||
`cd ${nodeConsumerTestPath}`,
|
`cd ${nodeConsumerTestPath}`,
|
||||||
"npm link cyberchef"
|
"npm link cyberchef"
|
||||||
]),
|
]),
|
||||||
|
sync: true
|
||||||
},
|
},
|
||||||
teardownNodeConsumers: {
|
teardownNodeConsumers: {
|
||||||
command: chainCommands([
|
command: chainCommands([
|
||||||
|
|||||||
5222
package-lock.json
generated
5222
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
74
package.json
74
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cyberchef",
|
"name": "cyberchef",
|
||||||
"version": "9.11.4",
|
"version": "9.11.20",
|
||||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||||
"author": "n1474335 <n1474335@gmail.com>",
|
"author": "n1474335 <n1474335@gmail.com>",
|
||||||
"homepage": "https://gchq.github.io/CyberChef",
|
"homepage": "https://gchq.github.io/CyberChef",
|
||||||
@@ -36,26 +36,26 @@
|
|||||||
"node >= 10"
|
"node >= 10"
|
||||||
],
|
],
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.5.5",
|
"@babel/core": "^7.7.5",
|
||||||
"@babel/plugin-transform-runtime": "^7.5.5",
|
"@babel/plugin-transform-runtime": "^7.7.6",
|
||||||
"@babel/preset-env": "^7.5.5",
|
"@babel/preset-env": "^7.7.6",
|
||||||
"autoprefixer": "^9.6.1",
|
"autoprefixer": "^9.7.3",
|
||||||
"babel-eslint": "^10.0.3",
|
"babel-eslint": "^10.0.3",
|
||||||
"babel-loader": "^8.0.6",
|
"babel-loader": "^8.0.6",
|
||||||
"babel-plugin-dynamic-import-node": "^2.3.0",
|
"babel-plugin-dynamic-import-node": "^2.3.0",
|
||||||
"chromedriver": "^77.0.0",
|
"chromedriver": "^78.0.1",
|
||||||
"colors": "^1.3.3",
|
"colors": "^1.4.0",
|
||||||
"copy-webpack-plugin": "^5.0.4",
|
"copy-webpack-plugin": "^5.0.5",
|
||||||
"css-loader": "^3.2.0",
|
"css-loader": "^3.2.1",
|
||||||
"eslint": "^6.2.2",
|
"eslint": "^6.7.2",
|
||||||
"exports-loader": "^0.7.0",
|
"exports-loader": "^0.7.0",
|
||||||
"file-loader": "^4.2.0",
|
"file-loader": "^5.0.2",
|
||||||
"grunt": "^1.0.4",
|
"grunt": "^1.0.4",
|
||||||
"grunt-accessibility": "~6.0.0",
|
"grunt-accessibility": "~6.0.0",
|
||||||
"grunt-chmod": "~1.1.1",
|
"grunt-chmod": "~1.1.1",
|
||||||
"grunt-concurrent": "^3.0.0",
|
"grunt-concurrent": "^3.0.0",
|
||||||
"grunt-contrib-clean": "~2.0.0",
|
"grunt-contrib-clean": "~2.0.0",
|
||||||
"grunt-contrib-connect": "^2.0.0",
|
"grunt-contrib-connect": "^2.1.0",
|
||||||
"grunt-contrib-copy": "~1.0.0",
|
"grunt-contrib-copy": "~1.0.0",
|
||||||
"grunt-contrib-watch": "^1.1.0",
|
"grunt-contrib-watch": "^1.1.0",
|
||||||
"grunt-eslint": "^22.0.0",
|
"grunt-eslint": "^22.0.0",
|
||||||
@@ -65,43 +65,43 @@
|
|||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
"imports-loader": "^0.8.0",
|
"imports-loader": "^0.8.0",
|
||||||
"mini-css-extract-plugin": "^0.8.0",
|
"mini-css-extract-plugin": "^0.8.0",
|
||||||
"nightwatch": "^1.2.1",
|
"nightwatch": "^1.3.2",
|
||||||
"node-sass": "^4.12.0",
|
"node-sass": "^4.13.0",
|
||||||
"postcss-css-variables": "^0.13.0",
|
"postcss-css-variables": "^0.14.0",
|
||||||
"postcss-import": "^12.0.1",
|
"postcss-import": "^12.0.1",
|
||||||
"postcss-loader": "^3.0.0",
|
"postcss-loader": "^3.0.0",
|
||||||
"prompt": "^1.0.0",
|
"prompt": "^1.0.0",
|
||||||
"sass-loader": "^8.0.0",
|
"sass-loader": "^8.0.0",
|
||||||
"sitemap": "^4.1.1",
|
"sitemap": "^5.1.0",
|
||||||
"style-loader": "^1.0.0",
|
"style-loader": "^1.0.1",
|
||||||
"svg-url-loader": "^3.0.1",
|
"svg-url-loader": "^3.0.3",
|
||||||
"url-loader": "^2.1.0",
|
"url-loader": "^3.0.0",
|
||||||
"webpack": "^4.39.3",
|
"webpack": "^4.41.2",
|
||||||
"webpack-bundle-analyzer": "^3.4.1",
|
"webpack-bundle-analyzer": "^3.6.0",
|
||||||
"webpack-dev-server": "^3.8.0",
|
"webpack-dev-server": "^3.9.0",
|
||||||
"webpack-node-externals": "^1.7.2",
|
"webpack-node-externals": "^1.7.2",
|
||||||
"worker-loader": "^2.0.0"
|
"worker-loader": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/polyfill": "^7.4.4",
|
"@babel/polyfill": "^7.7.0",
|
||||||
"@babel/runtime": "^7.5.5",
|
"@babel/runtime": "^7.7.6",
|
||||||
"arrive": "^2.4.1",
|
"arrive": "^2.4.1",
|
||||||
"avsc": "^5.4.16",
|
"avsc": "^5.4.16",
|
||||||
"babel-plugin-transform-builtin-extend": "1.1.2",
|
"babel-plugin-transform-builtin-extend": "1.1.2",
|
||||||
"bcryptjs": "^2.4.3",
|
"bcryptjs": "^2.4.3",
|
||||||
"bignumber.js": "^9.0.0",
|
"bignumber.js": "^9.0.0",
|
||||||
"blakejs": "^1.1.0",
|
"blakejs": "^1.1.0",
|
||||||
"bootstrap": "4.3.1",
|
"bootstrap": "4.4.1",
|
||||||
"bootstrap-colorpicker": "^3.1.2",
|
"bootstrap-colorpicker": "^3.2.0",
|
||||||
"bootstrap-material-design": "^4.1.2",
|
"bootstrap-material-design": "^4.1.2",
|
||||||
"bson": "^4.0.2",
|
"bson": "^4.0.2",
|
||||||
"chi-squared": "^1.1.0",
|
"chi-squared": "^1.1.0",
|
||||||
"codepage": "^1.14.0",
|
"codepage": "^1.14.0",
|
||||||
"core-js": "^3.2.1",
|
"core-js": "^3.4.8",
|
||||||
"crypto-api": "^0.8.5",
|
"crypto-api": "^0.8.5",
|
||||||
"crypto-js": "^3.1.9-1",
|
"crypto-js": "^3.1.9-1",
|
||||||
"ctph.js": "0.0.5",
|
"ctph.js": "0.0.5",
|
||||||
"d3": "^5.11.0",
|
"d3": "^5.14.2",
|
||||||
"d3-hexbin": "^0.2.2",
|
"d3-hexbin": "^0.2.2",
|
||||||
"diff": "^4.0.1",
|
"diff": "^4.0.1",
|
||||||
"es6-promisify": "^6.0.2",
|
"es6-promisify": "^6.0.2",
|
||||||
@@ -112,8 +112,8 @@
|
|||||||
"exif-parser": "^0.1.12",
|
"exif-parser": "^0.1.12",
|
||||||
"file-saver": "^2.0.2",
|
"file-saver": "^2.0.2",
|
||||||
"geodesy": "^1.1.3",
|
"geodesy": "^1.1.3",
|
||||||
"highlight.js": "^9.15.10",
|
"highlight.js": "^9.16.2",
|
||||||
"jimp": "^0.6.4",
|
"jimp": "^0.9.3",
|
||||||
"jquery": "3.4.1",
|
"jquery": "3.4.1",
|
||||||
"js-crc": "^0.2.0",
|
"js-crc": "^0.2.0",
|
||||||
"js-sha3": "^0.8.0",
|
"js-sha3": "^0.8.0",
|
||||||
@@ -122,27 +122,27 @@
|
|||||||
"jsonwebtoken": "^8.5.1",
|
"jsonwebtoken": "^8.5.1",
|
||||||
"jsqr": "^1.2.0",
|
"jsqr": "^1.2.0",
|
||||||
"jsrsasign": "8.0.12",
|
"jsrsasign": "8.0.12",
|
||||||
"kbpgp": "2.1.3",
|
"kbpgp": "2.1.6",
|
||||||
"libbzip2-wasm": "0.0.4",
|
"libbzip2-wasm": "0.0.4",
|
||||||
"libyara-wasm": "^1.0.1",
|
"libyara-wasm": "^1.0.1",
|
||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"loglevel": "^1.6.3",
|
"loglevel": "^1.6.6",
|
||||||
"loglevel-message-prefix": "^3.0.0",
|
"loglevel-message-prefix": "^3.0.0",
|
||||||
"markdown-it": "^9.1.0",
|
"markdown-it": "^10.0.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.26",
|
"moment-timezone": "^0.5.27",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
"node-forge": "^0.9.1",
|
"node-forge": "^0.9.1",
|
||||||
"node-md6": "^0.1.0",
|
"node-md6": "^0.1.0",
|
||||||
"nodom": "^2.2.0",
|
"nodom": "^2.4.0",
|
||||||
"notepack.io": "^2.2.0",
|
"notepack.io": "^2.2.0",
|
||||||
"nwmatcher": "^1.4.4",
|
"nwmatcher": "^1.4.4",
|
||||||
"otp": "^0.1.3",
|
"otp": "^0.1.3",
|
||||||
"popper.js": "^1.15.0",
|
"popper.js": "^1.16.0",
|
||||||
"qr-image": "^3.2.0",
|
"qr-image": "^3.2.0",
|
||||||
"scryptsy": "^2.1.0",
|
"scryptsy": "^2.1.0",
|
||||||
"snackbarjs": "^1.1.0",
|
"snackbarjs": "^1.1.0",
|
||||||
"sortablejs": "^1.9.0",
|
"sortablejs": "^1.10.1",
|
||||||
"split.js": "^1.5.11",
|
"split.js": "^1.5.11",
|
||||||
"ssdeep.js": "0.0.2",
|
"ssdeep.js": "0.0.2",
|
||||||
"tesseract.js": "^2.0.0-alpha.15",
|
"tesseract.js": "^2.0.0-alpha.15",
|
||||||
|
|||||||
@@ -73,10 +73,10 @@ class Chef {
|
|||||||
// The threshold is specified in KiB.
|
// The threshold is specified in KiB.
|
||||||
const threshold = (options.ioDisplayThreshold || 1024) * 1024;
|
const threshold = (options.ioDisplayThreshold || 1024) * 1024;
|
||||||
const returnType =
|
const returnType =
|
||||||
this.dish.size > threshold ?
|
this.dish.type === Dish.HTML ?
|
||||||
Dish.ARRAY_BUFFER :
|
Dish.HTML :
|
||||||
this.dish.type === Dish.HTML ?
|
this.dish.size > threshold ?
|
||||||
Dish.HTML :
|
Dish.ARRAY_BUFFER :
|
||||||
Dish.STRING;
|
Dish.STRING;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -591,6 +591,44 @@ class Utils {
|
|||||||
return utf8 ? Utils.byteArrayToUtf8(arr) : Utils.byteArrayToChars(arr);
|
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.
|
* Parses CSV data and returns it as a two dimensional array or strings.
|
||||||
@@ -758,15 +796,15 @@ class Utils {
|
|||||||
"%7E": "~",
|
"%7E": "~",
|
||||||
"%21": "!",
|
"%21": "!",
|
||||||
"%24": "$",
|
"%24": "$",
|
||||||
//"%26": "&",
|
// "%26": "&",
|
||||||
"%27": "'",
|
"%27": "'",
|
||||||
"%28": "(",
|
"%28": "(",
|
||||||
"%29": ")",
|
"%29": ")",
|
||||||
"%2A": "*",
|
"%2A": "*",
|
||||||
//"%2B": "+",
|
// "%2B": "+",
|
||||||
"%2C": ",",
|
"%2C": ",",
|
||||||
"%3B": ";",
|
"%3B": ";",
|
||||||
//"%3D": "=",
|
// "%3D": "=",
|
||||||
"%3A": ":",
|
"%3A": ":",
|
||||||
"%40": "@",
|
"%40": "@",
|
||||||
"%2F": "/",
|
"%2F": "/",
|
||||||
@@ -1335,14 +1373,14 @@ export function debounce(func, wait, id, scope, args) {
|
|||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart
|
||||||
if (!String.prototype.padStart) {
|
if (!String.prototype.padStart) {
|
||||||
String.prototype.padStart = function padStart(targetLength, padString) {
|
String.prototype.padStart = function padStart(targetLength, padString) {
|
||||||
targetLength = targetLength>>0; //floor if number or convert non-number to 0;
|
targetLength = targetLength>>0; // floor if number or convert non-number to 0;
|
||||||
padString = String((typeof padString !== "undefined" ? padString : " "));
|
padString = String((typeof padString !== "undefined" ? padString : " "));
|
||||||
if (this.length > targetLength) {
|
if (this.length > targetLength) {
|
||||||
return String(this);
|
return String(this);
|
||||||
} else {
|
} else {
|
||||||
targetLength = targetLength-this.length;
|
targetLength = targetLength-this.length;
|
||||||
if (targetLength > padString.length) {
|
if (targetLength > padString.length) {
|
||||||
padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
|
padString += padString.repeat(targetLength/padString.length); // append to original to ensure we are longer than needed
|
||||||
}
|
}
|
||||||
return padString.slice(0, targetLength) + String(this);
|
return padString.slice(0, targetLength) + String(this);
|
||||||
}
|
}
|
||||||
@@ -1354,14 +1392,14 @@ if (!String.prototype.padStart) {
|
|||||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd
|
||||||
if (!String.prototype.padEnd) {
|
if (!String.prototype.padEnd) {
|
||||||
String.prototype.padEnd = function padEnd(targetLength, padString) {
|
String.prototype.padEnd = function padEnd(targetLength, padString) {
|
||||||
targetLength = targetLength>>0; //floor if number or convert non-number to 0;
|
targetLength = targetLength>>0; // floor if number or convert non-number to 0;
|
||||||
padString = String((typeof padString !== "undefined" ? padString : " "));
|
padString = String((typeof padString !== "undefined" ? padString : " "));
|
||||||
if (this.length > targetLength) {
|
if (this.length > targetLength) {
|
||||||
return String(this);
|
return String(this);
|
||||||
} else {
|
} else {
|
||||||
targetLength = targetLength-this.length;
|
targetLength = targetLength-this.length;
|
||||||
if (targetLength > padString.length) {
|
if (targetLength > padString.length) {
|
||||||
padString += padString.repeat(targetLength/padString.length); //append to original to ensure we are longer than needed
|
padString += padString.repeat(targetLength/padString.length); // append to original to ensure we are longer than needed
|
||||||
}
|
}
|
||||||
return String(this) + padString.slice(0, targetLength);
|
return String(this) + padString.slice(0, targetLength);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*eslint no-console: ["off"] */
|
/* eslint no-console: ["off"] */
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*eslint no-console: ["off"] */
|
/* eslint no-console: ["off"] */
|
||||||
|
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*eslint no-console: ["off"] */
|
/* eslint no-console: ["off"] */
|
||||||
|
|
||||||
import prompt from "prompt";
|
import prompt from "prompt";
|
||||||
import colors from "colors";
|
import colors from "colors";
|
||||||
@@ -208,7 +208,7 @@ ${result.highlight ? `
|
|||||||
export default ${moduleName};
|
export default ${moduleName};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
//console.log(template);
|
// console.log(template);
|
||||||
|
|
||||||
const filename = path.join(dir, `./${moduleName}.mjs`);
|
const filename = path.join(dir, `./${moduleName}.mjs`);
|
||||||
if (fs.existsSync(filename)) {
|
if (fs.existsSync(filename)) {
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import DishType from "./DishType.mjs";
|
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
|
* convert the given value to a ArrayBuffer
|
||||||
*/
|
*/
|
||||||
static toArrayBuffer() {
|
static async toArrayBuffer() {
|
||||||
DishListFile.checkForValue(this.value);
|
DishListFile.checkForValue(this.value);
|
||||||
|
|
||||||
if (isNodeEnvironment()) {
|
if (isNodeEnvironment()) {
|
||||||
this.value = this.value.map(file => Uint8Array.from(file.data));
|
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")];
|
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
|
* Concatenates a list of Uint8Arrays together
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ export const ALPHABET_OPTIONS = [
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "IPv6",
|
name: "IPv6",
|
||||||
value: "0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|~}",
|
value: "0-9A-Za-z!#$%&()*+\\-;<=>?@^_`{|}~",
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -280,7 +280,7 @@ export const FILE_SIGNATURES = {
|
|||||||
9: 0x0,
|
9: 0x0,
|
||||||
10: [0x0, 0x1]
|
10: [0x0, 0x1]
|
||||||
},
|
},
|
||||||
extractor: null
|
extractor: extractICO
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Radiance High Dynamic Range image",
|
name: "Radiance High Dynamic Range image",
|
||||||
@@ -1008,8 +1008,7 @@ export const FILE_SIGNATURES = {
|
|||||||
0: 0x7b,
|
0: 0x7b,
|
||||||
1: 0x5c,
|
1: 0x5c,
|
||||||
2: 0x72,
|
2: 0x72,
|
||||||
3: 0x74,
|
3: 0x74
|
||||||
4: 0x66
|
|
||||||
},
|
},
|
||||||
extractor: extractRTF
|
extractor: extractRTF
|
||||||
},
|
},
|
||||||
@@ -1282,17 +1281,30 @@ export const FILE_SIGNATURES = {
|
|||||||
extension: "dylib",
|
extension: "dylib",
|
||||||
mime: "application/octet-stream",
|
mime: "application/octet-stream",
|
||||||
description: "",
|
description: "",
|
||||||
signature: {
|
signature: [
|
||||||
0: 0xca,
|
{
|
||||||
1: 0xfe,
|
0: 0xca,
|
||||||
2: 0xba,
|
1: 0xfe,
|
||||||
3: 0xbe,
|
2: 0xba,
|
||||||
4: 0x00,
|
3: 0xbe,
|
||||||
5: 0x00,
|
4: 0x00,
|
||||||
6: 0x00,
|
5: 0x00,
|
||||||
7: [0x01, 0x02, 0x03]
|
6: 0x00,
|
||||||
},
|
7: [0x01, 0x02, 0x03]
|
||||||
extractor: null
|
},
|
||||||
|
{
|
||||||
|
0: 0xce,
|
||||||
|
1: 0xfa,
|
||||||
|
2: 0xed,
|
||||||
|
3: 0xfe,
|
||||||
|
4: 0x07,
|
||||||
|
5: 0x00,
|
||||||
|
6: 0x00,
|
||||||
|
7: 0x00,
|
||||||
|
8: [0x01, 0x02, 0x03]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
extractor: extractMACHO
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "MacOS Mach-O 64-bit object",
|
name: "MacOS Mach-O 64-bit object",
|
||||||
@@ -1305,7 +1317,7 @@ export const FILE_SIGNATURES = {
|
|||||||
2: 0xed,
|
2: 0xed,
|
||||||
3: 0xfe
|
3: 0xfe
|
||||||
},
|
},
|
||||||
extractor: null
|
extractor: extractMACHO
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Adobe Flash",
|
name: "Adobe Flash",
|
||||||
@@ -1404,7 +1416,7 @@ export const FILE_SIGNATURES = {
|
|||||||
260: 0x61,
|
260: 0x61,
|
||||||
261: 0x72
|
261: 0x72
|
||||||
},
|
},
|
||||||
extractor: null
|
extractor: extractTAR
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Roshal Archive",
|
name: "Roshal Archive",
|
||||||
@@ -2720,6 +2732,154 @@ export function extractZIP(bytes, offset) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MACHO extractor
|
||||||
|
*
|
||||||
|
* @param {Uint8Array} bytes
|
||||||
|
* @param {number} offset
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
export function extractMACHO(bytes, offset) {
|
||||||
|
|
||||||
|
// Magic bytes.
|
||||||
|
const MHCIGAM64 = "207250237254";
|
||||||
|
const MHMAGIC64 = "254237250207";
|
||||||
|
const MHCIGAM = "206250237254";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks to see if the file is 64-bit.
|
||||||
|
*
|
||||||
|
* @param {string} magic
|
||||||
|
* @returns {bool}
|
||||||
|
*/
|
||||||
|
function isMagic64(magic) {
|
||||||
|
return magic === MHCIGAM64 || magic === MHMAGIC64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the endianness of the file.
|
||||||
|
*
|
||||||
|
* @param {string} magic
|
||||||
|
* @returns {bool}
|
||||||
|
*/
|
||||||
|
function shouldSwapBytes(magic) {
|
||||||
|
return magic === MHCIGAM || magic === MHCIGAM64;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Jumps through segment information and calculates the sum of the segement sizes.
|
||||||
|
*
|
||||||
|
* @param {Stream} stream
|
||||||
|
* @param {number} offset
|
||||||
|
* @param {string} isSwap
|
||||||
|
* @param {number} ncmds
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function dumpSegmentCommands(stream, offset, isSwap, ncmds) {
|
||||||
|
let total = 0;
|
||||||
|
const LCSEGEMENT64 = 0x19;
|
||||||
|
const LCSEGEMENT = 0x1;
|
||||||
|
|
||||||
|
for (let i = 0; i < ncmds; i++) {
|
||||||
|
|
||||||
|
// Move to start of segment.
|
||||||
|
stream.moveTo(offset);
|
||||||
|
const cmd = stream.readInt(4, isSwap);
|
||||||
|
if (cmd === LCSEGEMENT64) {
|
||||||
|
|
||||||
|
// Move to size of segment field.
|
||||||
|
stream.moveTo(offset + 48);
|
||||||
|
|
||||||
|
// Extract size of segement.
|
||||||
|
total += stream.readInt(8, isSwap);
|
||||||
|
stream.moveTo(offset + 4);
|
||||||
|
|
||||||
|
// Move to offset of next segment.
|
||||||
|
offset += stream.readInt(4, isSwap);
|
||||||
|
} else if (cmd === LCSEGEMENT) {
|
||||||
|
stream.moveTo(offset + 36);
|
||||||
|
|
||||||
|
// Extract size of segement.
|
||||||
|
total += stream.readInt(4, isSwap);
|
||||||
|
stream.moveTo(offset + 4);
|
||||||
|
offset += stream.readInt(4, isSwap);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return total;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads the number of command segments.
|
||||||
|
*
|
||||||
|
* @param {Stream} stream
|
||||||
|
* @param {bool} is64
|
||||||
|
* @param {string} isSwap
|
||||||
|
* @returns {number}
|
||||||
|
*/
|
||||||
|
function dumpMachHeader(stream, is64, isSwap) {
|
||||||
|
let loadCommandsOffset = 28;
|
||||||
|
if (is64)
|
||||||
|
loadCommandsOffset += 4;
|
||||||
|
|
||||||
|
// Move to number of commands field.
|
||||||
|
stream.moveTo(16);
|
||||||
|
const ncmds = stream.readInt(4, isSwap);
|
||||||
|
return dumpSegmentCommands(stream, loadCommandsOffset, isSwap, ncmds);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const stream = new Stream(bytes.slice(offset));
|
||||||
|
const magic = stream.getBytes(4).join("");
|
||||||
|
|
||||||
|
// Move to the end of the final segment.
|
||||||
|
stream.moveTo(dumpMachHeader(stream, isMagic64(magic), shouldSwapBytes(magic) ? "le" : "be"));
|
||||||
|
return stream.carve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TAR extractor.
|
||||||
|
*
|
||||||
|
* @param {Uint8Array} bytes
|
||||||
|
* @param {number} offset
|
||||||
|
* @returns {Uint8Array}
|
||||||
|
*/
|
||||||
|
export function extractTAR(bytes, offset) {
|
||||||
|
const stream = new Stream(bytes.slice(offset));
|
||||||
|
while (stream.hasMore()) {
|
||||||
|
|
||||||
|
// Move to ustar identifier.
|
||||||
|
stream.moveForwardsBy(0x101);
|
||||||
|
if (stream.getBytes(5).join("") !== [0x75, 0x73, 0x74, 0x61, 0x72].join("")) {
|
||||||
|
// Reverse back to the end of the last section.
|
||||||
|
stream.moveBackwardsBy(0x106);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move back to file size field.
|
||||||
|
stream.moveBackwardsBy(0x8a);
|
||||||
|
let fsize = 0;
|
||||||
|
|
||||||
|
// Read file size field.
|
||||||
|
stream.getBytes(11).forEach((element, index) => {
|
||||||
|
fsize += (element - 48).toString();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Round number up from octet to nearest 512.
|
||||||
|
fsize = (Math.ceil(parseInt(fsize, 8) / 512) * 512);
|
||||||
|
|
||||||
|
// Move forwards to the end of that file.
|
||||||
|
stream.moveForwardsBy(fsize + 0x179);
|
||||||
|
}
|
||||||
|
stream.consumeWhile(0x00);
|
||||||
|
return stream.carve();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PNG extractor.
|
* PNG extractor.
|
||||||
*
|
*
|
||||||
@@ -2772,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.
|
* WAV extractor.
|
||||||
*
|
*
|
||||||
@@ -2786,7 +2972,7 @@ export function extractWAV(bytes, offset) {
|
|||||||
stream.moveTo(4);
|
stream.moveTo(4);
|
||||||
|
|
||||||
// Move to file size.
|
// Move to file size.
|
||||||
stream.moveTo(stream.readInt(4, "le") - 4);
|
stream.moveTo(stream.readInt(4, "le"));
|
||||||
|
|
||||||
return stream.carve();
|
return stream.carve();
|
||||||
}
|
}
|
||||||
@@ -2914,15 +3100,127 @@ export function extractSQLITE(bytes, offset) {
|
|||||||
export function extractPListXML(bytes, offset) {
|
export function extractPListXML(bytes, offset) {
|
||||||
const stream = new Stream(bytes.slice(offset));
|
const stream = new Stream(bytes.slice(offset));
|
||||||
|
|
||||||
// Find closing tag (</plist>)
|
let braceCount = 0;
|
||||||
stream.continueUntil([0x3c, 0x2f, 0x70, 0x6c, 0x69, 0x73, 0x74, 0x3e]);
|
|
||||||
stream.moveForwardsBy(8);
|
// 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);
|
stream.consumeIf(0x0a);
|
||||||
|
|
||||||
return stream.carve();
|
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.
|
* GZIP extractor.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ class Magic {
|
|||||||
await recipe.execute(dish);
|
await recipe.execute(dish);
|
||||||
// Return an empty buffer if the recipe did not run to completion
|
// Return an empty buffer if the recipe did not run to completion
|
||||||
if (recipe.lastRunOp === recipe.opList[recipe.opList.length - 1]) {
|
if (recipe.lastRunOp === recipe.opList[recipe.opList.length - 1]) {
|
||||||
return dish.get(Dish.ARRAY_BUFFER);
|
return await dish.get(Dish.ARRAY_BUFFER);
|
||||||
} else {
|
} else {
|
||||||
return new ArrayBuffer();
|
return new ArrayBuffer();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,9 +63,9 @@ class DNSOverHTTPS extends Operation {
|
|||||||
value: false
|
value: false
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Validate DNSSEC",
|
name: "Disable DNSSEC validation",
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
value: true
|
value: false
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class FromMorseCode extends Operation {
|
|||||||
const letterDelim = Utils.charRep(args[0]);
|
const letterDelim = Utils.charRep(args[0]);
|
||||||
const wordDelim = Utils.charRep(args[1]);
|
const wordDelim = Utils.charRep(args[1]);
|
||||||
|
|
||||||
input = input.replace(/-|‐|−|_|–|—|dash/ig, "<dash>"); //hyphen-minus|hyphen|minus-sign|undersore|en-dash|em-dash
|
input = input.replace(/-|‐|−|_|–|—|dash/ig, "<dash>"); // hyphen-minus|hyphen|minus-sign|undersore|en-dash|em-dash
|
||||||
input = input.replace(/\.|·|dot/ig, "<dot>");
|
input = input.replace(/\.|·|dot/ig, "<dot>");
|
||||||
|
|
||||||
let words = input.split(wordDelim);
|
let words = input.split(wordDelim);
|
||||||
@@ -147,7 +147,8 @@ const MORSE_TABLE = {
|
|||||||
"=": "<dash><dot><dot><dot><dash>",
|
"=": "<dash><dot><dot><dot><dash>",
|
||||||
"&": "<dot><dash><dot><dot><dot>",
|
"&": "<dot><dash><dot><dot><dot>",
|
||||||
"_": "<dot><dot><dash><dash><dot><dash>",
|
"_": "<dot><dot><dash><dash><dot><dash>",
|
||||||
"$": "<dot><dot><dot><dash><dot><dot><dash>"
|
"$": "<dot><dot><dot><dash><dot><dot><dash>",
|
||||||
|
" ": "<dot><dot><dot><dot><dot><dot><dot>"
|
||||||
};
|
};
|
||||||
|
|
||||||
export default FromMorseCode;
|
export default FromMorseCode;
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ class GroupIPAddresses extends Operation {
|
|||||||
|
|
||||||
// Sort IPv6 network dictionaries and print
|
// Sort IPv6 network dictionaries and print
|
||||||
for (networkStr in ipv6Networks) {
|
for (networkStr in ipv6Networks) {
|
||||||
//ipv6Networks[networkStr] = ipv6Networks[networkStr].sort(); TODO
|
// ipv6Networks[networkStr] = ipv6Networks[networkStr].sort(); TODO
|
||||||
|
|
||||||
output += networkStr + "/" + cidr + "\n";
|
output += networkStr + "/" + cidr + "\n";
|
||||||
|
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import zlibAndGzip from "zlibjs/bin/zlib_and_gzip.min.js";
|
import gunzip from "zlibjs/bin/gunzip.min.js";
|
||||||
|
|
||||||
const Zlib = zlibAndGzip.Zlib;
|
const Zlib = gunzip.Zlib;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gunzip operation
|
* Gunzip operation
|
||||||
@@ -42,8 +42,8 @@ class Gunzip extends Operation {
|
|||||||
* @returns {File}
|
* @returns {File}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
run(input, args) {
|
||||||
const gunzip = new Zlib.Gunzip(new Uint8Array(input));
|
const gzipObj = new Zlib.Gunzip(new Uint8Array(input));
|
||||||
return new Uint8Array(gunzip.decompress()).buffer;
|
return new Uint8Array(gzipObj.decompress()).buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
import {COMPRESSION_TYPE, ZLIB_COMPRESSION_TYPE_LOOKUP} from "../lib/Zlib.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
|
* Gzip operation
|
||||||
@@ -73,12 +73,15 @@ class Gzip extends Operation {
|
|||||||
options.filename = filename;
|
options.filename = filename;
|
||||||
}
|
}
|
||||||
if (comment.length) {
|
if (comment.length) {
|
||||||
options.flags.fcommenct = true;
|
options.flags.comment = true;
|
||||||
options.comment = comment;
|
options.comment = comment;
|
||||||
}
|
}
|
||||||
|
const gzipObj = new Zlib.Gzip(new Uint8Array(input), options);
|
||||||
const gzip = new Zlib.Gzip(new Uint8Array(input), options);
|
const compressed = new Uint8Array(gzipObj.compress());
|
||||||
return new Uint8Array(gzip.compress()).buffer;
|
if (options.flags.comment && !(compressed[3] & 0x10)) {
|
||||||
|
compressed[3] |= 0x10;
|
||||||
|
}
|
||||||
|
return compressed.buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,8 +6,8 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation";
|
import Operation from "../Operation.mjs";
|
||||||
import OperationError from "../errors/OperationError";
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Lorenz operation
|
* Lorenz operation
|
||||||
@@ -391,7 +391,7 @@ class Lorenz extends Operation {
|
|||||||
// Chi 2 one back lim - The active character of Chi 2 (2nd Chi wheel) in the previous position
|
// Chi 2 one back lim - The active character of Chi 2 (2nd Chi wheel) in the previous position
|
||||||
lim = parseInt(chiSettings[2][x2bptr-1], 10);
|
lim = parseInt(chiSettings[2][x2bptr-1], 10);
|
||||||
if (kt) {
|
if (kt) {
|
||||||
//p5 back 2
|
// p5 back 2
|
||||||
if (lim===p5[2]) {
|
if (lim===p5[2]) {
|
||||||
lim = 0;
|
lim = 0;
|
||||||
} else {
|
} else {
|
||||||
@@ -413,7 +413,7 @@ class Lorenz extends Operation {
|
|||||||
lim = 1;
|
lim = 1;
|
||||||
if (x2b1lug===s1b1lug) lim=0;
|
if (x2b1lug===s1b1lug) lim=0;
|
||||||
if (kt) {
|
if (kt) {
|
||||||
//p5 back 2
|
// p5 back 2
|
||||||
if (lim===p5[2]) {
|
if (lim===p5[2]) {
|
||||||
lim=0;
|
lim=0;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
/**
|
/**
|
||||||
* @author masq [github.cyberchef@masq.cc]
|
* @author masq [github.cyberchef@masq.cc]
|
||||||
|
* @author n1073645
|
||||||
* @copyright Crown Copyright 2018
|
* @copyright Crown Copyright 2018
|
||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Operation from "../Operation.mjs";
|
import Operation from "../Operation.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* To Case Insensitive Regex operation
|
* To Case Insensitive Regex operation
|
||||||
@@ -32,7 +34,61 @@ class ToCaseInsensitiveRegex extends Operation {
|
|||||||
* @returns {string}
|
* @returns {string}
|
||||||
*/
|
*/
|
||||||
run(input, args) {
|
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}`);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -148,7 +148,8 @@ const MORSE_TABLE = {
|
|||||||
"=": "<dash><dot><dot><dot><dash>",
|
"=": "<dash><dot><dot><dot><dash>",
|
||||||
"&": "<dot><dash><dot><dot><dot>",
|
"&": "<dot><dash><dot><dot><dot>",
|
||||||
"_": "<dot><dot><dash><dash><dot><dash>",
|
"_": "<dot><dot><dash><dash><dot><dash>",
|
||||||
"$": "<dot><dot><dot><dash><dot><dot><dash>"
|
"$": "<dot><dot><dot><dash><dot><dot><dash>",
|
||||||
|
" ": "<dot><dot><dot><dot><dot><dot><dot>"
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ToMorseCode;
|
export default ToMorseCode;
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*eslint no-console: ["off"] */
|
/* eslint no-console: ["off"] */
|
||||||
|
|
||||||
import NodeDish from "./NodeDish.mjs";
|
import NodeDish from "./NodeDish.mjs";
|
||||||
import NodeRecipe from "./NodeRecipe.mjs";
|
import NodeRecipe from "./NodeRecipe.mjs";
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*eslint no-global-assign: ["off"] */
|
/* eslint no-global-assign: ["off"] */
|
||||||
require = require("esm")(module);
|
require = require("esm")(module);
|
||||||
module.exports = require("./index.mjs");
|
module.exports = require("./index.mjs");
|
||||||
module.exports.File = require("./File.mjs");
|
module.exports.File = require("./File.mjs");
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*eslint no-console: 0 */
|
/* eslint no-console: 0 */
|
||||||
|
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ const chef = require("./cjs.js");
|
|||||||
const repl = require("repl");
|
const repl = require("repl");
|
||||||
|
|
||||||
|
|
||||||
/*eslint no-console: ["off"] */
|
/* eslint no-console: ["off"] */
|
||||||
|
|
||||||
console.log(`
|
console.log(`
|
||||||
______ __ ________ ____
|
______ __ ________ ____
|
||||||
|
|||||||
@@ -604,7 +604,7 @@ class App {
|
|||||||
else if (prev[1] > 0) prev[1]--;
|
else if (prev[1] > 0) prev[1]--;
|
||||||
else prev[0]--;
|
else prev[0]--;
|
||||||
|
|
||||||
//const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`;
|
// const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`;
|
||||||
|
|
||||||
let compileInfo = `<a href='https://github.com/gchq/CyberChef/blob/master/CHANGELOG.md'>Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago</a>`;
|
let compileInfo = `<a href='https://github.com/gchq/CyberChef/blob/master/CHANGELOG.md'>Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago</a>`;
|
||||||
|
|
||||||
|
|||||||
@@ -197,6 +197,7 @@ class Manager {
|
|||||||
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
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.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-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);
|
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));
|
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);
|
this.addDynamicListener(".extract-file,.extract-file i", "click", this.output.extractFileClick, this.output);
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
<meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
|
<meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
|
||||||
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
|
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
|
||||||
|
|
||||||
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
|
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico').default %>" />
|
||||||
|
|
||||||
<script type="application/javascript">
|
<script type="application/javascript">
|
||||||
"use strict";
|
"use strict";
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<button type="button" class="mx-2 btn btn-lg btn-success btn-raised btn-block" id="bake">
|
<button type="button" class="mx-2 btn btn-lg btn-success btn-raised btn-block" id="bake">
|
||||||
<img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png') %>" alt="Chef Icon"/>
|
<img aria-hidden="true" src="<%- require('../static/images/cook_male-32x32.png').default %>" alt="Chef Icon"/>
|
||||||
<span>Bake!</span>
|
<span>Bake!</span>
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
@@ -271,7 +271,7 @@
|
|||||||
<div class="file-overlay" id="file-overlay"></div>
|
<div class="file-overlay" id="file-overlay"></div>
|
||||||
<div style="position: relative; height: 100%;">
|
<div style="position: relative; height: 100%;">
|
||||||
<div class="io-card card">
|
<div class="io-card card">
|
||||||
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png') %>" alt="File icon" id="input-file-thumbnail"/>
|
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png').default %>" alt="File icon" id="input-file-thumbnail"/>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<button type="button" class="close" id="input-file-close">×</button>
|
<button type="button" class="close" id="input-file-close">×</button>
|
||||||
Name: <span id="input-file-name"></span><br>
|
Name: <span id="input-file-name"></span><br>
|
||||||
@@ -346,24 +346,26 @@
|
|||||||
<div id="output-highlighter" class="no-select"></div>
|
<div id="output-highlighter" class="no-select"></div>
|
||||||
<div id="output-html"></div>
|
<div id="output-html"></div>
|
||||||
<textarea id="output-text" readonly="readonly" spellcheck="false"></textarea>
|
<textarea id="output-text" readonly="readonly" spellcheck="false"></textarea>
|
||||||
<img id="show-file-overlay" aria-hidden="true" src="<%- require('../static/images/file-32x32.png') %>" alt="Show file overlay" title="Show file overlay"/>
|
<img id="show-file-overlay" aria-hidden="true" src="<%- require('../static/images/file-32x32.png').default %>" alt="Show file overlay" title="Show file overlay"/>
|
||||||
<div id="output-file">
|
<div id="output-file">
|
||||||
<div class="file-overlay"></div>
|
<div class="file-overlay"></div>
|
||||||
<div style="position: relative; height: 100%;">
|
<div style="position: relative; height: 100%;">
|
||||||
<div class="io-card card">
|
<div class="io-card card">
|
||||||
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png') %>" alt="File icon"/>
|
<img aria-hidden="true" src="<%- require('../static/images/file-128x128.png').default %>" alt="File icon"/>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
Size: <span id="output-file-size"></span><br>
|
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-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">
|
<div class="input-group">
|
||||||
<span class="input-group-btn">
|
<span class="input-group-prepend">
|
||||||
<button id="output-file-slice" type="button" class="btn btn-secondary bmd-btn-icon" title="View slice">
|
<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>
|
<i class="material-icons">search</i>
|
||||||
</button>
|
</button>
|
||||||
</span>
|
</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>
|
<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>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -489,6 +491,15 @@
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</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">
|
<div class="form-group option-item">
|
||||||
<label for="errorTimeout" class="bmd-label-floating">Operation error timeout in ms (0 for never)</label>
|
<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">
|
<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
|
Keep the current tab in sync between the input and output
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</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>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" class="btn btn-secondary" id="reset-options">Reset options to default</button>
|
<button type="button" class="btn btn-secondary" id="reset-options">Reset options to default</button>
|
||||||
@@ -622,7 +626,7 @@
|
|||||||
<h5 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h5>
|
<h5 class="modal-title">CyberChef - The Cyber Swiss Army Knife</h5>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png') %>" alt="CyberChef Logo"/>
|
<img aria-hidden="true" class="about-img-left" src="<%- require('../static/images/cyberchef-128x128.png').default %>" alt="CyberChef Logo"/>
|
||||||
<p class="subtext">
|
<p class="subtext">
|
||||||
Version <%= htmlWebpackPlugin.options.version %><br>
|
Version <%= htmlWebpackPlugin.options.version %><br>
|
||||||
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
|
Compile time: <%= htmlWebpackPlugin.options.compileTime %>
|
||||||
@@ -745,7 +749,7 @@
|
|||||||
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>
|
||||||
</div>
|
</div>
|
||||||
<a href="https://github.com/gchq/CyberChef">
|
<a href="https://github.com/gchq/CyberChef">
|
||||||
<img aria-hidden="true" style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png') %>" alt="Fork me on GitHub">
|
<img aria-hidden="true" style="position: absolute; top: 0; right: 0; border: 0;" src="<%- require('../static/images/fork_me.png').default %>" alt="Fork me on GitHub">
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -49,13 +49,12 @@ function main() {
|
|||||||
attemptHighlight: true,
|
attemptHighlight: true,
|
||||||
theme: "classic",
|
theme: "classic",
|
||||||
useMetaKey: false,
|
useMetaKey: false,
|
||||||
ioDisplayThreshold: 512,
|
ioDisplayThreshold: 2048,
|
||||||
logLevel: "info",
|
logLevel: "info",
|
||||||
autoMagic: true,
|
autoMagic: true,
|
||||||
imagePreview: true,
|
imagePreview: true,
|
||||||
syncTabs: true,
|
syncTabs: true,
|
||||||
preserveCR: true,
|
preserveCR: "entropy"
|
||||||
userSetCR: false
|
|
||||||
};
|
};
|
||||||
|
|
||||||
document.removeEventListener("DOMContentLoaded", main, false);
|
document.removeEventListener("DOMContentLoaded", main, false);
|
||||||
|
|||||||
@@ -98,6 +98,11 @@
|
|||||||
.io-card.card input[type=number] {
|
.io-card.card input[type=number] {
|
||||||
padding-right: 6px;
|
padding-right: 6px;
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
|
height: unset;
|
||||||
|
}
|
||||||
|
|
||||||
|
.io-card.card .input-group {
|
||||||
|
padding-top: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#files .card-header .float-right a:hover {
|
#files .card-header .float-right a:hover {
|
||||||
|
|||||||
@@ -446,7 +446,6 @@ class HighlighterWaiter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const cssClass = "hl1";
|
const cssClass = "hl1";
|
||||||
//if (colour) cssClass += "-"+colour;
|
|
||||||
|
|
||||||
// Remove HTML tags
|
// Remove HTML tags
|
||||||
text = text
|
text = text
|
||||||
|
|||||||
@@ -29,20 +29,20 @@ class InputWaiter {
|
|||||||
|
|
||||||
// Define keys that don't change the input so we don't have to autobake when they are pressed
|
// Define keys that don't change the input so we don't have to autobake when they are pressed
|
||||||
this.badKeys = [
|
this.badKeys = [
|
||||||
16, //Shift
|
16, // Shift
|
||||||
17, //Ctrl
|
17, // Ctrl
|
||||||
18, //Alt
|
18, // Alt
|
||||||
19, //Pause
|
19, // Pause
|
||||||
20, //Caps
|
20, // Caps
|
||||||
27, //Esc
|
27, // Esc
|
||||||
33, 34, 35, 36, //PgUp, PgDn, End, Home
|
33, 34, 35, 36, // PgUp, PgDn, End, Home
|
||||||
37, 38, 39, 40, //Directional
|
37, 38, 39, 40, // Directional
|
||||||
44, //PrntScrn
|
44, // PrntScrn
|
||||||
91, 92, //Win
|
91, 92, // Win
|
||||||
93, //Context
|
93, // Context
|
||||||
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, //F1-12
|
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, // F1-12
|
||||||
144, //Num
|
144, // Num
|
||||||
145, //Scroll
|
145, // Scroll
|
||||||
];
|
];
|
||||||
|
|
||||||
this.inputWorker = null;
|
this.inputWorker = null;
|
||||||
@@ -476,7 +476,7 @@ class InputWaiter {
|
|||||||
*/
|
*/
|
||||||
resetFileThumb() {
|
resetFileThumb() {
|
||||||
const fileThumb = document.getElementById("input-file-thumbnail");
|
const fileThumb = document.getElementById("input-file-thumbnail");
|
||||||
fileThumb.src = require("../static/images/file-128x128.png");
|
fileThumb.src = require("../static/images/file-128x128.png").default;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -767,7 +767,9 @@ class InputWaiter {
|
|||||||
// and manually fire inputChange()
|
// and manually fire inputChange()
|
||||||
inputText.value = val;
|
inputText.value = val;
|
||||||
inputText.setSelectionRange(selStart + pastedData.length, selStart + pastedData.length);
|
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;
|
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>";
|
const optionsStr = "This behaviour can be changed in the <a href='#' onclick='document.getElementById(\"options\").click()'>Options pane</a>";
|
||||||
if (!this.app.options.userSetCR) {
|
const preserveStr = `A carriage return (\\r, 0x0d) was detected in your input. To preserve it, editing has been disabled.<br>${optionsStr}`;
|
||||||
// User has not set a CR preference yet
|
const dontPreserveStr = `A carriage return (\\r, 0x0d) was detected in your input. It has not been preserved.<br>${optionsStr}`;
|
||||||
let preserve = await new Promise(function(resolve, reject) {
|
|
||||||
this.app.confirm(
|
switch (this.app.options.preserveCR) {
|
||||||
"Carriage Return Detected",
|
case "always":
|
||||||
"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.",
|
this.app.alert(preserveStr, 6000);
|
||||||
"Preserve Carriage Returns",
|
return true;
|
||||||
"Enable Editing", resolve, this);
|
case "never":
|
||||||
}.bind(this));
|
this.app.alert(dontPreserveStr, 6000);
|
||||||
if (preserve === undefined) {
|
return false;
|
||||||
// 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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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"),
|
showFileOverlay = document.getElementById("show-file-overlay"),
|
||||||
sliceFromEl = document.getElementById("output-file-slice-from"),
|
sliceFromEl = document.getElementById("output-file-slice-from"),
|
||||||
sliceToEl = document.getElementById("output-file-slice-to"),
|
sliceToEl = document.getElementById("output-file-slice-to"),
|
||||||
sliceFrom = parseInt(sliceFromEl.value, 10),
|
sliceFrom = parseInt(sliceFromEl.value, 10) * 1024,
|
||||||
sliceTo = parseInt(sliceToEl.value, 10),
|
sliceTo = parseInt(sliceToEl.value, 10) * 1024,
|
||||||
output = this.outputs[this.manager.tabs.getActiveOutputTab()].data;
|
output = this.outputs[this.manager.tabs.getActiveOutputTab()].data;
|
||||||
|
|
||||||
let str;
|
let str;
|
||||||
@@ -1137,6 +1137,39 @@ class OutputWaiter {
|
|||||||
showFileOverlay.style.display = "block";
|
showFileOverlay.style.display = "block";
|
||||||
outputText.value = Utils.printable(str, true);
|
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";
|
outputText.style.display = "block";
|
||||||
outputHtml.style.display = "none";
|
outputHtml.style.display = "none";
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ class RecipeWaiter {
|
|||||||
}
|
}
|
||||||
}.bind(this),
|
}.bind(this),
|
||||||
onSort: function(evt) {
|
onSort: function(evt) {
|
||||||
|
this.updateZIndices();
|
||||||
if (evt.from.id === "rec-list") {
|
if (evt.from.id === "rec-list") {
|
||||||
document.dispatchEvent(this.manager.statechange);
|
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.
|
* Handler for favourite dragover events.
|
||||||
* If the element being dragged is an operation, displays a visual cue so that the user knows it can
|
* 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`);
|
log.debug(`'${e.target.querySelector(".op-title").textContent}' added to recipe`);
|
||||||
|
|
||||||
this.triggerArgEvents(e.target);
|
this.triggerArgEvents(e.target);
|
||||||
|
this.updateZIndices();
|
||||||
window.dispatchEvent(this.manager.statechange);
|
window.dispatchEvent(this.manager.statechange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ TestRegister.addApiTests([
|
|||||||
<a href="https://github.com">Click here</a>
|
<a href="https://github.com">Click here</a>
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>`.replace(/\n|\s{4}/g, ""); //remove newlines, tabs
|
</html>`.replace(/\n|\s{4}/g, ""); // remove newlines, tabs
|
||||||
|
|
||||||
const dish = new Dish(html, Dish.HTML);
|
const dish = new Dish(html, Dish.HTML);
|
||||||
dish.get(4);
|
dish.get(4);
|
||||||
@@ -187,8 +187,8 @@ TestRegister.addApiTests([
|
|||||||
const dish = new Dish([file1, file2], Dish.LIST_FILE);
|
const dish = new Dish([file1, file2], Dish.LIST_FILE);
|
||||||
|
|
||||||
dish.get(Dish.ARRAY_BUFFER);
|
dish.get(Dish.ARRAY_BUFFER);
|
||||||
assert.deepStrictEqual(dish.value, new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b]).buffer);
|
assert.deepStrictEqual(dish.value, [new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]), new Uint8Array([0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b])]);
|
||||||
assert.strictEqual(dish.value.byteLength, 11);
|
assert.strictEqual(dish.value.length, 2);
|
||||||
|
|
||||||
dish.get(Dish.LIST_FILE);
|
dish.get(Dish.LIST_FILE);
|
||||||
const dataArray = new Uint8Array(dish.value[0].data);
|
const dataArray = new Uint8Array(dish.value[0].data);
|
||||||
|
|||||||
@@ -41,6 +41,8 @@ import "./tests/DateTime.mjs";
|
|||||||
import "./tests/ExtractEmailAddresses.mjs";
|
import "./tests/ExtractEmailAddresses.mjs";
|
||||||
import "./tests/Fork.mjs";
|
import "./tests/Fork.mjs";
|
||||||
import "./tests/FromDecimal.mjs";
|
import "./tests/FromDecimal.mjs";
|
||||||
|
import "./tests/Gzip.mjs";
|
||||||
|
import "./tests/Gunzip.mjs";
|
||||||
import "./tests/Hash.mjs";
|
import "./tests/Hash.mjs";
|
||||||
import "./tests/HaversineDistance.mjs";
|
import "./tests/HaversineDistance.mjs";
|
||||||
import "./tests/Hexdump.mjs";
|
import "./tests/Hexdump.mjs";
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ TestRegister.addTests([
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "To Octal: Γειά σου",
|
name: "To Octal: Γειά σου",
|
||||||
input: "Γειά σου", //[206,147,206,181,206,185,206,172,32,207,131,206,191,207,133],
|
input: "Γειά σου", // [206,147,206,181,206,185,206,172,32,207,131,206,191,207,133],
|
||||||
expectedOutput: "316 223 316 265 316 271 316 254 40 317 203 316 277 317 205",
|
expectedOutput: "316 223 316 265 316 271 316 254 40 317 203 316 277 317 205",
|
||||||
recipeConfig: [
|
recipeConfig: [
|
||||||
{
|
{
|
||||||
|
|||||||
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"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
]);
|
||||||
@@ -1099,7 +1099,7 @@ TestRegister.addTests([
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
/*{ // This takes a LONG time to run (over a minute usually).
|
/* { // This takes a LONG time to run (over a minute usually).
|
||||||
name: "Scrypt: RFC test vector 4",
|
name: "Scrypt: RFC test vector 4",
|
||||||
input: "pleaseletmein",
|
input: "pleaseletmein",
|
||||||
expectedOutput: "2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4",
|
expectedOutput: "2101cb9b6a511aaeaddbbe09cf70f881ec568d574a2ffd4dabe5ee9820adaa478e56fd8f4ba5d09ffa1c6d927c40f4c337304049e8a952fbcbf45c6fa77a41a4",
|
||||||
@@ -1115,5 +1115,5 @@ TestRegister.addTests([
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},*/
|
}, */
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -248,7 +248,7 @@ TestRegister.addTests([
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
/*{ This operation only works in a browser
|
/* { This operation only works in a browser
|
||||||
name: "Optical Character Recognition",
|
name: "Optical Character Recognition",
|
||||||
input: "iVBORw0KGgoAAAANSUhEUgAAAUAAAAC0CAIAAABqhmJGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAASuSURBVHhe7dftVdswAIbRzsVAzMM0XabDUCOUxLYsWW4Jp+/pvf9w9GH76CHw4x2IJWAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAI9p8G/PbyY8rL2686g8t+vnqHTyfgIYfvz/26veTXn/UKX8+f0EU9bHrtu/6KfAN/AwEXAj7lFf2TBFw4nae8on+SgIvJ01n/KLzpDK+L3bT/Ap4O+HC+V12mTH+M3gzcLbIY/EO6HfxYp13k09nb6r3UqcdnjoCL3ll72J26h+35Oxy2XvZ0wOLaXq9v2+F1UC+7RZtMZ/DnfX1lwDOPzwUCLo7O2trtDK8H3M/iqoc6bj1subT68XTA/F7bGJooyzKbhTvLPHY8eJLHlbNX1DqYUVfdXbqwJjsCLsans37aNNJM6w68OR0wv9f9ymKw3k67yn2ZZpHlg3a3zis60s6oV+ZvlzMCLoanc3Dsdt9TdWT/lM8OmNjr5KY72jmzq1zfrbvXtVtmRMDF8HTWcgaaqIrD1U4G/MFewxrW262s5jS/Fzpmdts6mnHy+Fwl4GJ0OjsNrG1P/y7CNo3+gEt7jW56MVprNed7A/5w+n6YJ+BieDpnj/jO6pweTz0acGWvmZveL9XOmd3x6wKuTt8PEwRczLRw4eje1XX7c/cDruw1uuneOu2c4aOvzI57mJhRh1xZlQ0BF+Oz9vcF96fuB1zYa7R2b5mD6/XSwdfg8snj4q21+W/L02dfzIxhQMDFyTm6Hd7m+JYP7rPKT5sRuzhOBywm91rUkYc3fV9ltchtr8VmzuGOdfDB9N1tFYefNfdXLmyGjNZkhoCLUQufVqd/7z7rUcLW/XieDvg0s9difNOdRV5ePibt5vTuazusWbF9rs2E5v4mH58LBFyMW7g5OID7s9cMuTygmt9rcNPb5MrAz0lHc3Z9Ht7XZsxqxO36ZtLR/c0+PpMEzLOc/4LhrwmYZ6lfywJ+JgHzJPr9DgLmi23/zdXvcwmYL7YKWL1PJ2AIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmCI9f7+G6yFxVg/GyYwAAAAAElFTkSuQmCC",
|
input: "iVBORw0KGgoAAAANSUhEUgAAAUAAAAC0CAIAAABqhmJGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAASuSURBVHhe7dftVdswAIbRzsVAzMM0XabDUCOUxLYsWW4Jp+/pvf9w9GH76CHw4x2IJWAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAI9p8G/PbyY8rL2686g8t+vnqHTyfgIYfvz/26veTXn/UKX8+f0EU9bHrtu/6KfAN/AwEXAj7lFf2TBFw4nae8on+SgIvJ01n/KLzpDK+L3bT/Ap4O+HC+V12mTH+M3gzcLbIY/EO6HfxYp13k09nb6r3UqcdnjoCL3ll72J26h+35Oxy2XvZ0wOLaXq9v2+F1UC+7RZtMZ/DnfX1lwDOPzwUCLo7O2trtDK8H3M/iqoc6bj1subT68XTA/F7bGJooyzKbhTvLPHY8eJLHlbNX1DqYUVfdXbqwJjsCLsans37aNNJM6w68OR0wv9f9ymKw3k67yn2ZZpHlg3a3zis60s6oV+ZvlzMCLoanc3Dsdt9TdWT/lM8OmNjr5KY72jmzq1zfrbvXtVtmRMDF8HTWcgaaqIrD1U4G/MFewxrW262s5jS/Fzpmdts6mnHy+Fwl4GJ0OjsNrG1P/y7CNo3+gEt7jW56MVprNed7A/5w+n6YJ+BieDpnj/jO6pweTz0acGWvmZveL9XOmd3x6wKuTt8PEwRczLRw4eje1XX7c/cDruw1uuneOu2c4aOvzI57mJhRh1xZlQ0BF+Oz9vcF96fuB1zYa7R2b5mD6/XSwdfg8snj4q21+W/L02dfzIxhQMDFyTm6Hd7m+JYP7rPKT5sRuzhOBywm91rUkYc3fV9ltchtr8VmzuGOdfDB9N1tFYefNfdXLmyGjNZkhoCLUQufVqd/7z7rUcLW/XieDvg0s9difNOdRV5ePibt5vTuazusWbF9rs2E5v4mH58LBFyMW7g5OID7s9cMuTygmt9rcNPb5MrAz0lHc3Z9Ht7XZsxqxO36ZtLR/c0+PpMEzLOc/4LhrwmYZ6lfywJ+JgHzJPr9DgLmi23/zdXvcwmYL7YKWL1PJ2AIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmAIJmCI9f7+G6yFxVg/GyYwAAAAAElFTkSuQmCC",
|
||||||
expectedOutput: "Tesseract.js\n",
|
expectedOutput: "Tesseract.js\n",
|
||||||
@@ -262,5 +262,5 @@ TestRegister.addTests([
|
|||||||
"args": [false]
|
"args": [false]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}*/
|
} */
|
||||||
]);
|
]);
|
||||||
|
|||||||
@@ -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: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
}
|
||||||
]);
|
]);
|
||||||
|
|||||||
Reference in New Issue
Block a user