cyberchef 11.0.0 → 11.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/CHANGELOG.md +170 -1
  2. package/Dockerfile +2 -2
  3. package/Gruntfile.js +10 -5
  4. package/README.md +10 -7
  5. package/SECURITY.md +11 -19
  6. package/package.json +35 -34
  7. package/src/core/Chef.mjs +2 -0
  8. package/src/core/config/Categories.json +6 -0
  9. package/src/core/config/OperationConfig.json +144 -19
  10. package/src/core/config/modules/Default.mjs +8 -0
  11. package/src/core/config/modules/PGP.mjs +2 -0
  12. package/src/core/config/scripts/generateOpsIndex.mjs +63 -0
  13. package/src/core/config/scripts/newOperation.mjs +31 -4
  14. package/src/core/dishTypes/DishType.mjs +1 -1
  15. package/src/core/errors/ExcludedOperationError.mjs +1 -1
  16. package/src/core/lib/Charts.mjs +3 -3
  17. package/src/core/lib/Protocol.mjs +8 -6
  18. package/src/core/operations/AESDecrypt.mjs +61 -16
  19. package/src/core/operations/AESEncrypt.mjs +26 -11
  20. package/src/core/operations/BLAKE3.mjs +13 -7
  21. package/src/core/operations/BSONDeserialise.mjs +2 -2
  22. package/src/core/operations/BSONSerialise.mjs +3 -2
  23. package/src/core/operations/Bcrypt.mjs +1 -1
  24. package/src/core/operations/BcryptCompare.mjs +1 -1
  25. package/src/core/operations/DecodeText.mjs +4 -0
  26. package/src/core/operations/EncodeText.mjs +4 -0
  27. package/src/core/operations/EscapeSmartCharacters.mjs +129 -0
  28. package/src/core/operations/GenerateDeBruijnSequence.mjs +8 -0
  29. package/src/core/operations/GenerateLoremIpsum.mjs +34 -3
  30. package/src/core/operations/GeneratePGPKeyPair.mjs +8 -7
  31. package/src/core/operations/PGPSign.mjs +83 -0
  32. package/src/core/operations/ParityBit.mjs +1 -1
  33. package/src/core/operations/ParseEthernetFrame.mjs +1 -1
  34. package/src/core/operations/ParseIPv4Header.mjs +2 -2
  35. package/src/core/operations/ParseObjectIDTimestamp.mjs +2 -2
  36. package/src/core/operations/ParseUserAgent.mjs +1 -1
  37. package/src/core/operations/ROR13.mjs +83 -0
  38. package/src/core/operations/RemoveANSIEscapeCodes.mjs +41 -0
  39. package/src/core/operations/SHA2.mjs +1 -1
  40. package/src/core/operations/SeriesChart.mjs +16 -0
  41. package/src/core/operations/ToHexdump.mjs +7 -1
  42. package/src/core/operations/Wrap.mjs +47 -0
  43. package/src/core/operations/XORChecksum.mjs +10 -3
  44. package/src/core/operations/index.mjs +10 -0
  45. package/src/node/index.mjs +25 -0
  46. package/src/web/App.mjs +19 -1
  47. package/src/web/HTMLIngredient.mjs +1 -0
  48. package/src/web/html/index.html +3 -3
  49. package/src/web/static/sitemap.mjs +3 -3
  50. package/src/web/waiters/RecipeWaiter.mjs +9 -1
  51. package/tests/browser/02_ops.js +7 -7
  52. package/tests/browser/03_recipe_load.js +48 -0
  53. package/tests/browser/browserUtils.js +6 -3
  54. package/tests/node/index.mjs +2 -0
  55. package/tests/node/tests/PGP.mjs +69 -0
  56. package/tests/node/tests/lib/ChartsProtocolPrototypePollution.mjs +90 -0
  57. package/tests/node/tests/operations.mjs +41 -2
  58. package/tests/operations/index.mjs +71 -66
  59. package/tests/operations/tests/BLAKE3.mjs +18 -0
  60. package/tests/operations/tests/CharEnc.mjs +26 -0
  61. package/tests/operations/tests/Charts.mjs +11 -0
  62. package/tests/operations/tests/Crypt.mjs +288 -62
  63. package/tests/operations/tests/EscapeSmartCharacters.mjs +132 -0
  64. package/tests/operations/tests/FlaskSession.mjs +11 -8
  65. package/tests/operations/tests/GenerateLoremIpsum.mjs +80 -0
  66. package/tests/operations/tests/Hexdump.mjs +11 -0
  67. package/tests/operations/tests/IPv6Transition.mjs +4 -4
  68. package/tests/operations/tests/PGP.mjs +178 -154
  69. package/tests/operations/tests/ParseEthernetFrame.mjs +11 -0
  70. package/tests/operations/tests/ParseIPv4Header.mjs +34 -0
  71. package/tests/operations/tests/ParseX509CRL.mjs +16 -16
  72. package/tests/operations/tests/ROR13.mjs +45 -0
  73. package/tests/operations/tests/Register.mjs +3 -1
  74. package/tests/operations/tests/RemoveANSIEscapeCodes.mjs +62 -0
  75. package/tests/operations/tests/Wrap.mjs +44 -0
