cyberchef 9.38.0 → 9.38.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyberchef",
3
- "version": "9.38.0",
3
+ "version": "9.38.1",
4
4
  "description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
5
5
  "author": "n1474335 <n1474335@gmail.com>",
6
6
  "homepage": "https://gchq.github.io/CyberChef",
@@ -69,6 +69,7 @@
69
69
  "html-webpack-plugin": "^5.5.0",
70
70
  "imports-loader": "^3.1.1",
71
71
  "mini-css-extract-plugin": "2.6.0",
72
+ "modify-source-webpack-plugin": "^3.0.0",
72
73
  "nightwatch": "^2.0.10",
73
74
  "postcss": "^8.4.12",
74
75
  "postcss-css-variables": "^0.18.0",
@@ -174,6 +175,7 @@
174
175
  "lint": "npx grunt lint",
175
176
  "postinstall": "npx grunt exec:fixCryptoApiImports",
176
177
  "newop": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newOperation.mjs",
178
+ "minor": "node --experimental-modules --experimental-json-modules src/core/config/scripts/newMinorVersion.mjs",
177
179
  "getheapsize": "node -e 'console.log(`node heap limit = ${require(\"v8\").getHeapStatistics().heap_size_limit / (1024 * 1024)} Mb`)'",
178
180
  "setheapsize": "export NODE_OPTIONS=--max_old_space_size=2048"
179
181
  }
