cyberchef 9.37.2 → 9.37.3
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 +1 -1
- package/src/core/config/OperationConfig.json +76 -1
- package/src/core/lib/Extract.mjs +16 -11
- package/src/core/lib/Sort.mjs +105 -0
- package/src/core/operations/ExtractDates.mjs +7 -1
- package/src/core/operations/ExtractDomains.mjs +29 -5
- package/src/core/operations/ExtractEmailAddresses.mjs +29 -5
- package/src/core/operations/ExtractFilePaths.mjs +38 -14
- package/src/core/operations/ExtractIPAddresses.mjs +44 -27
- package/src/core/operations/ExtractMACAddresses.mjs +28 -6
- package/src/core/operations/ExtractURLs.mjs +28 -5
- package/src/core/operations/Sort.mjs +5 -105
- package/src/core/operations/Strings.mjs +36 -14
- package/src/core/operations/Unique.mjs +25 -5
- package/tests/node/tests/operations.mjs +3 -4
- package/tests/operations/tests/ExtractEmailAddresses.mjs +4 -4
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cyberchef",
|
|
3
|
-
"version": "9.37.
|
|
3
|
+
"version": "9.37.3",
|
|
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",
|
|
@@ -4946,7 +4946,17 @@
|
|
|
4946
4946
|
{
|
|
4947
4947
|
"name": "Display total",
|
|
4948
4948
|
"type": "boolean",
|
|
4949
|
-
"value":
|
|
4949
|
+
"value": false
|
|
4950
|
+
},
|
|
4951
|
+
{
|
|
4952
|
+
"name": "Sort",
|
|
4953
|
+
"type": "boolean",
|
|
4954
|
+
"value": false
|
|
4955
|
+
},
|
|
4956
|
+
{
|
|
4957
|
+
"name": "Unique",
|
|
4958
|
+
"type": "boolean",
|
|
4959
|
+
"value": false
|
|
4950
4960
|
}
|
|
4951
4961
|
]
|
|
4952
4962
|
},
|
|
@@ -4973,6 +4983,16 @@
|
|
|
4973
4983
|
"name": "Display total",
|
|
4974
4984
|
"type": "boolean",
|
|
4975
4985
|
"value": false
|
|
4986
|
+
},
|
|
4987
|
+
{
|
|
4988
|
+
"name": "Sort",
|
|
4989
|
+
"type": "boolean",
|
|
4990
|
+
"value": false
|
|
4991
|
+
},
|
|
4992
|
+
{
|
|
4993
|
+
"name": "Unique",
|
|
4994
|
+
"type": "boolean",
|
|
4995
|
+
"value": false
|
|
4976
4996
|
}
|
|
4977
4997
|
]
|
|
4978
4998
|
},
|
|
@@ -4999,6 +5019,16 @@
|
|
|
4999
5019
|
"name": "Display total",
|
|
5000
5020
|
"type": "boolean",
|
|
5001
5021
|
"value": false
|
|
5022
|
+
},
|
|
5023
|
+
{
|
|
5024
|
+
"name": "Sort",
|
|
5025
|
+
"type": "boolean",
|
|
5026
|
+
"value": false
|
|
5027
|
+
},
|
|
5028
|
+
{
|
|
5029
|
+
"name": "Unique",
|
|
5030
|
+
"type": "boolean",
|
|
5031
|
+
"value": false
|
|
5002
5032
|
}
|
|
5003
5033
|
]
|
|
5004
5034
|
},
|
|
@@ -5091,6 +5121,16 @@
|
|
|
5091
5121
|
"name": "Display total",
|
|
5092
5122
|
"type": "boolean",
|
|
5093
5123
|
"value": false
|
|
5124
|
+
},
|
|
5125
|
+
{
|
|
5126
|
+
"name": "Sort",
|
|
5127
|
+
"type": "boolean",
|
|
5128
|
+
"value": false
|
|
5129
|
+
},
|
|
5130
|
+
{
|
|
5131
|
+
"name": "Unique",
|
|
5132
|
+
"type": "boolean",
|
|
5133
|
+
"value": false
|
|
5094
5134
|
}
|
|
5095
5135
|
]
|
|
5096
5136
|
},
|
|
@@ -5174,6 +5214,16 @@
|
|
|
5174
5214
|
"name": "Display total",
|
|
5175
5215
|
"type": "boolean",
|
|
5176
5216
|
"value": false
|
|
5217
|
+
},
|
|
5218
|
+
{
|
|
5219
|
+
"name": "Sort",
|
|
5220
|
+
"type": "boolean",
|
|
5221
|
+
"value": false
|
|
5222
|
+
},
|
|
5223
|
+
{
|
|
5224
|
+
"name": "Unique",
|
|
5225
|
+
"type": "boolean",
|
|
5226
|
+
"value": false
|
|
5177
5227
|
}
|
|
5178
5228
|
]
|
|
5179
5229
|
},
|
|
@@ -5228,6 +5278,16 @@
|
|
|
5228
5278
|
"name": "Display total",
|
|
5229
5279
|
"type": "boolean",
|
|
5230
5280
|
"value": false
|
|
5281
|
+
},
|
|
5282
|
+
{
|
|
5283
|
+
"name": "Sort",
|
|
5284
|
+
"type": "boolean",
|
|
5285
|
+
"value": false
|
|
5286
|
+
},
|
|
5287
|
+
{
|
|
5288
|
+
"name": "Unique",
|
|
5289
|
+
"type": "boolean",
|
|
5290
|
+
"value": false
|
|
5231
5291
|
}
|
|
5232
5292
|
]
|
|
5233
5293
|
},
|
|
@@ -12712,6 +12772,16 @@
|
|
|
12712
12772
|
"name": "Display total",
|
|
12713
12773
|
"type": "boolean",
|
|
12714
12774
|
"value": false
|
|
12775
|
+
},
|
|
12776
|
+
{
|
|
12777
|
+
"name": "Sort",
|
|
12778
|
+
"type": "boolean",
|
|
12779
|
+
"value": false
|
|
12780
|
+
},
|
|
12781
|
+
{
|
|
12782
|
+
"name": "Unique",
|
|
12783
|
+
"type": "boolean",
|
|
12784
|
+
"value": false
|
|
12715
12785
|
}
|
|
12716
12786
|
]
|
|
12717
12787
|
},
|
|
@@ -16039,6 +16109,11 @@
|
|
|
16039
16109
|
"Colon",
|
|
16040
16110
|
"Nothing (separate chars)"
|
|
16041
16111
|
]
|
|
16112
|
+
},
|
|
16113
|
+
{
|
|
16114
|
+
"name": "Display count",
|
|
16115
|
+
"type": "boolean",
|
|
16116
|
+
"value": false
|
|
16042
16117
|
}
|
|
16043
16118
|
]
|
|
16044
16119
|
},
|
package/src/core/lib/Extract.mjs
CHANGED
|
@@ -12,15 +12,15 @@
|
|
|
12
12
|
*
|
|
13
13
|
* @param {string} input
|
|
14
14
|
* @param {RegExp} searchRegex
|
|
15
|
-
* @param {RegExp} removeRegex - A regular expression defining results to remove from the
|
|
15
|
+
* @param {RegExp} [removeRegex=null] - A regular expression defining results to remove from the
|
|
16
16
|
* final list
|
|
17
|
-
* @param {
|
|
17
|
+
* @param {Function} [sortBy=null] - The sorting comparison function to apply
|
|
18
|
+
* @param {boolean} [unique=false] - Whether to unique the results
|
|
18
19
|
* @returns {string}
|
|
19
20
|
*/
|
|
20
|
-
export function search
|
|
21
|
-
let
|
|
22
|
-
|
|
23
|
-
match;
|
|
21
|
+
export function search(input, searchRegex, removeRegex=null, sortBy=null, unique=false) {
|
|
22
|
+
let results = [];
|
|
23
|
+
let match;
|
|
24
24
|
|
|
25
25
|
while ((match = searchRegex.exec(input))) {
|
|
26
26
|
// Moves pointer when an empty string is matched (prevents infinite loop)
|
|
@@ -30,14 +30,19 @@ export function search (input, searchRegex, removeRegex, includeTotal) {
|
|
|
30
30
|
|
|
31
31
|
if (removeRegex && removeRegex.test(match[0]))
|
|
32
32
|
continue;
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
|
|
34
|
+
results.push(match[0]);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if (sortBy) {
|
|
38
|
+
results = results.sort(sortBy);
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
if (
|
|
38
|
-
|
|
41
|
+
if (unique) {
|
|
42
|
+
results = results.unique();
|
|
43
|
+
}
|
|
39
44
|
|
|
40
|
-
return
|
|
45
|
+
return results;
|
|
41
46
|
}
|
|
42
47
|
|
|
43
48
|
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sorting functions
|
|
3
|
+
*
|
|
4
|
+
* @author n1474335 [n1474335@gmail.com]
|
|
5
|
+
* @copyright Crown Copyright 2022
|
|
6
|
+
* @license Apache-2.0
|
|
7
|
+
*
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Comparison operation for sorting of strings ignoring case.
|
|
12
|
+
*
|
|
13
|
+
* @param {string} a
|
|
14
|
+
* @param {string} b
|
|
15
|
+
* @returns {number}
|
|
16
|
+
*/
|
|
17
|
+
export function caseInsensitiveSort(a, b) {
|
|
18
|
+
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Comparison operation for sorting of IPv4 addresses.
|
|
24
|
+
*
|
|
25
|
+
* @param {string} a
|
|
26
|
+
* @param {string} b
|
|
27
|
+
* @returns {number}
|
|
28
|
+
*/
|
|
29
|
+
export function ipSort(a, b) {
|
|
30
|
+
let a_ = a.split("."),
|
|
31
|
+
b_ = b.split(".");
|
|
32
|
+
|
|
33
|
+
a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1;
|
|
34
|
+
b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1;
|
|
35
|
+
|
|
36
|
+
if (isNaN(a_) && !isNaN(b_)) return 1;
|
|
37
|
+
if (!isNaN(a_) && isNaN(b_)) return -1;
|
|
38
|
+
if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b);
|
|
39
|
+
|
|
40
|
+
return a_ - b_;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Comparison operation for sorting of numeric values.
|
|
45
|
+
*
|
|
46
|
+
* @author Chris van Marle
|
|
47
|
+
* @param {string} a
|
|
48
|
+
* @param {string} b
|
|
49
|
+
* @returns {number}
|
|
50
|
+
*/
|
|
51
|
+
export function numericSort(a, b) {
|
|
52
|
+
const a_ = a.split(/([^\d]+)/),
|
|
53
|
+
b_ = b.split(/([^\d]+)/);
|
|
54
|
+
|
|
55
|
+
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
|
56
|
+
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
|
57
|
+
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
|
58
|
+
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
|
59
|
+
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
|
60
|
+
if (ret !== 0) return ret;
|
|
61
|
+
}
|
|
62
|
+
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
|
63
|
+
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return a.localeCompare(b);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Comparison operation for sorting of hexadecimal values.
|
|
72
|
+
*
|
|
73
|
+
* @author Chris van Marle
|
|
74
|
+
* @param {string} a
|
|
75
|
+
* @param {string} b
|
|
76
|
+
* @returns {number}
|
|
77
|
+
*/
|
|
78
|
+
export function hexadecimalSort(a, b) {
|
|
79
|
+
let a_ = a.split(/([^\da-f]+)/i),
|
|
80
|
+
b_ = b.split(/([^\da-f]+)/i);
|
|
81
|
+
|
|
82
|
+
a_ = a_.map(v => {
|
|
83
|
+
const t = parseInt(v, 16);
|
|
84
|
+
return isNaN(t) ? v : t;
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
b_ = b_.map(v => {
|
|
88
|
+
const t = parseInt(v, 16);
|
|
89
|
+
return isNaN(t) ? v : t;
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
|
93
|
+
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
|
94
|
+
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
|
95
|
+
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
|
96
|
+
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
|
97
|
+
if (ret !== 0) return ret;
|
|
98
|
+
}
|
|
99
|
+
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
|
100
|
+
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
return a.localeCompare(b);
|
|
105
|
+
}
|
|
@@ -44,7 +44,13 @@ class ExtractDates extends Operation {
|
|
|
44
44
|
date3 = "(?:0[1-9]|1[012])[- /.](?:0[1-9]|[12][0-9]|3[01])[- /.](?:19|20)\\d\\d", // mm/dd/yyyy
|
|
45
45
|
regex = new RegExp(date1 + "|" + date2 + "|" + date3, "ig");
|
|
46
46
|
|
|
47
|
-
|
|
47
|
+
const results = search(input, regex);
|
|
48
|
+
|
|
49
|
+
if (displayTotal) {
|
|
50
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
51
|
+
} else {
|
|
52
|
+
return results.join("\n");
|
|
53
|
+
}
|
|
48
54
|
}
|
|
49
55
|
|
|
50
56
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search, DOMAIN_REGEX } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract domains operation
|
|
@@ -25,9 +26,19 @@ class ExtractDomains extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,8 +49,21 @@ class ExtractDomains extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
42
|
-
|
|
52
|
+
const [displayTotal, sort, unique] = args;
|
|
53
|
+
|
|
54
|
+
const results = search(
|
|
55
|
+
input,
|
|
56
|
+
DOMAIN_REGEX,
|
|
57
|
+
null,
|
|
58
|
+
sort ? caseInsensitiveSort : null,
|
|
59
|
+
unique
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
if (displayTotal) {
|
|
63
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
64
|
+
} else {
|
|
65
|
+
return results.join("\n");
|
|
66
|
+
}
|
|
43
67
|
}
|
|
44
68
|
|
|
45
69
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract email addresses operation
|
|
@@ -25,9 +26,19 @@ class ExtractEmailAddresses extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,10 +49,23 @@ class ExtractEmailAddresses extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
52
|
+
const [displayTotal, sort, unique] = args,
|
|
42
53
|
// email regex from: https://www.regextester.com/98066
|
|
43
54
|
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFFa-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}\])/ig;
|
|
44
|
-
|
|
55
|
+
|
|
56
|
+
const results = search(
|
|
57
|
+
input,
|
|
58
|
+
regex,
|
|
59
|
+
null,
|
|
60
|
+
sort ? caseInsensitiveSort : null,
|
|
61
|
+
unique
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
if (displayTotal) {
|
|
65
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
66
|
+
} else {
|
|
67
|
+
return results.join("\n");
|
|
68
|
+
}
|
|
45
69
|
}
|
|
46
70
|
|
|
47
71
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract file paths operation
|
|
@@ -25,19 +26,29 @@ class ExtractFilePaths extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Windows",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: true
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
name: "UNIX",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: true
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
name: "Display total",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
name: "Sort",
|
|
45
|
+
type: "boolean",
|
|
46
|
+
value: false
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "Unique",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
value: false
|
|
41
52
|
}
|
|
42
53
|
];
|
|
43
54
|
}
|
|
@@ -48,7 +59,7 @@ class ExtractFilePaths extends Operation {
|
|
|
48
59
|
* @returns {string}
|
|
49
60
|
*/
|
|
50
61
|
run(input, args) {
|
|
51
|
-
const [includeWinPath, includeUnixPath, displayTotal] = args,
|
|
62
|
+
const [includeWinPath, includeUnixPath, displayTotal, sort, unique] = args,
|
|
52
63
|
winDrive = "[A-Z]:\\\\",
|
|
53
64
|
winName = "[A-Z\\d][A-Z\\d\\- '_\\(\\)~]{0,61}",
|
|
54
65
|
winExt = "[A-Z\\d]{1,6}",
|
|
@@ -65,12 +76,25 @@ class ExtractFilePaths extends Operation {
|
|
|
65
76
|
filePaths = unixPath;
|
|
66
77
|
}
|
|
67
78
|
|
|
68
|
-
if (filePaths) {
|
|
69
|
-
const regex = new RegExp(filePaths, "ig");
|
|
70
|
-
return search(input, regex, null, displayTotal);
|
|
71
|
-
} else {
|
|
79
|
+
if (!filePaths) {
|
|
72
80
|
return "";
|
|
73
81
|
}
|
|
82
|
+
|
|
83
|
+
const regex = new RegExp(filePaths, "ig");
|
|
84
|
+
const results = search(
|
|
85
|
+
input,
|
|
86
|
+
regex,
|
|
87
|
+
null,
|
|
88
|
+
sort ? caseInsensitiveSort : null,
|
|
89
|
+
unique
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
if (displayTotal) {
|
|
93
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
94
|
+
} else {
|
|
95
|
+
return results.join("\n");
|
|
96
|
+
}
|
|
97
|
+
|
|
74
98
|
}
|
|
75
99
|
|
|
76
100
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { ipSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract IP addresses operation
|
|
@@ -25,24 +26,34 @@ class ExtractIPAddresses extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "IPv4",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: true
|
|
31
32
|
},
|
|
32
33
|
{
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
34
|
+
name: "IPv6",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
36
37
|
},
|
|
37
38
|
{
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
name: "Remove local IPv4 addresses",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
41
42
|
},
|
|
42
43
|
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
name: "Display total",
|
|
45
|
+
type: "boolean",
|
|
46
|
+
value: false
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: "Sort",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
value: false
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Unique",
|
|
55
|
+
type: "boolean",
|
|
56
|
+
value: false
|
|
46
57
|
}
|
|
47
58
|
];
|
|
48
59
|
}
|
|
@@ -53,7 +64,7 @@ class ExtractIPAddresses extends Operation {
|
|
|
53
64
|
* @returns {string}
|
|
54
65
|
*/
|
|
55
66
|
run(input, args) {
|
|
56
|
-
const [includeIpv4, includeIpv6, removeLocal, displayTotal] = args,
|
|
67
|
+
const [includeIpv4, includeIpv6, removeLocal, displayTotal, sort, unique] = args,
|
|
57
68
|
ipv4 = "(?:(?:\\d|[01]?\\d\\d|2[0-4]\\d|25[0-5])\\.){3}(?:25[0-5]|2[0-4]\\d|[01]?\\d\\d|\\d)(?:\\/\\d{1,2})?",
|
|
58
69
|
ipv6 = "((?=.*::)(?!.*::.+::)(::)?([\\dA-F]{1,4}:(:|\\b)|){5}|([\\dA-F]{1,4}:){6})((([\\dA-F]{1,4}((?!\\3)::|:\\b|(?![\\dA-F])))|(?!\\2\\3)){2}|(((2[0-4]|1\\d|[1-9])?\\d|25[0-5])\\.?\\b){4})";
|
|
59
70
|
let ips = "";
|
|
@@ -66,23 +77,29 @@ class ExtractIPAddresses extends Operation {
|
|
|
66
77
|
ips = ipv6;
|
|
67
78
|
}
|
|
68
79
|
|
|
69
|
-
if (ips)
|
|
70
|
-
const regex = new RegExp(ips, "ig");
|
|
80
|
+
if (!ips) return "";
|
|
71
81
|
|
|
72
|
-
|
|
73
|
-
const ten = "10\\..+",
|
|
74
|
-
oneninetwo = "192\\.168\\..+",
|
|
75
|
-
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
|
76
|
-
onetwoseven = "127\\..+",
|
|
77
|
-
removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo +
|
|
78
|
-
"|" + oneseventwo + "|" + onetwoseven + ")");
|
|
82
|
+
const regex = new RegExp(ips, "ig");
|
|
79
83
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
+
const ten = "10\\..+",
|
|
85
|
+
oneninetwo = "192\\.168\\..+",
|
|
86
|
+
oneseventwo = "172\\.(?:1[6-9]|2\\d|3[01])\\..+",
|
|
87
|
+
onetwoseven = "127\\..+",
|
|
88
|
+
removeRegex = new RegExp("^(?:" + ten + "|" + oneninetwo +
|
|
89
|
+
"|" + oneseventwo + "|" + onetwoseven + ")");
|
|
90
|
+
|
|
91
|
+
const results = search(
|
|
92
|
+
input,
|
|
93
|
+
regex,
|
|
94
|
+
removeLocal ? removeRegex : null,
|
|
95
|
+
sort ? ipSort : null,
|
|
96
|
+
unique
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
if (displayTotal) {
|
|
100
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
84
101
|
} else {
|
|
85
|
-
return "";
|
|
102
|
+
return results.join("\n");
|
|
86
103
|
}
|
|
87
104
|
}
|
|
88
105
|
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search } from "../lib/Extract.mjs";
|
|
9
|
+
import { hexadecimalSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract MAC addresses operation
|
|
@@ -25,9 +26,19 @@ class ExtractMACAddresses extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,10 +49,21 @@ class ExtractMACAddresses extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
42
|
-
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig
|
|
52
|
+
const [displayTotal, sort, unique] = args,
|
|
53
|
+
regex = /[A-F\d]{2}(?:[:-][A-F\d]{2}){5}/ig,
|
|
54
|
+
results = search(
|
|
55
|
+
input,
|
|
56
|
+
regex,
|
|
57
|
+
null,
|
|
58
|
+
sort ? hexadecimalSort : null,
|
|
59
|
+
unique
|
|
60
|
+
);
|
|
43
61
|
|
|
44
|
-
|
|
62
|
+
if (displayTotal) {
|
|
63
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
64
|
+
} else {
|
|
65
|
+
return results.join("\n");
|
|
66
|
+
}
|
|
45
67
|
}
|
|
46
68
|
|
|
47
69
|
}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import { search, URL_REGEX } from "../lib/Extract.mjs";
|
|
9
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* Extract URLs operation
|
|
@@ -25,9 +26,19 @@ class ExtractURLs extends Operation {
|
|
|
25
26
|
this.outputType = "string";
|
|
26
27
|
this.args = [
|
|
27
28
|
{
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
name: "Display total",
|
|
30
|
+
type: "boolean",
|
|
31
|
+
value: false
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Sort",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
37
|
+
},
|
|
38
|
+
{
|
|
39
|
+
name: "Unique",
|
|
40
|
+
type: "boolean",
|
|
41
|
+
value: false
|
|
31
42
|
}
|
|
32
43
|
];
|
|
33
44
|
}
|
|
@@ -38,8 +49,20 @@ class ExtractURLs extends Operation {
|
|
|
38
49
|
* @returns {string}
|
|
39
50
|
*/
|
|
40
51
|
run(input, args) {
|
|
41
|
-
const displayTotal = args
|
|
42
|
-
|
|
52
|
+
const [displayTotal, sort, unique] = args;
|
|
53
|
+
const results = search(
|
|
54
|
+
input,
|
|
55
|
+
URL_REGEX,
|
|
56
|
+
null,
|
|
57
|
+
sort ? caseInsensitiveSort : null,
|
|
58
|
+
unique
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
if (displayTotal) {
|
|
62
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
63
|
+
} else {
|
|
64
|
+
return results.join("\n");
|
|
65
|
+
}
|
|
43
66
|
}
|
|
44
67
|
|
|
45
68
|
}
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import Utils from "../Utils.mjs";
|
|
9
9
|
import {INPUT_DELIM_OPTIONS} from "../lib/Delim.mjs";
|
|
10
|
+
import {caseInsensitiveSort, ipSort, numericSort, hexadecimalSort} from "../lib/Sort.mjs";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Sort operation
|
|
@@ -57,120 +58,19 @@ class Sort extends Operation {
|
|
|
57
58
|
if (order === "Alphabetical (case sensitive)") {
|
|
58
59
|
sorted = sorted.sort();
|
|
59
60
|
} else if (order === "Alphabetical (case insensitive)") {
|
|
60
|
-
sorted = sorted.sort(
|
|
61
|
+
sorted = sorted.sort(caseInsensitiveSort);
|
|
61
62
|
} else if (order === "IP address") {
|
|
62
|
-
sorted = sorted.sort(
|
|
63
|
+
sorted = sorted.sort(ipSort);
|
|
63
64
|
} else if (order === "Numeric") {
|
|
64
|
-
sorted = sorted.sort(
|
|
65
|
+
sorted = sorted.sort(numericSort);
|
|
65
66
|
} else if (order === "Numeric (hexadecimal)") {
|
|
66
|
-
sorted = sorted.sort(
|
|
67
|
+
sorted = sorted.sort(hexadecimalSort);
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
if (sortReverse) sorted.reverse();
|
|
70
71
|
return sorted.join(delim);
|
|
71
72
|
}
|
|
72
73
|
|
|
73
|
-
/**
|
|
74
|
-
* Comparison operation for sorting of strings ignoring case.
|
|
75
|
-
*
|
|
76
|
-
* @private
|
|
77
|
-
* @param {string} a
|
|
78
|
-
* @param {string} b
|
|
79
|
-
* @returns {number}
|
|
80
|
-
*/
|
|
81
|
-
static _caseInsensitiveSort(a, b) {
|
|
82
|
-
return a.toLowerCase().localeCompare(b.toLowerCase());
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Comparison operation for sorting of IPv4 addresses.
|
|
88
|
-
*
|
|
89
|
-
* @private
|
|
90
|
-
* @param {string} a
|
|
91
|
-
* @param {string} b
|
|
92
|
-
* @returns {number}
|
|
93
|
-
*/
|
|
94
|
-
static _ipSort(a, b) {
|
|
95
|
-
let a_ = a.split("."),
|
|
96
|
-
b_ = b.split(".");
|
|
97
|
-
|
|
98
|
-
a_ = a_[0] * 0x1000000 + a_[1] * 0x10000 + a_[2] * 0x100 + a_[3] * 1;
|
|
99
|
-
b_ = b_[0] * 0x1000000 + b_[1] * 0x10000 + b_[2] * 0x100 + b_[3] * 1;
|
|
100
|
-
|
|
101
|
-
if (isNaN(a_) && !isNaN(b_)) return 1;
|
|
102
|
-
if (!isNaN(a_) && isNaN(b_)) return -1;
|
|
103
|
-
if (isNaN(a_) && isNaN(b_)) return a.localeCompare(b);
|
|
104
|
-
|
|
105
|
-
return a_ - b_;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
/**
|
|
109
|
-
* Comparison operation for sorting of numeric values.
|
|
110
|
-
*
|
|
111
|
-
* @author Chris van Marle
|
|
112
|
-
* @private
|
|
113
|
-
* @param {string} a
|
|
114
|
-
* @param {string} b
|
|
115
|
-
* @returns {number}
|
|
116
|
-
*/
|
|
117
|
-
static _numericSort(a, b) {
|
|
118
|
-
const a_ = a.split(/([^\d]+)/),
|
|
119
|
-
b_ = b.split(/([^\d]+)/);
|
|
120
|
-
|
|
121
|
-
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
|
122
|
-
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
|
123
|
-
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
|
124
|
-
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
|
125
|
-
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
|
126
|
-
if (ret !== 0) return ret;
|
|
127
|
-
}
|
|
128
|
-
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
|
129
|
-
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return a.localeCompare(b);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Comparison operation for sorting of hexadecimal values.
|
|
138
|
-
*
|
|
139
|
-
* @author Chris van Marle
|
|
140
|
-
* @private
|
|
141
|
-
* @param {string} a
|
|
142
|
-
* @param {string} b
|
|
143
|
-
* @returns {number}
|
|
144
|
-
*/
|
|
145
|
-
static _hexadecimalSort(a, b) {
|
|
146
|
-
let a_ = a.split(/([^\da-f]+)/i),
|
|
147
|
-
b_ = b.split(/([^\da-f]+)/i);
|
|
148
|
-
|
|
149
|
-
a_ = a_.map(v => {
|
|
150
|
-
const t = parseInt(v, 16);
|
|
151
|
-
return isNaN(t) ? v : t;
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
b_ = b_.map(v => {
|
|
155
|
-
const t = parseInt(v, 16);
|
|
156
|
-
return isNaN(t) ? v : t;
|
|
157
|
-
});
|
|
158
|
-
|
|
159
|
-
for (let i = 0; i < a_.length && i < b.length; ++i) {
|
|
160
|
-
if (isNaN(a_[i]) && !isNaN(b_[i])) return 1; // Numbers after non-numbers
|
|
161
|
-
if (!isNaN(a_[i]) && isNaN(b_[i])) return -1;
|
|
162
|
-
if (isNaN(a_[i]) && isNaN(b_[i])) {
|
|
163
|
-
const ret = a_[i].localeCompare(b_[i]); // Compare strings
|
|
164
|
-
if (ret !== 0) return ret;
|
|
165
|
-
}
|
|
166
|
-
if (!isNaN(a_[i]) && !isNaN(b_[i])) { // Compare numbers
|
|
167
|
-
if (a_[i] - b_[i] !== 0) return a_[i] - b_[i];
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
return a.localeCompare(b);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
74
|
}
|
|
175
75
|
|
|
176
76
|
export default Sort;
|
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
import Operation from "../Operation.mjs";
|
|
8
8
|
import XRegExp from "xregexp";
|
|
9
9
|
import { search } from "../lib/Extract.mjs";
|
|
10
|
+
import { caseInsensitiveSort } from "../lib/Sort.mjs";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* Strings operation
|
|
@@ -27,27 +28,37 @@ class Strings extends Operation {
|
|
|
27
28
|
this.outputType = "string";
|
|
28
29
|
this.args = [
|
|
29
30
|
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
name: "Encoding",
|
|
32
|
+
type: "option",
|
|
33
|
+
value: ["Single byte", "16-bit littleendian", "16-bit bigendian", "All"]
|
|
33
34
|
},
|
|
34
35
|
{
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
name: "Minimum length",
|
|
37
|
+
type: "number",
|
|
38
|
+
value: 4
|
|
38
39
|
},
|
|
39
40
|
{
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
41
|
+
name: "Match",
|
|
42
|
+
type: "option",
|
|
43
|
+
value: [
|
|
43
44
|
"[ASCII]", "Alphanumeric + punctuation (A)", "All printable chars (A)", "Null-terminated strings (A)",
|
|
44
45
|
"[Unicode]", "Alphanumeric + punctuation (U)", "All printable chars (U)", "Null-terminated strings (U)"
|
|
45
46
|
]
|
|
46
47
|
},
|
|
47
48
|
{
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
49
|
+
name: "Display total",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
value: false
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
name: "Sort",
|
|
55
|
+
type: "boolean",
|
|
56
|
+
value: false
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "Unique",
|
|
60
|
+
type: "boolean",
|
|
61
|
+
value: false
|
|
51
62
|
}
|
|
52
63
|
];
|
|
53
64
|
}
|
|
@@ -58,7 +69,7 @@ class Strings extends Operation {
|
|
|
58
69
|
* @returns {string}
|
|
59
70
|
*/
|
|
60
71
|
run(input, args) {
|
|
61
|
-
const [encoding, minLen, matchType, displayTotal] = args,
|
|
72
|
+
const [encoding, minLen, matchType, displayTotal, sort, unique] = args,
|
|
62
73
|
alphanumeric = "A-Z\\d",
|
|
63
74
|
punctuation = "/\\-:.,_$%'\"()<>= !\\[\\]{}@",
|
|
64
75
|
printable = "\x20-\x7e",
|
|
@@ -108,8 +119,19 @@ class Strings extends Operation {
|
|
|
108
119
|
}
|
|
109
120
|
|
|
110
121
|
const regex = new XRegExp(strings, "ig");
|
|
122
|
+
const results = search(
|
|
123
|
+
input,
|
|
124
|
+
regex,
|
|
125
|
+
null,
|
|
126
|
+
sort ? caseInsensitiveSort : null,
|
|
127
|
+
unique
|
|
128
|
+
);
|
|
111
129
|
|
|
112
|
-
|
|
130
|
+
if (displayTotal) {
|
|
131
|
+
return `Total found: ${results.length}\n\n${results.join("\n")}`;
|
|
132
|
+
} else {
|
|
133
|
+
return results.join("\n");
|
|
134
|
+
}
|
|
113
135
|
}
|
|
114
136
|
|
|
115
137
|
}
|
|
@@ -26,9 +26,14 @@ class Unique extends Operation {
|
|
|
26
26
|
this.outputType = "string";
|
|
27
27
|
this.args = [
|
|
28
28
|
{
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
name: "Delimiter",
|
|
30
|
+
type: "option",
|
|
31
|
+
value: INPUT_DELIM_OPTIONS
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
name: "Display count",
|
|
35
|
+
type: "boolean",
|
|
36
|
+
value: false
|
|
32
37
|
}
|
|
33
38
|
];
|
|
34
39
|
}
|
|
@@ -39,8 +44,23 @@ class Unique extends Operation {
|
|
|
39
44
|
* @returns {string}
|
|
40
45
|
*/
|
|
41
46
|
run(input, args) {
|
|
42
|
-
const delim = Utils.charRep(args[0])
|
|
43
|
-
|
|
47
|
+
const delim = Utils.charRep(args[0]),
|
|
48
|
+
count = args[1];
|
|
49
|
+
|
|
50
|
+
if (count) {
|
|
51
|
+
const valMap = input.split(delim).reduce((acc, curr) => {
|
|
52
|
+
if (Object.prototype.hasOwnProperty.call(acc, curr)) {
|
|
53
|
+
acc[curr]++;
|
|
54
|
+
} else {
|
|
55
|
+
acc[curr] = 1;
|
|
56
|
+
}
|
|
57
|
+
return acc;
|
|
58
|
+
}, {});
|
|
59
|
+
|
|
60
|
+
return Object.keys(valMap).map(val => `${valMap[val]} ${val}`).join(delim);
|
|
61
|
+
} else {
|
|
62
|
+
return input.split(delim).unique().join(delim);
|
|
63
|
+
}
|
|
44
64
|
}
|
|
45
65
|
|
|
46
66
|
}
|
|
@@ -471,7 +471,7 @@ color: white;
|
|
|
471
471
|
}),
|
|
472
472
|
|
|
473
473
|
it("Extract dates", () => {
|
|
474
|
-
assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992
|
|
474
|
+
assert.strictEqual(chef.extractDates("Don't Look a Gift Horse In The Mouth 01/02/1992").toString(), "01/02/1992");
|
|
475
475
|
}),
|
|
476
476
|
|
|
477
477
|
it("Filter", () => {
|
|
@@ -859,7 +859,7 @@ pCGTErs=
|
|
|
859
859
|
}),
|
|
860
860
|
|
|
861
861
|
it("SQL Beautify", () => {
|
|
862
|
-
const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F
|
|
862
|
+
const result = chef.SQLBeautify(`SELECT MONTH, ID, RAIN_I, TEMP_F
|
|
863
863
|
FROM STATS;`);
|
|
864
864
|
const expected = `SELECT MONTH,
|
|
865
865
|
ID,
|
|
@@ -879,8 +879,7 @@ FROM STATS;`;
|
|
|
879
879
|
const result = chef.strings("smothering ampersand abreast", {displayTotal: true});
|
|
880
880
|
const expected = `Total found: 1
|
|
881
881
|
|
|
882
|
-
smothering ampersand abreast
|
|
883
|
-
`;
|
|
882
|
+
smothering ampersand abreast`;
|
|
884
883
|
assert.strictEqual(result.toString(), expected);
|
|
885
884
|
}),
|
|
886
885
|
|
|
@@ -11,7 +11,7 @@ TestRegister.addTests([
|
|
|
11
11
|
{
|
|
12
12
|
name: "Extract email address",
|
|
13
13
|
input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
|
|
14
|
-
expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com
|
|
14
|
+
expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com",
|
|
15
15
|
recipeConfig: [
|
|
16
16
|
{
|
|
17
17
|
"op": "Extract email addresses",
|
|
@@ -22,7 +22,7 @@ TestRegister.addTests([
|
|
|
22
22
|
{
|
|
23
23
|
name: "Extract email address - Display total",
|
|
24
24
|
input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
|
|
25
|
-
expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com
|
|
25
|
+
expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com",
|
|
26
26
|
recipeConfig: [
|
|
27
27
|
{
|
|
28
28
|
"op": "Extract email addresses",
|
|
@@ -33,7 +33,7 @@ TestRegister.addTests([
|
|
|
33
33
|
{
|
|
34
34
|
name: "Extract email address (Internationalized)",
|
|
35
35
|
input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
|
|
36
|
-
expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com
|
|
36
|
+
expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
|
|
37
37
|
recipeConfig: [
|
|
38
38
|
{
|
|
39
39
|
"op": "Extract email addresses",
|
|
@@ -44,7 +44,7 @@ TestRegister.addTests([
|
|
|
44
44
|
{
|
|
45
45
|
name: "Extract email address - Display total (Internationalized)",
|
|
46
46
|
input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
|
|
47
|
-
expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com
|
|
47
|
+
expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
|
|
48
48
|
recipeConfig: [
|
|
49
49
|
{
|
|
50
50
|
"op": "Extract email addresses",
|