@@ -20,7 +20,7 @@ class ParityBit extends Operation {
20
20
 
21
21
  this.name = "Parity Bit";
22
22
  this.module = "Default";
23
- this.description = "A parity bit, or check bit, is the simplest form of error detection. It is a bit which is added to a string of bits and represents if the number of 1's in the binary string is an even number or odd number.<br><br>If a delimiter is specified, the parity bit calculation will be performed on each 'block' of the input data, where the blocks are created by slicing the input at each occurence of the delimiter character";
23
+ this.description = "A parity bit, or check bit, is the simplest form of error detection. It is a bit which is added to a string of bits and represents if the number of 1's in the binary string is an even number or odd number.<br><br>If a delimiter is specified, the parity bit calculation will be performed on each 'block' of the input data, where the blocks are created by slicing the input at each occurrence of the delimiter character";
24
24
  this.infoURL = "https://wikipedia.org/wiki/Parity_bit";
25
25
  this.inputType = "string";
26
26
  this.outputType = "string";
@@ -92,7 +92,7 @@ class ParseEthernetFrame extends Operation {
92
92
  const packetData = input.slice(offset);
93
93
 
94
94
  if (outputFormat === "Packet data") {
95
- return Utils.byteArrayToChars(packetData);
95
+ return Utils.escapeHtml(Utils.byteArrayToChars(packetData));
96
96
  } else if (outputFormat === "Packet data (hex)") {
97
97
  return toHex(packetData);
98
98
  } else if (outputFormat === "Text output") {
@@ -74,7 +74,7 @@ class ParseIPv4Header extends Operation {
74
74
  checksum = input[10] << 8 | input[11],
75
75
  srcIP = input[12] << 24 | input[13] << 16 | input[14] << 8 | input[15],
76
76
  dstIP = input[16] << 24 | input[17] << 16 | input[18] << 8 | input[19],
77
- checksumHeader = input.slice(0, 10).concat([0, 0]).concat(input.slice(12, 20));
77
+ checksumHeader = [...input.slice(0, 10), 0, 0, ...input.slice(12, 20)];
78
78
  let version = (input[0] >>> 4) & 0x0f,
79
79
  options = [];
80
80
 
@@ -138,7 +138,7 @@ class ParseIPv4Header extends Operation {
138
138
  } else if (outputFormat === "Data (hex)") {
139
139
  return toHex(data);
140
140
  } else if (outputFormat === "Data (raw)") {
141
- return Utils.byteArrayToChars(data);
141
+ return Utils.escapeHtml(Utils.byteArrayToChars(data));
142
142
  }
143
143
  }
144
144
 
@@ -6,7 +6,7 @@
6
6
 
7
7
  import Operation from "../Operation.mjs";
8
8
  import OperationError from "../errors/OperationError.mjs";
9
- import BSON from "bson";
9
+ import { ObjectId } from "bson";
10
10
 
11
11
  /**
12
12
  * Parse ObjectID timestamp operation
@@ -35,7 +35,7 @@ class ParseObjectIDTimestamp extends Operation {
35
35
  */
36
36
  run(input, args) {
37
37
  try {
38
- const objectId = new BSON.ObjectID(input);
38
+ const objectId = new ObjectId(input);
39
39
  return objectId.getTimestamp().toISOString();
40
40
  } catch (err) {
41
41
  throw new OperationError(err);
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  import Operation from "../Operation.mjs";
8
- import UAParser from "ua-parser-js";
8
+ import { UAParser } from "ua-parser-js";
9
9
 
10
10
  /**
11
11
  * Parse User Agent operation
@@ -0,0 +1,83 @@
1
+ /**
2
+ * ROR13 Hash operation (Windows API hashing convention)
3
+ * @author fufu_btw
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+
9
+ /**
10
+ * Implements a ROR13 hash used for API name hashing techniques.
11
+ */
12
+ class ROR13 extends Operation {
13
+
14
+ /**
15
+ * Constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "ROR13";
21
+ this.module = "Default";
22
+ this.description = "Computes a ROR13 hash used in API hashing techniques.";
23
+ this.infoURL = "";
24
+ this.inputType = "byteArray";
25
+ this.outputType = "string";
26
+
27
+ this.args = [];
28
+ }
29
+
30
+ /**
31
+ * Rotate right (32-bit)
32
+ *
33
+ * @param {number} value - input value
34
+ * @param {number} bits - rotation bits
35
+ * @returns {number} rotated value
36
+ */
37
+ ror(value, bits) {
38
+ return ((value >>> bits) | (value << (32 - bits))) >>> 0;
39
+ }
40
+
41
+ /**
42
+ * Execute ROR13 hash
43
+ *
44
+ * @param {byteArray} input - input bytes
45
+ * @param {Object[]} args - operation arguments
46
+ * @returns {string} hex hash
47
+ */
48
+ run(input, args) {
49
+ let hash = 0;
50
+
51
+ for (let i = 0; i < input.length; i++) {
52
+ const chr = input[i] & 0xFF;
53
+ hash = this.ror(hash, 13);
54
+ hash = (hash + chr) >>> 0;
55
+ }
56
+
57
+ return "0x" + hash.toString(16).padStart(8, "0").toUpperCase();
58
+ }
59
+
60
+ /**
61
+ * Highlight input
62
+ *
63
+ * @param {Object[]} pos
64
+ * @param {Object[]} args
65
+ * @returns {Object[]}
66
+ */
67
+ highlight(pos, args) {
68
+ return pos;
69
+ }
70
+
71
+ /**
72
+ * Reverse highlight
73
+ *
74
+ * @param {Object[]} pos
75
+ * @param {Object[]} args
76
+ * @returns {Object[]}
77
+ */
78
+ highlightReverse(pos, args) {
79
+ return pos;
80
+ }
81
+ }
82
+
83
+ export default ROR13;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * @author Louis-Ladd [lewisharshman1@gmail.com]
3
+ * @copyright Crown Copyright 2025
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+
9
+ /**
10
+ * Remove ANSI Escape Codes operation
11
+ */
12
+ class RemoveANSIEscapeCodes extends Operation {
13
+
14
+ /**
15
+ * RemoveANSIEscapeCodes constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "Remove ANSI Escape Codes";
21
+ this.module = "Default";
22
+ this.description = "Removes ANSI Escape Codes.";
23
+ this.infoURL = "https://wikipedia.org/wiki/ANSI_escape_code";
24
+ this.inputType = "string";
25
+ this.outputType = "string";
26
+ this.args = [];
27
+ }
28
+
29
+ /**
30
+ * @param {string} input
31
+ * @param {Object[]} args
32
+ * @returns {string}
33
+ */
34
+ run(input, args) {
35
+ const ansiRegex = /\x1B\[[0-?]*[ -/]*[@-~]/g;
36
+ return input.replace(ansiRegex, "");
37
+ }
38
+
39
+ }
40
+
41
+ export default RemoveANSIEscapeCodes;
@@ -20,7 +20,7 @@ class SHA2 extends Operation {
20
20
 
21
21
  this.name = "SHA2";
22
22
  this.module = "Crypto";
23
- this.description = "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.<br><br><ul><li>SHA-512 operates on 64-bit words.</li><li>SHA-256 operates on 32-bit words.</li><li>SHA-384 is largely identical to SHA-512 but is truncated to 384 bytes.</li><li>SHA-224 is largely identical to SHA-256 but is truncated to 224 bytes.</li><li>SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.</li></ul> The message digest algorithm for SHA256 variants consists, by default, of 64 rounds, and for SHA512 variants, it is, by default, 160.";
23
+ this.description = "The SHA-2 (Secure Hash Algorithm 2) hash functions were designed by the NSA. SHA-2 includes significant changes from its predecessor, SHA-1. The SHA-2 family consists of hash functions with digests (hash values) that are 224, 256, 384 or 512 bits: SHA224, SHA256, SHA384, SHA512.<br><br><ul><li>SHA-512 operates on 64-bit words.</li><li>SHA-256 operates on 32-bit words.</li><li>SHA-384 is largely identical to SHA-512 but is truncated to 384 bits.</li><li>SHA-224 is largely identical to SHA-256 but is truncated to 224 bits.</li><li>SHA-512/224 and SHA-512/256 are truncated versions of SHA-512, but the initial values are generated using the method described in Federal Information Processing Standards (FIPS) PUB 180-4.</li></ul> The message digest algorithm for SHA256 variants consists, by default, of 64 rounds, and for SHA512 variants, it is, by default, 160.";
24
24
  this.infoURL = "https://wikipedia.org/wiki/SHA-2";
25
25
  this.inputType = "ArrayBuffer";
26
26
  this.outputType = "string";
@@ -15,6 +15,20 @@ import Utils from "../Utils.mjs";
15
15
  const d3 = d3temp.default ? d3temp.default : d3temp;
16
16
  const nodom = nodomtemp.default ? nodomtemp.default: nodomtemp;
17
17
 
18
+ /**
19
+ * Removes D3's internal bound data from a nodom tree before serialization.
20
+ * nodom serializes enumerable expando properties such as __data__ as attributes,
21
+ * so leaving them on attacker-controlled values can create executable markup.
22
+ *
23
+ * @param {Object} node
24
+ */
25
+ function clearD3BoundData(node) {
26
+ delete node.__data__;
27
+
28
+ if (!node.childNodes) return;
29
+ node.childNodes.forEach(clearD3BoundData);
30
+ }
31
+
18
32
  /**
19
33
  * Series chart operation
20
34
  */
@@ -222,6 +236,8 @@ class SeriesChart extends Operation {
222
236
  .text(serie.name);
223
237
  });
224
238
 
239
+ clearD3BoundData(svg.node());
240
+
225
241
  return svg._groups[0][0].outerHTML;
226
242
  }
227
243
 
@@ -8,6 +8,8 @@ import Operation from "../Operation.mjs";
8
8
  import Utils from "../Utils.mjs";
9
9
  import OperationError from "../errors/OperationError.mjs";
10
10
 
11
+ const MAX_WIDTH = 65536;
12
+
11
13
  /**
12
14
  * To Hexdump operation
13
15
  */
@@ -30,7 +32,8 @@ class ToHexdump extends Operation {
30
32
  "name": "Width",
31
33
  "type": "number",
32
34
  "value": 16,
33
- "min": 1
35
+ "min": 1,
36
+ "max": MAX_WIDTH
34
37
  },
35
38
  {
36
39
  "name": "Upper case hex",
@@ -63,6 +66,9 @@ class ToHexdump extends Operation {
63
66
  if (length < 1 || Math.round(length) !== length)
64
67
  throw new OperationError("Width must be a positive integer");
65
68
 
69
+ if (length > MAX_WIDTH)
70
+ throw new OperationError(`Width must be no more than ${MAX_WIDTH}`);
71
+
66
72
  const lines = [];
67
73
  for (let i = 0; i < data.length; i += length) {
68
74
  let lineNo = Utils.hex(i, 8);
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @author 0xff1ce [github.com/0xff1ce]
3
+ * @copyright Crown Copyright 2024
4
+ * @license Apache-2.0
5
+ */
6
+
7
+ import Operation from "../Operation.mjs";
8
+
9
+ /**
10
+ * Wrap operation
11
+ */
12
+ class Wrap extends Operation {
13
+
14
+ /**
15
+ * Wrap constructor
16
+ */
17
+ constructor() {
18
+ super();
19
+
20
+ this.name = "Wrap";
21
+ this.module = "Default";
22
+ this.description = "Wraps the input text at a specified number of characters per line.";
23
+ this.inputType = "string";
24
+ this.outputType = "string";
25
+ this.args = [
26
+ {
27
+ "name": "Line Width",
28
+ "type": "number",
29
+ "value": 64,
30
+ },
31
+ ];
32
+ }
33
+
34
+ /**
35
+ * @param {string} input
36
+ * @param {Object[]} args
37
+ * @returns {string}
38
+ */
39
+ run(input, args) {
40
+ if (!input) return ""; // Handle empty input
41
+ const lineWidth = args[0];
42
+ const regex = new RegExp(`.{1,${lineWidth}}`, "g");
43
+ return input.match(regex).join("\n");
44
+ }
45
+ }
46
+
47
+ export default Wrap;
@@ -7,12 +7,12 @@
7
7
  import Operation from "../Operation.mjs";
8
8
  import Utils from "../Utils.mjs";
9
9
  import { toHex } from "../lib/Hex.mjs";
10
+ import OperationError from "../errors/OperationError.mjs";
10
11
 
11
12
  /**
12
13
  * XOR Checksum operation
13
14
  */
14
15
  class XORChecksum extends Operation {
15
-
16
16
  /**
17
17
  * XORChecksum constructor
18
18
  */
@@ -21,7 +21,8 @@ class XORChecksum extends Operation {
21
21
 
22
22
  this.name = "XOR Checksum";
23
23
  this.module = "Crypto";
24
- this.description = "XOR Checksum splits the input into blocks of a configurable size and performs the XOR operation on these blocks.";
24
+ this.description =
25
+ "XOR Checksum splits the input into blocks of a configurable size and performs the XOR operation on these blocks.";
25
26
  this.infoURL = "https://wikipedia.org/wiki/XOR";
26
27
  this.inputType = "ArrayBuffer";
27
28
  this.outputType = "string";
@@ -29,7 +30,7 @@ class XORChecksum extends Operation {
29
30
  {
30
31
  name: "Blocksize",
31
32
  type: "number",
32
- value: 4
33
+ value: 4,
33
34
  },
34
35
  ];
35
36
  }
@@ -41,6 +42,12 @@ class XORChecksum extends Operation {
41
42
  */
42
43
  run(input, args) {
43
44
  const blocksize = args[0];
45
+
46
+
47
+ if (!Number.isInteger(blocksize) || blocksize <= 0) {
48
+ throw new OperationError("Blocksize must be a positive integer.");
49
+ }
50
+
44
51
  input = new Uint8Array(input);
45
52
 
46
53
  const res = Array(blocksize);
@@ -114,6 +114,7 @@ import EncodeNetBIOSName from "./EncodeNetBIOSName.mjs";
114
114
  import EncodeText from "./EncodeText.mjs";
115
115
  import Enigma from "./Enigma.mjs";
116
116
  import Entropy from "./Entropy.mjs";
117
+ import EscapeSmartCharacters from "./EscapeSmartCharacters.mjs";
117
118
  import EscapeString from "./EscapeString.mjs";
118
119
  import EscapeUnicodeCharacters from "./EscapeUnicodeCharacters.mjs";
119
120
  import ExpandAlphabetRange from "./ExpandAlphabetRange.mjs";
@@ -283,6 +284,7 @@ import PGPDecrypt from "./PGPDecrypt.mjs";
283
284
  import PGPDecryptAndVerify from "./PGPDecryptAndVerify.mjs";
284
285
  import PGPEncrypt from "./PGPEncrypt.mjs";
285
286
  import PGPEncryptAndSign from "./PGPEncryptAndSign.mjs";
287
+ import PGPSign from "./PGPSign.mjs";
286
288
  import PGPVerify from "./PGPVerify.mjs";
287
289
  import PHPDeserialize from "./PHPDeserialize.mjs";
288
290
  import PHPSerialize from "./PHPSerialize.mjs";
@@ -325,6 +327,7 @@ import RC4Drop from "./RC4Drop.mjs";
325
327
  import RC6Decrypt from "./RC6Decrypt.mjs";
326
328
  import RC6Encrypt from "./RC6Encrypt.mjs";
327
329
  import RIPEMD from "./RIPEMD.mjs";
330
+ import ROR13 from "./ROR13.mjs";
328
331
  import ROT13 from "./ROT13.mjs";
329
332
  import ROT13BruteForce from "./ROT13BruteForce.mjs";
330
333
  import ROT47 from "./ROT47.mjs";
@@ -342,6 +345,7 @@ import RawDeflate from "./RawDeflate.mjs";
342
345
  import RawInflate from "./RawInflate.mjs";
343
346
  import Register from "./Register.mjs";
344
347
  import RegularExpression from "./RegularExpression.mjs";
348
+ import RemoveANSIEscapeCodes from "./RemoveANSIEscapeCodes.mjs";
345
349
  import RemoveDiacritics from "./RemoveDiacritics.mjs";
346
350
  import RemoveEXIF from "./RemoveEXIF.mjs";
347
351
  import RemoveLineNumbers from "./RemoveLineNumbers.mjs";
@@ -466,6 +470,7 @@ import VigenèreDecode from "./VigenèreDecode.mjs";
466
470
  import VigenèreEncode from "./VigenèreEncode.mjs";
467
471
  import Whirlpool from "./Whirlpool.mjs";
468
472
  import WindowsFiletimeToUNIXTimestamp from "./WindowsFiletimeToUNIXTimestamp.mjs";
473
+ import Wrap from "./Wrap.mjs";
469
474
  import XKCDRandomNumber from "./XKCDRandomNumber.mjs";
470
475
  import XMLBeautify from "./XMLBeautify.mjs";
471
476
  import XMLMinify from "./XMLMinify.mjs";
@@ -592,6 +597,7 @@ export {
592
597
  EncodeText,
593
598
  Enigma,
594
599
  Entropy,
600
+ EscapeSmartCharacters,
595
601
  EscapeString,
596
602
  EscapeUnicodeCharacters,
597
603
  ExpandAlphabetRange,
@@ -761,6 +767,7 @@ export {
761
767
  PGPDecryptAndVerify,
762
768
  PGPEncrypt,
763
769
  PGPEncryptAndSign,
770
+ PGPSign,
764
771
  PGPVerify,
765
772
  PHPDeserialize,
766
773
  PHPSerialize,
@@ -803,6 +810,7 @@ export {
803
810
  RC6Decrypt,
804
811
  RC6Encrypt,
805
812
  RIPEMD,
813
+ ROR13,
806
814
  ROT13,
807
815
  ROT13BruteForce,
808
816
  ROT47,
@@ -820,6 +828,7 @@ export {
820
828
  RawInflate,
821
829
  Register,
822
830
  RegularExpression,
831
+ RemoveANSIEscapeCodes,
823
832
  RemoveDiacritics,
824
833
  RemoveEXIF,
825
834
  RemoveLineNumbers,
@@ -944,6 +953,7 @@ export {
944
953
  VigenèreEncode,
945
954
  Whirlpool,
946
955
  WindowsFiletimeToUNIXTimestamp,
956
+ Wrap,
947
957
  XKCDRandomNumber,
948
958
  XMLBeautify,
949
959
  XMLMinify,
@@ -122,6 +122,7 @@ import {
122
122
  EncodeText as core_EncodeText,
123
123
  Enigma as core_Enigma,
124
124
  Entropy as core_Entropy,
125
+ EscapeSmartCharacters as core_EscapeSmartCharacters,
125
126
  EscapeString as core_EscapeString,
126
127
  EscapeUnicodeCharacters as core_EscapeUnicodeCharacters,
127
128
  ExpandAlphabetRange as core_ExpandAlphabetRange,
@@ -284,6 +285,7 @@ import {
284
285
  PGPDecryptAndVerify as core_PGPDecryptAndVerify,
285
286
  PGPEncrypt as core_PGPEncrypt,
286
287
  PGPEncryptAndSign as core_PGPEncryptAndSign,
288
+ PGPSign as core_PGPSign,
287
289
  PGPVerify as core_PGPVerify,
288
290
  PHPDeserialize as core_PHPDeserialize,
289
291
  PHPSerialize as core_PHPSerialize,
@@ -326,6 +328,7 @@ import {
326
328
  RC6Decrypt as core_RC6Decrypt,
327
329
  RC6Encrypt as core_RC6Encrypt,
328
330
  RIPEMD as core_RIPEMD,
331
+ ROR13 as core_ROR13,
329
332
  ROT13 as core_ROT13,
330
333
  ROT13BruteForce as core_ROT13BruteForce,
331
334
  ROT47 as core_ROT47,
@@ -343,6 +346,7 @@ import {
343
346
  RawInflate as core_RawInflate,
344
347
  Register as core_Register,
345
348
  RegularExpression as core_RegularExpression,
349
+ RemoveANSIEscapeCodes as core_RemoveANSIEscapeCodes,
346
350
  RemoveDiacritics as core_RemoveDiacritics,
347
351
  RemoveEXIF as core_RemoveEXIF,
348
352
  RemoveLineNumbers as core_RemoveLineNumbers,
@@ -466,6 +470,7 @@ import {
466
470
  VigenèreEncode as core_VigenèreEncode,
467
471
  Whirlpool as core_Whirlpool,
468
472
  WindowsFiletimeToUNIXTimestamp as core_WindowsFiletimeToUNIXTimestamp,
473
+ Wrap as core_Wrap,
469
474
  XKCDRandomNumber as core_XKCDRandomNumber,
470
475
  XMLBeautify as core_XMLBeautify,
471
476
  XMLMinify as core_XMLMinify,
@@ -600,6 +605,7 @@ function generateChef() {
600
605
  "encodeText": _wrap(core_EncodeText),
601
606
  "enigma": _wrap(core_Enigma),
602
607
  "entropy": _wrap(core_Entropy),
608
+ "escapeSmartCharacters": _wrap(core_EscapeSmartCharacters),
603
609
  "escapeString": _wrap(core_EscapeString),
604
610
  "escapeUnicodeCharacters": _wrap(core_EscapeUnicodeCharacters),
605
611
  "expandAlphabetRange": _wrap(core_ExpandAlphabetRange),
@@ -762,6 +768,7 @@ function generateChef() {
762
768
  "PGPDecryptAndVerify": _wrap(core_PGPDecryptAndVerify),
763
769
  "PGPEncrypt": _wrap(core_PGPEncrypt),
764
770
  "PGPEncryptAndSign": _wrap(core_PGPEncryptAndSign),
771
+ "PGPSign": _wrap(core_PGPSign),
765
772
  "PGPVerify": _wrap(core_PGPVerify),
766
773
  "PHPDeserialize": _wrap(core_PHPDeserialize),
767
774
  "PHPSerialize": _wrap(core_PHPSerialize),
@@ -804,6 +811,7 @@ function generateChef() {
804
811
  "RC6Decrypt": _wrap(core_RC6Decrypt),
805
812
  "RC6Encrypt": _wrap(core_RC6Encrypt),
806
813
  "RIPEMD": _wrap(core_RIPEMD),
814
+ "ROR13": _wrap(core_ROR13),
807
815
  "ROT13": _wrap(core_ROT13),
808
816
  "ROT13BruteForce": _wrap(core_ROT13BruteForce),
809
817
  "ROT47": _wrap(core_ROT47),
@@ -821,6 +829,7 @@ function generateChef() {
821
829
  "rawInflate": _wrap(core_RawInflate),
822
830
  "register": _wrap(core_Register),
823
831
  "regularExpression": _wrap(core_RegularExpression),
832
+ "removeANSIEscapeCodes": _wrap(core_RemoveANSIEscapeCodes),
824
833
  "removeDiacritics": _wrap(core_RemoveDiacritics),
825
834
  "removeEXIF": _wrap(core_RemoveEXIF),
826
835
  "removeLineNumbers": _wrap(core_RemoveLineNumbers),
@@ -944,6 +953,7 @@ function generateChef() {
944
953
  "vigenèreEncode": _wrap(core_VigenèreEncode),
945
954
  "whirlpool": _wrap(core_Whirlpool),
946
955
  "windowsFiletimeToUNIXTimestamp": _wrap(core_WindowsFiletimeToUNIXTimestamp),
956
+ "wrap": _wrap(core_Wrap),
947
957
  "XKCDRandomNumber": _wrap(core_XKCDRandomNumber),
948
958
  "XMLBeautify": _wrap(core_XMLBeautify),
949
959
  "XMLMinify": _wrap(core_XMLMinify),
@@ -1088,6 +1098,7 @@ const encodeNetBIOSName = chef.encodeNetBIOSName;
1088
1098
  const encodeText = chef.encodeText;
1089
1099
  const enigma = chef.enigma;
1090
1100
  const entropy = chef.entropy;
1101
+ const escapeSmartCharacters = chef.escapeSmartCharacters;
1091
1102
  const escapeString = chef.escapeString;
1092
1103
  const escapeUnicodeCharacters = chef.escapeUnicodeCharacters;
1093
1104
  const expandAlphabetRange = chef.expandAlphabetRange;
@@ -1257,6 +1268,7 @@ const PGPDecrypt = chef.PGPDecrypt;
1257
1268
  const PGPDecryptAndVerify = chef.PGPDecryptAndVerify;
1258
1269
  const PGPEncrypt = chef.PGPEncrypt;
1259
1270
  const PGPEncryptAndSign = chef.PGPEncryptAndSign;
1271
+ const PGPSign = chef.PGPSign;
1260
1272
  const PGPVerify = chef.PGPVerify;
1261
1273
  const PHPDeserialize = chef.PHPDeserialize;
1262
1274
  const PHPSerialize = chef.PHPSerialize;
@@ -1299,6 +1311,7 @@ const RC4Drop = chef.RC4Drop;
1299
1311
  const RC6Decrypt = chef.RC6Decrypt;
1300
1312
  const RC6Encrypt = chef.RC6Encrypt;
1301
1313
  const RIPEMD = chef.RIPEMD;
1314
+ const ROR13 = chef.ROR13;
1302
1315
  const ROT13 = chef.ROT13;
1303
1316
  const ROT13BruteForce = chef.ROT13BruteForce;
1304
1317
  const ROT47 = chef.ROT47;
@@ -1316,6 +1329,7 @@ const rawDeflate = chef.rawDeflate;
1316
1329
  const rawInflate = chef.rawInflate;
1317
1330
  const register = chef.register;
1318
1331
  const regularExpression = chef.regularExpression;
1332
+ const removeANSIEscapeCodes = chef.removeANSIEscapeCodes;
1319
1333
  const removeDiacritics = chef.removeDiacritics;
1320
1334
  const removeEXIF = chef.removeEXIF;
1321
1335
  const removeLineNumbers = chef.removeLineNumbers;
@@ -1440,6 +1454,7 @@ const vigenèreDecode = chef.vigenèreDecode;
1440
1454
  const vigenèreEncode = chef.vigenèreEncode;
1441
1455
  const whirlpool = chef.whirlpool;
1442
1456
  const windowsFiletimeToUNIXTimestamp = chef.windowsFiletimeToUNIXTimestamp;
1457
+ const wrap = chef.wrap;
1443
1458
  const XKCDRandomNumber = chef.XKCDRandomNumber;
1444
1459
  const XMLBeautify = chef.XMLBeautify;
1445
1460
  const XMLMinify = chef.XMLMinify;
@@ -1568,6 +1583,7 @@ const operations = [
1568
1583
  encodeText,
1569
1584
  enigma,
1570
1585
  entropy,
1586
+ escapeSmartCharacters,
1571
1587
  escapeString,
1572
1588
  escapeUnicodeCharacters,
1573
1589
  expandAlphabetRange,
@@ -1737,6 +1753,7 @@ const operations = [
1737
1753
  PGPDecryptAndVerify,
1738
1754
  PGPEncrypt,
1739
1755
  PGPEncryptAndSign,
1756
+ PGPSign,
1740
1757
  PGPVerify,
1741
1758
  PHPDeserialize,
1742
1759
  PHPSerialize,
@@ -1779,6 +1796,7 @@ const operations = [
1779
1796
  RC6Decrypt,
1780
1797
  RC6Encrypt,
1781
1798
  RIPEMD,
1799
+ ROR13,
1782
1800
  ROT13,
1783
1801
  ROT13BruteForce,
1784
1802
  ROT47,
@@ -1796,6 +1814,7 @@ const operations = [
1796
1814
  rawInflate,
1797
1815
  register,
1798
1816
  regularExpression,
1817
+ removeANSIEscapeCodes,
1799
1818
  removeDiacritics,
1800
1819
  removeEXIF,
1801
1820
  removeLineNumbers,
@@ -1920,6 +1939,7 @@ const operations = [
1920
1939
  vigenèreEncode,
1921
1940
  whirlpool,
1922
1941
  windowsFiletimeToUNIXTimestamp,
1942
+ wrap,
1923
1943
  XKCDRandomNumber,
1924
1944
  XMLBeautify,
1925
1945
  XMLMinify,
@@ -2052,6 +2072,7 @@ export {
2052
2072
  encodeText,
2053
2073
  enigma,
2054
2074
  entropy,
2075
+ escapeSmartCharacters,
2055
2076
  escapeString,
2056
2077
  escapeUnicodeCharacters,
2057
2078
  expandAlphabetRange,
@@ -2221,6 +2242,7 @@ export {
2221
2242
  PGPDecryptAndVerify,
2222
2243
  PGPEncrypt,
2223
2244
  PGPEncryptAndSign,
2245
+ PGPSign,
2224
2246
  PGPVerify,
2225
2247
  PHPDeserialize,
2226
2248
  PHPSerialize,
@@ -2263,6 +2285,7 @@ export {
2263
2285
  RC6Decrypt,
2264
2286
  RC6Encrypt,
2265
2287
  RIPEMD,
2288
+ ROR13,
2266
2289
  ROT13,
2267
2290
  ROT13BruteForce,
2268
2291
  ROT47,
@@ -2280,6 +2303,7 @@ export {
2280
2303
  rawInflate,
2281
2304
  register,
2282
2305
  regularExpression,
2306
+ removeANSIEscapeCodes,
2283
2307
  removeDiacritics,
2284
2308
  removeEXIF,
2285
2309
  removeLineNumbers,
@@ -2404,6 +2428,7 @@ export {
2404
2428
  vigenèreEncode,
2405
2429
  whirlpool,
2406
2430
  windowsFiletimeToUNIXTimestamp,
2431
+ wrap,
2407
2432
  XKCDRandomNumber,
2408
2433
  XMLBeautify,
2409
2434
  XMLMinify,
package/src/web/App.mjs CHANGED
@@ -42,6 +42,14 @@ class App {
42
42
  this.progress = 0;
43
43
  this.ingId = 0;
44
44
 
45
+ // stateChangeId increments on every statechange dispatch; bakeStateId records
46
+ // the stateChangeId captured when the most recent bake started. autoBake uses
47
+ // these to decide whether the output is genuinely stale, so a debounced
48
+ // autoBake firing shortly after a manual bake doesn't clobber the bake's
49
+ // hideStaleIndicator with a redundant showStaleIndicator.
50
+ this.stateChangeId = 0;
51
+ this.bakeStateId = -1;
52
+
45
53
  this.appLoaded = false;
46
54
  this.workerLoaded = false;
47
55
  this.waitersLoaded = false;
@@ -136,6 +144,9 @@ class App {
136
144
  bake(step=false) {
137
145
  if (this.baking) return;
138
146
 
147
+ // Record which state version this bake is covering.
148
+ this.bakeStateId = this.stateChangeId;
149
+
139
150
  // Reset attemptHighlight flag
140
151
  this.options.attemptHighlight = true;
141
152
 
@@ -166,7 +177,10 @@ class App {
166
177
  nums: [this.manager.tabs.getActiveTab("input")],
167
178
  step: false
168
179
  });
169
- } else {
180
+ } else if (this.bakeStateId < this.stateChangeId) {
181
+ // Only show stale-indicator if the most recent bake didn't cover the
182
+ // current state. Without this guard, a debounced autoBake firing after
183
+ // a manual bake completed would re-show the indicator on fresh output.
170
184
  this.manager.controls.showStaleIndicator();
171
185
  }
172
186
  }
@@ -768,6 +782,10 @@ class App {
768
782
  * @param {event} e
769
783
  */
770
784
  stateChange(e) {
785
+ // Bump the state-change counter synchronously so a manual bake invoked between
786
+ // here and the debounced autoBake firing can record it via bakeStateId.
787
+ this.stateChangeId++;
788
+
771
789
  debounce(function() {
772
790
  this.progress = 0;
773
791
  this.autoBake();
@@ -166,6 +166,7 @@ class HTMLIngredient {
166
166
  id="${this.id}"
167
167
  tabindex="${this.tabIndex}"
168
168
  arg-name="${this.name}"
169
+ data-target="${this.target}"
169
170
  ${this.disabled ? "disabled" : ""}>`;
170
171
  for (i = 0; i < this.value.length; i++) {
171
172
  if ((m = this.value[i].name.match(/\[([a-z0-9 -()^]+)\]/i))) {