cyberchef 10.22.0 → 10.23.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 (121) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/CONTRIBUTING.md +37 -0
  3. package/Dockerfile +2 -0
  4. package/Gruntfile.js +0 -12
  5. package/README.md +1 -1
  6. package/babel.config.js +0 -6
  7. package/package.json +63 -62
  8. package/src/core/Chef.mjs +8 -1
  9. package/src/core/Ingredient.mjs +5 -2
  10. package/src/core/Operation.mjs +6 -1
  11. package/src/core/Recipe.mjs +10 -5
  12. package/src/core/config/Categories.json +18 -3
  13. package/src/core/config/OperationConfig.json +22310 -0
  14. package/src/core/config/modules/Bletchley.mjs +28 -0
  15. package/src/core/config/modules/Charts.mjs +24 -0
  16. package/src/core/config/modules/Ciphers.mjs +128 -0
  17. package/src/core/config/modules/Code.mjs +60 -0
  18. package/src/core/config/modules/Compression.mjs +52 -0
  19. package/src/core/config/modules/Crypto.mjs +134 -0
  20. package/src/core/config/modules/Default.mjs +424 -0
  21. package/src/core/config/modules/Diff.mjs +16 -0
  22. package/src/core/config/modules/Encodings.mjs +42 -0
  23. package/src/core/config/modules/Handlebars.mjs +16 -0
  24. package/src/core/config/modules/Hashing.mjs +30 -0
  25. package/src/core/config/modules/Image.mjs +70 -0
  26. package/src/core/config/modules/Jq.mjs +16 -0
  27. package/src/core/config/modules/OCR.mjs +16 -0
  28. package/src/core/config/modules/OpModules.mjs +63 -0
  29. package/src/core/config/modules/PGP.mjs +26 -0
  30. package/src/core/config/modules/Protobuf.mjs +18 -0
  31. package/src/core/config/modules/PublicKey.mjs +36 -0
  32. package/src/core/config/modules/Regex.mjs +40 -0
  33. package/src/core/config/modules/Serialise.mjs +26 -0
  34. package/src/core/config/modules/Shellcode.mjs +18 -0
  35. package/src/core/config/modules/URL.mjs +20 -0
  36. package/src/core/config/modules/UserAgent.mjs +16 -0
  37. package/src/core/config/modules/Yara.mjs +16 -0
  38. package/src/core/lib/AudioBytes.mjs +103 -0
  39. package/src/core/lib/AudioMetaSchema.mjs +82 -0
  40. package/src/core/lib/AudioParsers.mjs +630 -0
  41. package/src/core/lib/BigIntUtils.mjs +73 -0
  42. package/src/core/lib/Modhex.mjs +2 -0
  43. package/src/core/lib/QRCode.mjs +30 -10
  44. package/src/core/lib/RC6.mjs +625 -0
  45. package/src/core/operations/A1Z26CipherDecode.mjs +1 -1
  46. package/src/core/operations/AddTextToImage.mjs +116 -64
  47. package/src/core/operations/BlurImage.mjs +10 -12
  48. package/src/core/operations/ContainImage.mjs +50 -40
  49. package/src/core/operations/ConvertImageFormat.mjs +33 -39
  50. package/src/core/operations/CoverImage.mjs +39 -37
  51. package/src/core/operations/CropImage.mjs +35 -21
  52. package/src/core/operations/DisassembleARM.mjs +193 -0
  53. package/src/core/operations/DitherImage.mjs +8 -8
  54. package/src/core/operations/EscapeUnicodeCharacters.mjs +0 -17
  55. package/src/core/operations/ExtractAudioMetadata.mjs +175 -0
  56. package/src/core/operations/ExtractLSB.mjs +17 -11
  57. package/src/core/operations/ExtractRGBA.mjs +12 -10
  58. package/src/core/operations/FlaskSessionDecode.mjs +80 -0
  59. package/src/core/operations/FlaskSessionSign.mjs +89 -0
  60. package/src/core/operations/FlaskSessionVerify.mjs +136 -0
  61. package/src/core/operations/FlipImage.mjs +14 -10
  62. package/src/core/operations/GenerateImage.mjs +39 -32
  63. package/src/core/operations/ImageBrightnessContrast.mjs +10 -10
  64. package/src/core/operations/ImageFilter.mjs +14 -13
  65. package/src/core/operations/ImageHueSaturationLightness.mjs +22 -20
  66. package/src/core/operations/ImageOpacity.mjs +6 -8
  67. package/src/core/operations/InvertImage.mjs +4 -6
  68. package/src/core/operations/Jq.mjs +12 -4
  69. package/src/core/operations/NormaliseImage.mjs +5 -7
  70. package/src/core/operations/OffsetChecker.mjs +1 -1
  71. package/src/core/operations/ParseEthernetFrame.mjs +112 -0
  72. package/src/core/operations/ParseIPv4Header.mjs +23 -6
  73. package/src/core/operations/ParseQRCode.mjs +13 -13
  74. package/src/core/operations/PseudoRandomIntegerGenerator.mjs +164 -0
  75. package/src/core/operations/RC6Decrypt.mjs +119 -0
  76. package/src/core/operations/RC6Encrypt.mjs +119 -0
  77. package/src/core/operations/RandomizeColourPalette.mjs +11 -11
  78. package/src/core/operations/ResizeImage.mjs +30 -23
  79. package/src/core/operations/RotateImage.mjs +8 -9
  80. package/src/core/operations/SQLBeautify.mjs +21 -3
  81. package/src/core/operations/SharpenImage.mjs +94 -62
  82. package/src/core/operations/SplitColourChannels.mjs +47 -21
  83. package/src/core/operations/TextIntegerConverter.mjs +123 -0
  84. package/src/core/operations/UnescapeUnicodeCharacters.mjs +17 -0
  85. package/src/core/operations/ViewBitPlane.mjs +16 -20
  86. package/src/core/operations/index.mjs +960 -0
  87. package/src/node/index.mjs +2423 -0
  88. package/src/web/HTMLIngredient.mjs +24 -43
  89. package/src/web/Manager.mjs +1 -0
  90. package/src/web/html/index.html +6 -6
  91. package/src/web/static/fonts/bmfonts/Roboto72White.fnt +491 -485
  92. package/src/web/static/fonts/bmfonts/RobotoBlack72White.fnt +494 -488
  93. package/src/web/static/fonts/bmfonts/RobotoMono72White.fnt +110 -103
  94. package/src/web/static/fonts/bmfonts/RobotoSlab72White.fnt +498 -492
  95. package/src/web/stylesheets/layout/_banner.css +30 -0
  96. package/src/web/stylesheets/layout/_modals.css +5 -0
  97. package/src/web/stylesheets/utils/_overrides.css +7 -0
  98. package/src/web/waiters/ControlsWaiter.mjs +82 -0
  99. package/src/web/waiters/InputWaiter.mjs +12 -6
  100. package/src/web/waiters/RecipeWaiter.mjs +2 -2
  101. package/tests/browser/02_ops.js +23 -3
  102. package/tests/node/index.mjs +1 -0
  103. package/tests/node/tests/lib/BigIntUtils.mjs +150 -0
  104. package/tests/node/tests/operations.mjs +9 -7
  105. package/tests/operations/index.mjs +8 -0
  106. package/tests/operations/tests/A1Z26CipherDecode.mjs +33 -0
  107. package/tests/operations/tests/DisassembleARM.mjs +377 -0
  108. package/tests/operations/tests/ExtractAudioMetadata.mjs +287 -0
  109. package/tests/operations/tests/FlaskSession.mjs +246 -0
  110. package/tests/operations/tests/GenerateQRCode.mjs +67 -0
  111. package/tests/operations/tests/JWTSign.mjs +83 -8
  112. package/tests/operations/tests/Jq.mjs +32 -0
  113. package/tests/operations/tests/Modhex.mjs +20 -0
  114. package/tests/operations/tests/ParseEthernetFrame.mjs +45 -0
  115. package/tests/operations/tests/RC6.mjs +487 -0
  116. package/tests/operations/tests/SQLBeautify.mjs +54 -0
  117. package/tests/operations/tests/TextIntegerConverter.mjs +199 -0
  118. package/tests/samples/Audio.mjs +73 -0
  119. package/tests/samples/Images.mjs +0 -12
  120. package/webpack.config.js +10 -7
  121. package/src/core/lib/ImageManipulation.mjs +0 -251
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Disassemble ARM tests.
3
+ *
4
+ * @author MedjedThomasXM
5
+ *
6
+ * @copyright Crown Copyright 2024
7
+ * @license Apache-2.0
8
+ */
9
+ import TestRegister from "../../lib/TestRegister.mjs";
10
+
11
+ TestRegister.addTests([
12
+ // ==================== ARM32 TESTS ====================
13
+ {
14
+ name: "Disassemble ARM: ARM32 NOP (mov r0, r0)",
15
+ input: "00 00 a0 e1",
16
+ expectedMatch: /mov\s+r0,\s*r0/,
17
+ recipeConfig: [
18
+ {
19
+ op: "Disassemble ARM",
20
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
21
+ },
22
+ ],
23
+ },
24
+ {
25
+ name: "Disassemble ARM: ARM32 bx lr",
26
+ input: "1e ff 2f e1",
27
+ expectedMatch: /bx\s+lr/,
28
+ recipeConfig: [
29
+ {
30
+ op: "Disassemble ARM",
31
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
32
+ },
33
+ ],
34
+ },
35
+ {
36
+ name: "Disassemble ARM: ARM32 push {fp, lr}",
37
+ input: "00 48 2d e9",
38
+ expectedMatch: /push\s+\{fp,\s*lr\}/,
39
+ recipeConfig: [
40
+ {
41
+ op: "Disassemble ARM",
42
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
43
+ },
44
+ ],
45
+ },
46
+ {
47
+ name: "Disassemble ARM: ARM32 add fp, sp, #4",
48
+ input: "04 b0 8d e2",
49
+ expectedMatch: /add\s+fp,\s*sp/,
50
+ recipeConfig: [
51
+ {
52
+ op: "Disassemble ARM",
53
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
54
+ },
55
+ ],
56
+ },
57
+ {
58
+ name: "Disassemble ARM: ARM32 ldr r0, [r1]",
59
+ input: "00 00 91 e5",
60
+ expectedMatch: /ldr\s+r0,\s*\[r1\]/,
61
+ recipeConfig: [
62
+ {
63
+ op: "Disassemble ARM",
64
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ name: "Disassemble ARM: ARM32 str r0, [r1]",
70
+ input: "00 00 81 e5",
71
+ expectedMatch: /str\s+r0,\s*\[r1\]/,
72
+ recipeConfig: [
73
+ {
74
+ op: "Disassemble ARM",
75
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
76
+ },
77
+ ],
78
+ },
79
+ {
80
+ name: "Disassemble ARM: ARM32 bl (branch link)",
81
+ input: "00 00 00 eb",
82
+ expectedMatch: /bl\s+/,
83
+ recipeConfig: [
84
+ {
85
+ op: "Disassemble ARM",
86
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
87
+ },
88
+ ],
89
+ },
90
+ {
91
+ name: "Disassemble ARM: ARM32 mul r0, r1, r2",
92
+ input: "91 02 00 e0",
93
+ expectedMatch: /mul\s+r0,\s*r1,\s*r2/,
94
+ recipeConfig: [
95
+ {
96
+ op: "Disassemble ARM",
97
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
98
+ },
99
+ ],
100
+ },
101
+
102
+ // ==================== ARM32 THUMB TESTS ====================
103
+ {
104
+ name: "Disassemble ARM: Thumb mov r0, r0",
105
+ input: "00 46",
106
+ expectedMatch: /mov\s+r0,\s*r0/,
107
+ recipeConfig: [
108
+ {
109
+ op: "Disassemble ARM",
110
+ args: ["ARM (32-bit)", "Thumb", "Little Endian", 0, true, true],
111
+ },
112
+ ],
113
+ },
114
+ {
115
+ name: "Disassemble ARM: Thumb bx lr",
116
+ input: "70 47",
117
+ expectedMatch: /bx\s+lr/,
118
+ recipeConfig: [
119
+ {
120
+ op: "Disassemble ARM",
121
+ args: ["ARM (32-bit)", "Thumb", "Little Endian", 0, true, true],
122
+ },
123
+ ],
124
+ },
125
+ {
126
+ name: "Disassemble ARM: Thumb push {r4, lr}",
127
+ input: "10 b5",
128
+ expectedMatch: /push\s+\{r4,\s*lr\}/,
129
+ recipeConfig: [
130
+ {
131
+ op: "Disassemble ARM",
132
+ args: ["ARM (32-bit)", "Thumb", "Little Endian", 0, true, true],
133
+ },
134
+ ],
135
+ },
136
+ {
137
+ name: "Disassemble ARM: Thumb pop {r4, pc}",
138
+ input: "10 bd",
139
+ expectedMatch: /pop\s+\{r4,\s*pc\}/,
140
+ recipeConfig: [
141
+ {
142
+ op: "Disassemble ARM",
143
+ args: ["ARM (32-bit)", "Thumb", "Little Endian", 0, true, true],
144
+ },
145
+ ],
146
+ },
147
+
148
+ // ==================== ARM64 TESTS ====================
149
+ {
150
+ name: "Disassemble ARM: ARM64 ret",
151
+ input: "c0 03 5f d6",
152
+ expectedMatch: /ret/,
153
+ recipeConfig: [
154
+ {
155
+ op: "Disassemble ARM",
156
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
157
+ },
158
+ ],
159
+ },
160
+ {
161
+ name: "Disassemble ARM: ARM64 mov x0, #0",
162
+ input: "00 00 80 d2",
163
+ expectedMatch: /mov[z]?\s+x0,\s*#0/,
164
+ recipeConfig: [
165
+ {
166
+ op: "Disassemble ARM",
167
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
168
+ },
169
+ ],
170
+ },
171
+ {
172
+ name: "Disassemble ARM: ARM64 stp x29, x30, [sp, #-16]!",
173
+ input: "fd 7b bf a9",
174
+ expectedMatch: /stp\s+x29,\s*x30,\s*\[sp/,
175
+ recipeConfig: [
176
+ {
177
+ op: "Disassemble ARM",
178
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
179
+ },
180
+ ],
181
+ },
182
+ {
183
+ name: "Disassemble ARM: ARM64 ldp x29, x30, [sp], #16",
184
+ input: "fd 7b c1 a8",
185
+ expectedMatch: /ldp\s+x29,\s*x30,\s*\[sp\]/,
186
+ recipeConfig: [
187
+ {
188
+ op: "Disassemble ARM",
189
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
190
+ },
191
+ ],
192
+ },
193
+ {
194
+ name: "Disassemble ARM: ARM64 add x0, x1, x2",
195
+ input: "20 00 02 8b",
196
+ expectedMatch: /add\s+x0,\s*x1,\s*x2/,
197
+ recipeConfig: [
198
+ {
199
+ op: "Disassemble ARM",
200
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
201
+ },
202
+ ],
203
+ },
204
+ {
205
+ name: "Disassemble ARM: ARM64 sub x0, x1, x2",
206
+ input: "20 00 02 cb",
207
+ expectedMatch: /sub\s+x0,\s*x1,\s*x2/,
208
+ recipeConfig: [
209
+ {
210
+ op: "Disassemble ARM",
211
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
212
+ },
213
+ ],
214
+ },
215
+ {
216
+ name: "Disassemble ARM: ARM64 mul x0, x1, x2",
217
+ input: "20 7c 02 9b",
218
+ expectedMatch: /mul\s+x0,\s*x1,\s*x2/,
219
+ recipeConfig: [
220
+ {
221
+ op: "Disassemble ARM",
222
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
223
+ },
224
+ ],
225
+ },
226
+ {
227
+ name: "Disassemble ARM: ARM64 ldr x0, [x1]",
228
+ input: "20 00 40 f9",
229
+ expectedMatch: /ldr\s+x0,\s*\[x1\]/,
230
+ recipeConfig: [
231
+ {
232
+ op: "Disassemble ARM",
233
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
234
+ },
235
+ ],
236
+ },
237
+ {
238
+ name: "Disassemble ARM: ARM64 str x0, [x1]",
239
+ input: "20 00 00 f9",
240
+ expectedMatch: /str\s+x0,\s*\[x1\]/,
241
+ recipeConfig: [
242
+ {
243
+ op: "Disassemble ARM",
244
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
245
+ },
246
+ ],
247
+ },
248
+ {
249
+ name: "Disassemble ARM: ARM64 bl (branch link)",
250
+ input: "00 00 00 94",
251
+ expectedMatch: /bl\s+/,
252
+ recipeConfig: [
253
+ {
254
+ op: "Disassemble ARM",
255
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
256
+ },
257
+ ],
258
+ },
259
+ {
260
+ name: "Disassemble ARM: ARM64 cbz x0",
261
+ input: "00 00 00 b4",
262
+ expectedMatch: /cbz\s+x0/,
263
+ recipeConfig: [
264
+ {
265
+ op: "Disassemble ARM",
266
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
267
+ },
268
+ ],
269
+ },
270
+ {
271
+ name: "Disassemble ARM: ARM64 cbnz x0",
272
+ input: "00 00 00 b5",
273
+ expectedMatch: /cbnz\s+x0/,
274
+ recipeConfig: [
275
+ {
276
+ op: "Disassemble ARM",
277
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
278
+ },
279
+ ],
280
+ },
281
+ {
282
+ name: "Disassemble ARM: ARM64 sub sp, sp, #0x20",
283
+ input: "ff 83 00 d1",
284
+ expectedMatch: /sub\s+sp,\s*sp/,
285
+ recipeConfig: [
286
+ {
287
+ op: "Disassemble ARM",
288
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
289
+ },
290
+ ],
291
+ },
292
+ {
293
+ name: "Disassemble ARM: ARM64 add sp, sp, #0x20",
294
+ input: "ff 83 00 91",
295
+ expectedMatch: /add\s+sp,\s*sp/,
296
+ recipeConfig: [
297
+ {
298
+ op: "Disassemble ARM",
299
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
300
+ },
301
+ ],
302
+ },
303
+
304
+ // ==================== MULTI-INSTRUCTION TESTS ====================
305
+ {
306
+ name: "Disassemble ARM: ARM32 multiple instructions",
307
+ input: "00 48 2d e9 04 b0 8d e2 00 00 a0 e1 00 88 bd e8",
308
+ expectedMatch: /push.*\n.*add.*\n.*mov.*\n.*pop/s,
309
+ recipeConfig: [
310
+ {
311
+ op: "Disassemble ARM",
312
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 0, true, true],
313
+ },
314
+ ],
315
+ },
316
+ {
317
+ name: "Disassemble ARM: ARM64 function prologue/epilogue",
318
+ input: "fd 7b bf a9 fd 03 00 91 00 00 80 52 fd 7b c1 a8 c0 03 5f d6",
319
+ expectedMatch: /stp.*\n.*mov.*\n.*mov.*\n.*ldp.*\n.*ret/s,
320
+ recipeConfig: [
321
+ {
322
+ op: "Disassemble ARM",
323
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
324
+ },
325
+ ],
326
+ },
327
+
328
+ // ==================== ADDRESS TESTS ====================
329
+ {
330
+ name: "Disassemble ARM: ARM64 with start address 0x1000",
331
+ input: "c0 03 5f d6",
332
+ expectedMatch: /0x00001000/,
333
+ recipeConfig: [
334
+ {
335
+ op: "Disassemble ARM",
336
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 4096, true, true],
337
+ },
338
+ ],
339
+ },
340
+ {
341
+ name: "Disassemble ARM: ARM32 with start address 0x8000",
342
+ input: "00 00 a0 e1",
343
+ expectedMatch: /0x00008000/,
344
+ recipeConfig: [
345
+ {
346
+ op: "Disassemble ARM",
347
+ args: ["ARM (32-bit)", "ARM", "Little Endian", 32768, true, true],
348
+ },
349
+ ],
350
+ },
351
+
352
+ // ==================== ENDIANNESS TESTS ====================
353
+ {
354
+ name: "Disassemble ARM: ARM32 Big Endian",
355
+ input: "e1 a0 00 00",
356
+ expectedMatch: /mov\s+r0,\s*r0/,
357
+ recipeConfig: [
358
+ {
359
+ op: "Disassemble ARM",
360
+ args: ["ARM (32-bit)", "ARM", "Big Endian", 0, true, true],
361
+ },
362
+ ],
363
+ },
364
+
365
+ // ==================== EDGE CASES ====================
366
+ {
367
+ name: "Disassemble ARM: Empty input",
368
+ input: "",
369
+ expectedOutput: "",
370
+ recipeConfig: [
371
+ {
372
+ op: "Disassemble ARM",
373
+ args: ["ARM64 (AArch64)", "ARM", "Little Endian", 0, true, true],
374
+ },
375
+ ],
376
+ },
377
+ ]);
@@ -0,0 +1,287 @@
1
+ /**
2
+ * Extract Audio Metadata operation tests.
3
+ *
4
+ * @author d0s1nt
5
+ * @copyright Crown Copyright 2025
6
+ * @license Apache-2.0
7
+ */
8
+ import TestRegister from "../../lib/TestRegister.mjs";
9
+ import {
10
+ MP3_HEX, WAV_HEX, FLAC_HEX, AAC_HEX,
11
+ AC3_HEX, OGG_HEX, OPUS_HEX, WMA_HEX,
12
+ M4A_HEX, AIFF_HEX
13
+ } from "../../samples/Audio.mjs";
14
+
15
+ TestRegister.addTests([
16
+ // ---- MP3 ----
17
+ {
18
+ name: "Extract Audio Metadata: MP3 container and MIME",
19
+ input: MP3_HEX,
20
+ expectedMatch: /Container<\/td><td>mp3<\/td>.*MIME<\/td><td>audio\/mpeg<\/td>/s,
21
+ recipeConfig: [
22
+ { op: "From Hex", args: ["None"] },
23
+ { op: "Extract Audio Metadata", args: ["test.mp3", 524288] }
24
+ ]
25
+ },
26
+ {
27
+ name: "Extract Audio Metadata: MP3 common tags (title, artist)",
28
+ input: MP3_HEX,
29
+ expectedMatch: /Title<\/td><td>Galway<\/td>.*Artist<\/td><td>Kevin MacLeod<\/td>/s,
30
+ recipeConfig: [
31
+ { op: "From Hex", args: ["None"] },
32
+ { op: "Extract Audio Metadata", args: ["test.mp3", 524288] }
33
+ ]
34
+ },
35
+ {
36
+ name: "Extract Audio Metadata: MP3 ID3v2 frames (TIT2, TPE1, TSSE)",
37
+ input: MP3_HEX,
38
+ expectedMatch: /ID3v2 Frames.*TIT2.*Galway.*TPE1.*Kevin MacLeod.*TSSE.*Lavf56\.40\.101/s,
39
+ recipeConfig: [
40
+ { op: "From Hex", args: ["None"] },
41
+ { op: "Extract Audio Metadata", args: ["test.mp3", 524288] }
42
+ ]
43
+ },
44
+ {
45
+ name: "Extract Audio Metadata: MP3 detections (id3v2)",
46
+ input: MP3_HEX,
47
+ expectedMatch: /Metadata systems<\/td><td>id3v2<\/td>/,
48
+ recipeConfig: [
49
+ { op: "From Hex", args: ["None"] },
50
+ { op: "Extract Audio Metadata", args: ["test.mp3", 524288] }
51
+ ]
52
+ },
53
+
54
+ // ---- WAV ----
55
+ {
56
+ name: "Extract Audio Metadata: WAV container and MIME",
57
+ input: WAV_HEX,
58
+ expectedMatch: /Container<\/td><td>wav<\/td>.*MIME<\/td><td>audio\/wav<\/td>/s,
59
+ recipeConfig: [
60
+ { op: "From Hex", args: ["None"] },
61
+ { op: "Extract Audio Metadata", args: ["test.wav", 524288] }
62
+ ]
63
+ },
64
+ {
65
+ name: "Extract Audio Metadata: WAV RIFF chunks (fmt)",
66
+ input: WAV_HEX,
67
+ expectedMatch: /RIFF Chunks.*fmt .*16 bytes @ offset 20/s,
68
+ recipeConfig: [
69
+ { op: "From Hex", args: ["None"] },
70
+ { op: "Extract Audio Metadata", args: ["test.wav", 524288] }
71
+ ]
72
+ },
73
+
74
+ // ---- FLAC ----
75
+ {
76
+ name: "Extract Audio Metadata: FLAC container and common tags",
77
+ input: FLAC_HEX,
78
+ expectedMatch: /Container<\/td><td>flac<\/td>.*Title<\/td><td>Galway<\/td>.*Artist<\/td><td>Kevin MacLeod<\/td>/s,
79
+ recipeConfig: [
80
+ { op: "From Hex", args: ["None"] },
81
+ { op: "Extract Audio Metadata", args: ["test.flac", 524288] }
82
+ ]
83
+ },
84
+ {
85
+ name: "Extract Audio Metadata: FLAC metadata blocks (STREAMINFO, VORBIS_COMMENT)",
86
+ input: FLAC_HEX,
87
+ expectedMatch: /FLAC Metadata Blocks.*STREAMINFO<\/td><td>34 bytes<\/td>.*VORBIS_COMMENT<\/td><td>86 bytes<\/td>/s,
88
+ recipeConfig: [
89
+ { op: "From Hex", args: ["None"] },
90
+ { op: "Extract Audio Metadata", args: ["test.flac", 524288] }
91
+ ]
92
+ },
93
+ {
94
+ name: "Extract Audio Metadata: FLAC Vorbis comments (vendor, tags)",
95
+ input: FLAC_HEX,
96
+ expectedMatch: /Vorbis Comments.*Vendor<\/td><td>Lavf56\.40\.101<\/td>.*TITLE<\/td><td>Galway<\/td>.*ARTIST<\/td><td>Kevin MacLeod<\/td>.*ENCODER<\/td><td>Lavf56\.40\.101<\/td>/s,
97
+ recipeConfig: [
98
+ { op: "From Hex", args: ["None"] },
99
+ { op: "Extract Audio Metadata", args: ["test.flac", 524288] }
100
+ ]
101
+ },
102
+ {
103
+ name: "Extract Audio Metadata: FLAC detections",
104
+ input: FLAC_HEX,
105
+ expectedMatch: /Metadata systems<\/td><td>flac_metablocks, vorbis_comments<\/td>/,
106
+ recipeConfig: [
107
+ { op: "From Hex", args: ["None"] },
108
+ { op: "Extract Audio Metadata", args: ["test.flac", 524288] }
109
+ ]
110
+ },
111
+
112
+ // ---- AAC ----
113
+ {
114
+ name: "Extract Audio Metadata: AAC container and MIME",
115
+ input: AAC_HEX,
116
+ expectedMatch: /Container<\/td><td>aac<\/td>.*MIME<\/td><td>audio\/aac<\/td>/s,
117
+ recipeConfig: [
118
+ { op: "From Hex", args: ["None"] },
119
+ { op: "Extract Audio Metadata", args: ["test.aac", 524288] }
120
+ ]
121
+ },
122
+ {
123
+ name: "Extract Audio Metadata: AAC ADTS technical fields",
124
+ input: AAC_HEX,
125
+ expectedMatch: /AAC ADTS.*mpeg_version<\/td><td>MPEG-4<\/td>.*profile<\/td><td>LC<\/td>.*sample_rate<\/td><td>44100<\/td>.*channel_description<\/td><td>stereo<\/td>/s,
126
+ recipeConfig: [
127
+ { op: "From Hex", args: ["None"] },
128
+ { op: "Extract Audio Metadata", args: ["test.aac", 524288] }
129
+ ]
130
+ },
131
+
132
+ // ---- AC3 ----
133
+ {
134
+ name: "Extract Audio Metadata: AC3 container and MIME",
135
+ input: AC3_HEX,
136
+ expectedMatch: /Container<\/td><td>ac3<\/td>.*MIME<\/td><td>audio\/ac3<\/td>/s,
137
+ recipeConfig: [
138
+ { op: "From Hex", args: ["None"] },
139
+ { op: "Extract Audio Metadata", args: ["test.ac3", 524288] }
140
+ ]
141
+ },
142
+ {
143
+ name: "Extract Audio Metadata: AC3 technical fields (sample rate, bitrate, channels)",
144
+ input: AC3_HEX,
145
+ expectedMatch: /AC3 \(Dolby Digital\).*sample_rate<\/td><td>44100<\/td>.*bitrate_kbps<\/td><td>192<\/td>.*channel_layout<\/td><td>2\.0 \(L R\)<\/td>/s,
146
+ recipeConfig: [
147
+ { op: "From Hex", args: ["None"] },
148
+ { op: "Extract Audio Metadata", args: ["test.ac3", 524288] }
149
+ ]
150
+ },
151
+
152
+ // ---- OGG Vorbis ----
153
+ {
154
+ name: "Extract Audio Metadata: OGG container and common tags",
155
+ input: OGG_HEX,
156
+ expectedMatch: /Container<\/td><td>ogg<\/td>.*Title<\/td><td>Galway<\/td>.*Artist<\/td><td>Kevin MacLeod<\/td>/s,
157
+ recipeConfig: [
158
+ { op: "From Hex", args: ["None"] },
159
+ { op: "Extract Audio Metadata", args: ["test.ogg", 524288] }
160
+ ]
161
+ },
162
+ {
163
+ name: "Extract Audio Metadata: OGG Vorbis comments (vendor, encoder)",
164
+ input: OGG_HEX,
165
+ expectedMatch: /Vorbis Comments.*Vendor<\/td><td>Lavf56\.40\.101<\/td>.*ENCODER<\/td><td>Lavc56\.60\.100 libvorbis<\/td>/s,
166
+ recipeConfig: [
167
+ { op: "From Hex", args: ["None"] },
168
+ { op: "Extract Audio Metadata", args: ["test.ogg", 524288] }
169
+ ]
170
+ },
171
+
172
+ // ---- Opus ----
173
+ {
174
+ name: "Extract Audio Metadata: Opus container and common tags",
175
+ input: OPUS_HEX,
176
+ expectedMatch: /Container<\/td><td>opus<\/td>.*Title<\/td><td>Galway<\/td>.*Artist<\/td><td>Kevin MacLeod<\/td>/s,
177
+ recipeConfig: [
178
+ { op: "From Hex", args: ["None"] },
179
+ { op: "Extract Audio Metadata", args: ["test.opus", 524288] }
180
+ ]
181
+ },
182
+ {
183
+ name: "Extract Audio Metadata: Opus Vorbis comments (vendor, encoder)",
184
+ input: OPUS_HEX,
185
+ expectedMatch: /Vorbis Comments.*Vendor<\/td><td>Lavf58\.19\.102<\/td>.*ENCODER<\/td><td>Lavc58\.34\.100 libopus<\/td>/s,
186
+ recipeConfig: [
187
+ { op: "From Hex", args: ["None"] },
188
+ { op: "Extract Audio Metadata", args: ["test.opus", 524288] }
189
+ ]
190
+ },
191
+
192
+ // ---- WMA/ASF ----
193
+ {
194
+ name: "Extract Audio Metadata: WMA container and MIME",
195
+ input: WMA_HEX,
196
+ expectedMatch: /Container<\/td><td>wma<\/td>.*MIME<\/td><td>audio\/x-ms-wma<\/td>/s,
197
+ recipeConfig: [
198
+ { op: "From Hex", args: ["None"] },
199
+ { op: "Extract Audio Metadata", args: ["test.wma", 524288] }
200
+ ]
201
+ },
202
+ {
203
+ name: "Extract Audio Metadata: WMA common tags (title, artist)",
204
+ input: WMA_HEX,
205
+ expectedMatch: /Title<\/td><td>Galway<\/td>.*Artist<\/td><td>Kevin MacLeod<\/td>/s,
206
+ recipeConfig: [
207
+ { op: "From Hex", args: ["None"] },
208
+ { op: "Extract Audio Metadata", args: ["test.wma", 524288] }
209
+ ]
210
+ },
211
+ {
212
+ name: "Extract Audio Metadata: WMA ASF Content Description",
213
+ input: WMA_HEX,
214
+ expectedMatch: /ASF Content Description.*title<\/td><td>Galway<\/td>.*author<\/td><td>Kevin MacLeod<\/td>/s,
215
+ recipeConfig: [
216
+ { op: "From Hex", args: ["None"] },
217
+ { op: "Extract Audio Metadata", args: ["test.wma", 524288] }
218
+ ]
219
+ },
220
+ {
221
+ name: "Extract Audio Metadata: WMA ASF Extended Content (encoding settings)",
222
+ input: WMA_HEX,
223
+ expectedMatch: /ASF Extended Content.*WM\/EncodingSettings<\/td><td>Lavf56\.40\.101<\/td>/s,
224
+ recipeConfig: [
225
+ { op: "From Hex", args: ["None"] },
226
+ { op: "Extract Audio Metadata", args: ["test.wma", 524288] }
227
+ ]
228
+ },
229
+ {
230
+ name: "Extract Audio Metadata: WMA detections",
231
+ input: WMA_HEX,
232
+ expectedMatch: /Metadata systems<\/td><td>asf_header, asf_content_desc, asf_ext_content_desc<\/td>/,
233
+ recipeConfig: [
234
+ { op: "From Hex", args: ["None"] },
235
+ { op: "Extract Audio Metadata", args: ["test.wma", 524288] }
236
+ ]
237
+ },
238
+
239
+ // ---- M4A ----
240
+ {
241
+ name: "Extract Audio Metadata: M4A container, MIME and brand",
242
+ input: M4A_HEX,
243
+ expectedMatch: /Container<\/td><td>m4a<\/td>.*MIME<\/td><td>audio\/mp4<\/td>.*Brand<\/td><td>M4A <\/td>/s,
244
+ recipeConfig: [
245
+ { op: "From Hex", args: ["None"] },
246
+ { op: "Extract Audio Metadata", args: ["test.m4a", 524288] }
247
+ ]
248
+ },
249
+ {
250
+ name: "Extract Audio Metadata: M4A top-level atoms (ftyp, mdat)",
251
+ input: M4A_HEX,
252
+ expectedMatch: /MP4 Top-Level Atoms.*ftyp<\/td>.*mdat<\/td>/s,
253
+ recipeConfig: [
254
+ { op: "From Hex", args: ["None"] },
255
+ { op: "Extract Audio Metadata", args: ["test.m4a", 524288] }
256
+ ]
257
+ },
258
+
259
+ // ---- AIFF ----
260
+ {
261
+ name: "Extract Audio Metadata: AIFF container, MIME and brand",
262
+ input: AIFF_HEX,
263
+ expectedMatch: /Container<\/td><td>aiff<\/td>.*MIME<\/td><td>audio\/aiff<\/td>.*Brand<\/td><td>AIFF<\/td>/s,
264
+ recipeConfig: [
265
+ { op: "From Hex", args: ["None"] },
266
+ { op: "Extract Audio Metadata", args: ["test.aiff", 524288] }
267
+ ]
268
+ },
269
+ {
270
+ name: "Extract Audio Metadata: AIFF common tag (title from NAME chunk)",
271
+ input: AIFF_HEX,
272
+ expectedMatch: /Title<\/td><td>Galway<\/td>/,
273
+ recipeConfig: [
274
+ { op: "From Hex", args: ["None"] },
275
+ { op: "Extract Audio Metadata", args: ["test.aiff", 524288] }
276
+ ]
277
+ },
278
+ {
279
+ name: "Extract Audio Metadata: AIFF chunks (NAME)",
280
+ input: AIFF_HEX,
281
+ expectedMatch: /AIFF Chunks.*NAME<\/td><td>Galway<\/td>/s,
282
+ recipeConfig: [
283
+ { op: "From Hex", args: ["None"] },
284
+ { op: "Extract Audio Metadata", args: ["test.aiff", 524288] }
285
+ ]
286
+ },
287
+ ]);