@@ -0,0 +1,144 @@
1
+ /**
2
+ * This script updates the CHANGELOG when a new minor version is created.
3
+ *
4
+ * @author n1474335 [n1474335@gmail.com]
5
+ * @copyright Crown Copyright 2022
6
+ * @license Apache-2.0
7
+ */
8
+
9
+ /* eslint no-console: ["off"] */
10
+
11
+ import prompt from "prompt";
12
+ import colors from "colors";
13
+ import path from "path";
14
+ import fs from "fs";
15
+ import process from "process";
16
+
17
+ const dir = path.join(process.cwd() + "/src/core/config/");
18
+ if (!fs.existsSync(dir)) {
19
+ console.log("\nCWD: " + process.cwd());
20
+ console.log("Error: newMinorVersion.mjs should be run from the project root");
21
+ console.log("Example> node --experimental-modules src/core/config/scripts/newMinorVersion.mjs");
22
+ process.exit(1);
23
+ }
24
+
25
+ let changelogData = fs.readFileSync(path.join(process.cwd(), "CHANGELOG.md"), "utf8");
26
+ const lastVersion = changelogData.match(/## Details\s+### \[(\d+)\.(\d+)\.(\d+)\]/);
27
+ const newVersion = [
28
+ parseInt(lastVersion[1], 10),
29
+ parseInt(lastVersion[2], 10) + 1,
30
+ 0
31
+ ];
32
+
33
+ let knownContributors = changelogData.match(/^\[@([^\]]+)\]/gm);
34
+ knownContributors = knownContributors.map(c => c.slice(2, -1));
35
+
36
+ const date = (new Date()).toISOString().split("T")[0];
37
+
38
+ const schema = {
39
+ properties: {
40
+ message: {
41
+ description: "A short but descriptive summary of a feature in this version",
42
+ example: "Added 'Op name' operation",
43
+ prompt: "Feature description",
44
+ type: "string",
45
+ required: true,
46
+ },
47
+ author: {
48
+ description: "The author of the feature (only one supported, edit manually to add more)",
49
+ example: "n1474335",
50
+ prompt: "Author",
51
+ type: "string",
52
+ default: "n1474335"
53
+ },
54
+ id: {
55
+ description: "The PR number or full commit hash for this feature.",
56
+ example: "1200",
57
+ prompt: "Pull request or commit ID",
58
+ type: "string"
59
+ },
60
+ another: {
61
+ description: "y/n",
62
+ example: "y",
63
+ prompt: "Add another feature?",
64
+ type: "string",
65
+ pattern: /^[yn]$/,
66
+ }
67
+ }
68
+ };
69
+
70
+ // Build schema
71
+ for (const prop in schema.properties) {
72
+ const p = schema.properties[prop];
73
+ p.description = "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
74
+ }
75
+
76
+ prompt.message = "";
77
+ prompt.delimiter = ":".green;
78
+
79
+ const features = [];
80
+ const authors = [];
81
+ const prIDs = [];
82
+ const commitIDs = [];
83
+
84
+ prompt.start();
85
+
86
+ const getFeature = function() {
87
+ prompt.get(schema, (err, result) => {
88
+ if (err) {
89
+ console.log("\nExiting script.");
90
+ process.exit(0);
91
+ }
92
+
93
+ features.push(result);
94
+
95
+ if (result.another === "y") {
96
+ getFeature();
97
+ } else {
98
+ let message = `### [${newVersion[0]}.${newVersion[1]}.${newVersion[2]}] - ${date}\n`;
99
+
100
+ features.forEach(feature => {
101
+ const id = feature.id.length > 10 ? feature.id.slice(0, 7) : "#" + feature.id;
102
+ message += `- ${feature.message} [@${feature.author}] | [${id}]\n`;
103
+
104
+ if (!knownContributors.includes(feature.author)) {
105
+ authors.push(`[@${feature.author}]: https://github.com/${feature.author}`);
106
+ }
107
+
108
+ if (feature.id.length > 10) {
109
+ commitIDs.push(`[${id}]: https://github.com/gchq/CyberChef/commit/${feature.id}`);
110
+ } else {
111
+ prIDs.push(`[#${feature.id}]: https://github.com/gchq/CyberChef/pull/${feature.id}`);
112
+ }
113
+ });
114
+
115
+ // Message
116
+ changelogData = changelogData.replace(/## Details\n\n/, "## Details\n\n" + message + "\n");
117
+
118
+ // Tag
119
+ const newTag = `[${newVersion[0]}.${newVersion[1]}.${newVersion[2]}]: https://github.com/gchq/CyberChef/releases/tag/v${newVersion[0]}.${newVersion[1]}.${newVersion[2]}\n`;
120
+ changelogData = changelogData.replace(/\n\n(\[\d+\.\d+\.\d+\]: https)/, "\n\n" + newTag + "$1");
121
+
122
+ // Author
123
+ authors.forEach(author => {
124
+ changelogData = changelogData.replace(/(\n\[@[^\]]+\]: https:\/\/github\.com\/[^\n]+\n)\n/, "$1" + author + "\n\n");
125
+ });
126
+
127
+ // Commit IDs
128
+ commitIDs.forEach(commitID => {
129
+ changelogData = changelogData.replace(/(\n\[[^\].]+\]: https:\/\/github.com\/gchq\/CyberChef\/commit\/[^\n]+\n)\n/, "$1" + commitID + "\n\n");
130
+ });
131
+
132
+ // PR IDs
133
+ prIDs.forEach(prID => {
134
+ changelogData = changelogData.replace(/(\n\[#[^\]]+\]: https:\/\/github.com\/gchq\/CyberChef\/pull\/[^\n]+\n)\n/, "$1" + prID + "\n\n");
135
+ });
136
+
137
+ fs.writeFileSync(path.join(process.cwd(), "CHANGELOG.md"), changelogData);
138
+
139
+ console.log("Written CHANGELOG.md");
140
+ }
141
+ });
142
+ };
143
+
144
+ getFeature();
@@ -65,6 +65,10 @@ class ToBase45 extends Operation {
65
65
 
66
66
  if (chars < 2) {
67
67
  res.push("0");
68
+ chars++;
69
+ }
70
+ if (pair.length > 1 && chars < 3) {
71
+ res.push("0");
68
72
  }
69
73
  }
70
74
 
@@ -67,7 +67,7 @@ class ToHex extends Operation {
67
67
  * @returns {Object[]} pos
68
68
  */
69
69
  highlight(pos, args) {
70
- let delim, commaLen;
70
+ let delim, commaLen = 0;
71
71
  if (args[0] === "0x with comma") {
72
72
  delim = "0x";
73
73
  commaLen = 1;
@@ -86,7 +86,7 @@ class ToHex extends Operation {
86
86
  pos[0].start = pos[0].start * (2 + len) + countLF(pos[0].start);
87
87
  pos[0].end = pos[0].end * (2 + len) + countLF(pos[0].end);
88
88
 
89
- // if the deliminators are not prepended, trim the trailing deliminator
89
+ // if the delimiters are not prepended, trim the trailing delimiter
90
90
  if (!(delim === "0x" || delim === "\\x")) {
91
91
  pos[0].end -= delim.length;
92
92
  }
package/src/web/App.mjs CHANGED
@@ -57,7 +57,7 @@ class App {
57
57
  this.populateOperationsList();
58
58
  this.manager.setup();
59
59
  this.manager.output.saveBombe();
60
- this.resetLayout();
60
+ this.adjustComponentSizes();
61
61
  this.setCompileMessage();
62
62
 
63
63
  log.debug("App loaded");
@@ -295,9 +295,7 @@ class App {
295
295
  gutterSize: 4,
296
296
  expandToMin: true,
297
297
  onDrag: debounce(function() {
298
- this.manager.recipe.adjustWidth();
299
- this.manager.input.calcMaxTabs();
300
- this.manager.output.calcMaxTabs();
298
+ this.adjustComponentSizes();
301
299
  }, 50, "dragSplitter", this, [])
302
300
  });
303
301
 
@@ -307,7 +305,7 @@ class App {
307
305
  minSize: minimise ? [0, 0] : [100, 100]
308
306
  });
309
307
 
310
- this.resetLayout();
308
+ this.adjustComponentSizes();
311
309
  }
312
310
 
313
311
 
@@ -581,6 +579,13 @@ class App {
581
579
  resetLayout() {
582
580
  this.columnSplitter.setSizes([20, 30, 50]);
583
581
  this.ioSplitter.setSizes([50, 50]);
582
+ this.adjustComponentSizes();
583
+ }
584
+
585
+ /**
586
+ * Adjust components to fit their containers.
587
+ */
588
+ adjustComponentSizes() {
584
589
  this.manager.recipe.adjustWidth();
585
590
  this.manager.input.calcMaxTabs();
586
591
  this.manager.output.calcMaxTabs();
@@ -176,7 +176,7 @@
176
176
  <div id="recipe" class="split split-horizontal no-select">
177
177
  <div class="title no-select">
178
178
  Recipe
179
- <span class="float-right">
179
+ <span class="pane-controls hide-on-maximised-output">
180
180
  <button type="button" class="btn btn-primary bmd-btn-icon" id="save" data-toggle="tooltip" title="Save recipe">
181
181
  <i class="material-icons">save</i>
182
182
  </button>
@@ -190,7 +190,7 @@
190
190
  </div>
191
191
  <ul id="rec-list" class="list-area no-select"></ul>
192
192
 
193
- <div id="controls" class="no-select">
193
+ <div id="controls" class="no-select hide-on-maximised-output">
194
194
  <div id="controls-content" class="d-flex align-items-center">
195
195
  <button type="button" class="mx-2 btn btn-lg btn-secondary" id="step" data-toggle="tooltip" title="Step through the recipe">
196
196
  Step
@@ -217,7 +217,10 @@
217
217
  <div id="input" class="split no-select">
218
218
  <div class="title no-select">
219
219
  <label for="input-text">Input</label>
220
- <span class="float-right">
220
+ <span class="pane-controls">
221
+ <div class="io-info" id="input-files-info"></div>
222
+ <div class="io-info" id="input-selection-info"></div>
223
+ <div class="io-info" id="input-info"></div>
221
224
  <button type="button" class="btn btn-primary bmd-btn-icon" id="btn-new-tab" data-toggle="tooltip" title="Add a new input tab">
222
225
  <i class="material-icons">add</i>
223
226
  </button>
@@ -236,9 +239,7 @@
236
239
  <i class="material-icons">view_compact</i>
237
240
  </button>
238
241
  </span>
239
- <div class="io-info" id="input-files-info"></div>
240
- <div class="io-info" id="input-info"></div>
241
- <div class="io-info" id="input-selection-info"></div>
242
+
242
243
  </div>
243
244
  <div id="input-tabs-wrapper" style="display: none;" class="no-select">
244
245
  <span id="btn-previous-input-tab" class="input-tab-buttons">
@@ -288,7 +289,10 @@
288
289
  <div id="output" class="split">
289
290
  <div class="title no-select">
290
291
  <label for="output-text">Output</label>
291
- <span class="float-right">
292
+ <span class="pane-controls">
293
+ <div class="io-info" id="bake-info"></div>
294
+ <div class="io-info" id="output-selection-info"></div>
295
+ <div class="io-info" id="output-info"></div>
292
296
  <button type="button" class="btn btn-primary bmd-btn-icon" id="save-all-to-file" data-toggle="tooltip" title="Save all outputs to a zip file" style="display: none">
293
297
  <i class="material-icons">archive</i>
294
298
  </button>
@@ -308,9 +312,7 @@
308
312
  <i class="material-icons">fullscreen</i>
309
313
  </button>
310
314
  </span>
311
- <div class="io-info" id="bake-info"></div>
312
- <div class="io-info" id="output-info"></div>
313
- <div class="io-info" id="output-selection-info"></div>
315
+
314
316
  <button type="button" class="btn btn-primary bmd-btn-icon hidden" id="magic" data-toggle="tooltip" title="Magic!" data-html="true">
315
317
  <svg width="22" height="22" viewBox="0 0 24 24">
316
318
  <path d="M7.5,5.6L5,7L6.4,4.5L5,2L7.5,3.4L10,2L8.6,4.5L10,7L7.5,5.6M19.5,15.4L22,14L20.6,16.5L22,19L19.5,17.6L17,19L18.4,16.5L17,14L19.5,15.4M22,2L20.6,4.5L22,7L19.5,5.6L17,7L18.4,4.5L17,2L19.5,3.4L22,2M13.34,12.78L15.78,10.34L13.66,8.22L11.22,10.66L13.34,12.78M14.37,7.29L16.71,9.63C17.1,10 17.1,10.65 16.71,11.04L5.04,22.71C4.65,23.1 4,23.1 3.63,22.71L1.29,20.37C0.9,20 0.9,19.35 1.29,18.96L12.96,7.29C13.35,6.9 14,6.9 14.37,7.29Z" />
@@ -24,9 +24,16 @@
24
24
  line-height: calc(var(--title-height) - 14px);
25
25
  }
26
26
 
27
- .title>span,
28
- .title>.btn {
29
- margin-top: -4px;
27
+ .pane-controls {
28
+ position: absolute;
29
+ right: 8px;
30
+ top: 8px;
31
+ display: flex;
32
+ flex-direction: row;
33
+ }
34
+
35
+ .pane-controls .btn {
36
+ margin-left: 2px;
30
37
  }
31
38
 
32
39
  .list-area {
@@ -107,4 +114,4 @@
107
114
 
108
115
  #files .card-header .float-right a:hover {
109
116
  text-decoration: none;
110
- }
117
+ }
@@ -58,6 +58,10 @@
58
58
  border-radius: 30px;
59
59
  }
60
60
 
61
+ .output-maximised .hide-on-maximised-output {
62
+ display: none !important;
63
+ }
64
+
61
65
  .spin {
62
66
  animation-name: spin;
63
67
  animation-duration: 3s;
@@ -280,9 +280,8 @@
280
280
  }
281
281
 
282
282
  .io-info {
283
- margin-right: 20px;
283
+ margin-right: 18px;
284
284
  margin-top: 1px;
285
- float: right;
286
285
  height: 30px;
287
286
  text-align: right;
288
287
  line-height: 12px;
@@ -39,8 +39,8 @@ div#output {
39
39
 
40
40
  .split {
41
41
  box-sizing: border-box;
42
- /* overflow: auto;
43
- Removed to enable Background Magic button pulse to overflow.
42
+ /* overflow: auto; */
43
+ /* Removed to enable Background Magic button pulse to overflow.
44
44
  Replace this rule if it seems to be causing problems. */
45
45
  position: relative;
46
46
  }
@@ -1373,6 +1373,7 @@ class OutputWaiter {
1373
1373
  const el = e.target.id === "maximise-output" ? e.target : e.target.parentNode;
1374
1374
 
1375
1375
  if (el.getAttribute("data-original-title").indexOf("Maximise") === 0) {
1376
+ document.body.classList.add("output-maximised");
1376
1377
  this.app.initialiseSplitter(true);
1377
1378
  this.app.columnSplitter.collapse(0);
1378
1379
  this.app.columnSplitter.collapse(1);
@@ -1381,6 +1382,7 @@ class OutputWaiter {
1381
1382
  $(el).attr("data-original-title", "Restore output pane");
1382
1383
  el.querySelector("i").innerHTML = "fullscreen_exit";
1383
1384
  } else {
1385
+ document.body.classList.remove("output-maximised");
1384
1386
  $(el).attr("data-original-title", "Maximise output pane");
1385
1387
  el.querySelector("i").innerHTML = "fullscreen";
1386
1388
  this.app.initialiseSplitter(false);
@@ -23,11 +23,11 @@ class WindowWaiter {
23
23
 
24
24
  /**
25
25
  * Handler for window resize events.
26
- * Resets the layout of CyberChef's panes after 200ms (so that continuous resizing doesn't cause
26
+ * Resets adjustable component sizes after 200ms (so that continuous resizing doesn't cause
27
27
  * continuous resetting).
28
28
  */
29
29
  windowResize() {
30
- debounce(this.app.resetLayout, 200, "windowResize", this.app, [])();
30
+ debounce(this.app.adjustComponentSizes, 200, "windowResize", this.app, [])();
31
31
  }
32
32
 
33
33
 
package/webpack.config.js CHANGED
@@ -1,6 +1,7 @@
1
1
  const webpack = require("webpack");
2
2
  const MiniCssExtractPlugin = require("mini-css-extract-plugin");
3
3
  const CopyWebpackPlugin = require("copy-webpack-plugin");
4
+ const { ModifySourcePlugin } = require("modify-source-webpack-plugin");
4
5
  const path = require("path");
5
6
 
6
7
  /**
@@ -82,6 +83,16 @@ module.exports = {
82
83
  to: "assets/forge/"
83
84
  }
84
85
  ]
86
+ }),
87
+ new ModifySourcePlugin({
88
+ rules: [
89
+ {
90
+ // Fix toSpare(0) bug in Split.js by avoiding gutter accomodation
91
+ test: /split\.es\.js$/,
92
+ modify: (src, path) =>
93
+ src.replace("if (pixelSize < elementMinSize)", "if (false)")
94
+ }
95
+ ]
85
96
  })
86
97
  ],
87
98
  resolve: {