@procedures/client 0.27.8 → 0.28.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"regex-guard.js","sourceRoot":"","sources":["../../../src/procedures/collection/regex-guard.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "https://json.schemastore.org/package",
3
3
  "name": "@procedures/client",
4
- "version": "0.27.8",
4
+ "version": "0.28.0",
5
5
  "description": "Procedures as data for TypeScript: define typed procedures once and call them in process, over HTTP, WebSocket, the CLI or MCP. Streaming, middleware, retries, caching and a JSON program format.",
6
6
  "keywords": [
7
7
  "rpc",
@@ -46,6 +46,8 @@ export {
46
46
  versionConflictsOf,
47
47
  } from "./precondition.js";
48
48
  export type { CurrentItem, VersionConflict, VersionOf } from "./precondition.js";
49
+ // The guard of $regex has no imports either
50
+ import { exponentialRegex } from "./regex-guard.js";
49
51
 
50
52
  //
51
53
  // ═══ The types ═══
@@ -458,52 +460,6 @@ function withinDepth(depth: number, at: string, compilation: Compilation): boole
458
460
  return false;
459
461
  }
460
462
 
461
- /**
462
- * True when a pattern repeats a group that repeats without a bound, for example `(a+)+` or
463
- * `(a|b*)*`. Such a pattern can take an exponential time on a long text.
464
- */
465
- function repeatsRepetition(pattern: string): boolean {
466
- // For each open group: true when it holds a repetition without a bound
467
- const groups: boolean[] = [];
468
- let lastGroupRepeats = false;
469
- let inClass = false;
470
- for (let index = 0; index < pattern.length; index++) {
471
- const char = pattern[index]!;
472
- if (char === "\\") {
473
- index++;
474
- lastGroupRepeats = false;
475
- continue;
476
- }
477
- if (inClass) {
478
- if (char === "]") inClass = false;
479
- continue;
480
- }
481
- if (char === "[") {
482
- inClass = true;
483
- lastGroupRepeats = false;
484
- continue;
485
- }
486
- if (char === "(") {
487
- groups.push(false);
488
- lastGroupRepeats = false;
489
- continue;
490
- }
491
- if (char === ")") {
492
- lastGroupRepeats = groups.pop() ?? false;
493
- // A group that holds a repetition makes each group around it hold one too
494
- if (lastGroupRepeats && groups.length > 0) groups[groups.length - 1] = true;
495
- continue;
496
- }
497
- const unbounded = char === "*" || char === "+" || (char === "{" && /^\{\d*,\}/.test(pattern.slice(index)));
498
- if (unbounded) {
499
- if (lastGroupRepeats) return true;
500
- if (groups.length > 0) groups[groups.length - 1] = true;
501
- }
502
- if (char !== "?") lastGroupRepeats = false;
503
- }
504
- return false;
505
- }
506
-
507
463
  //
508
464
  // ═══ The compiler of a selector ═══
509
465
  //
@@ -666,8 +622,11 @@ function regexOf(pattern: unknown, flags: unknown, at: string, compilation: Comp
666
622
  problems.push(`${at}.$options has the flag ${refused.join(", ")}, and the query policy permits only "${limits.regexFlags}"`);
667
623
  return undefined;
668
624
  }
669
- if (repeatsRepetition(pattern)) {
670
- problems.push(`${at}.$regex repeats a group that repeats without a bound: such a pattern can take an exponential time`);
625
+ // The guard reads the pattern with its flags. (Before, it found only a repeated group with an
626
+ // unbounded repetition inside, not (a|aa)+ or (a{1,50}){1,50}: audit O56.)
627
+ const risk = exponentialRegex(pattern, typeof flags === "string" ? flags : "");
628
+ if (risk !== undefined) {
629
+ problems.push(`${at}.$regex ${risk}: such a pattern can take an exponential time`);
671
630
  return undefined;
672
631
  }
673
632
  try {
@@ -0,0 +1,333 @@
1
+ /**
2
+ * The guard of `$regex` against patterns that can take an exponential time in a backtracking
3
+ * engine such as V8. It reads the pattern, and it refuses a group that repeats when the group can
4
+ * match the same text in more than one way:
5
+ *
6
+ * - The group holds a repetition of variable length: `(a+)+`, `(a{2,3})+`, `(a?a?)+`.
7
+ * - The group holds alternatives that can start with the same character: `(a|a)*`, `(a|aa)+`.
8
+ *
9
+ * A group with a bounded repetition passes when the number of its ways to match is small, for
10
+ * example `(\d{1,3}\.){3}`. The guard does not find each polynomial pattern, for example `\s*\s*$`.
11
+ * A host keeps `maxRegexLength` small for callers that it does not trust.
12
+ */
13
+
14
+ /** A set of UTF-16 code units: the ranges, or each code unit outside them when `negated`. */
15
+ interface CharSet {
16
+ readonly ranges: ReadonlyArray<readonly [number, number]>;
17
+ readonly negated: boolean;
18
+ }
19
+
20
+ /** One part of a pattern. */
21
+ type RegexNode =
22
+ | { readonly kind: "atom"; readonly first: CharSet; readonly width: boolean }
23
+ | { readonly kind: "group"; readonly branches: RegexNode[][]; readonly width: boolean }
24
+ | { readonly kind: "repeat"; readonly node: RegexNode; readonly min: number; readonly max: number };
25
+
26
+ /** The most ways to match that a group with a bounded repetition can have. */
27
+ const MAX_WAYS = 1000;
28
+
29
+ const ANY: CharSet = { ranges: [], negated: true };
30
+ const DIGIT: Array<[number, number]> = [[0x30, 0x39]];
31
+ const WORD: Array<[number, number]> = [[0x30, 0x39], [0x41, 0x5a], [0x5f, 0x5f], [0x61, 0x7a]];
32
+ const SPACE: Array<[number, number]> = [
33
+ [0x09, 0x0d], [0x20, 0x20], [0xa0, 0xa0], [0x1680, 0x1680], [0x2000, 0x200a],
34
+ [0x2028, 0x2029], [0x202f, 0x202f], [0x205f, 0x205f], [0x3000, 0x3000], [0xfeff, 0xfeff],
35
+ ];
36
+ const CONTROL_ESCAPES: Record<string, number> = { t: 9, n: 10, v: 11, f: 12, r: 13, "0": 0 };
37
+
38
+ /** With the flag `i`, each ASCII letter of a range also gives the letter of the other case. */
39
+ function folded(ranges: ReadonlyArray<readonly [number, number]>, ignoreCase: boolean): Array<readonly [number, number]> {
40
+ const result: Array<readonly [number, number]> = [...ranges];
41
+ if (!ignoreCase) return result;
42
+ for (const [lo, hi] of ranges) {
43
+ for (const [from, to, shift] of [[0x41, 0x5a, 0x20], [0x61, 0x7a, -0x20]] as const) {
44
+ const start = Math.max(lo, from);
45
+ const end = Math.min(hi, to);
46
+ if (start <= end) result.push([start + shift, end + shift]);
47
+ }
48
+ }
49
+ return result;
50
+ }
51
+
52
+ /** True when each code unit of a range is in one of the ranges. */
53
+ function covered([lo, hi]: readonly [number, number], ranges: ReadonlyArray<readonly [number, number]>): boolean {
54
+ let next = lo;
55
+ for (const [from, to] of [...ranges].sort((a, b) => a[0] - b[0])) {
56
+ if (from > next) break;
57
+ next = Math.max(next, to + 1);
58
+ if (next > hi) return true;
59
+ }
60
+ return next > hi;
61
+ }
62
+
63
+ /** True when two sets can have the same code unit. */
64
+ function overlaps(a: CharSet, b: CharSet): boolean {
65
+ if (a.negated && b.negated) return true;
66
+ if (!a.negated && !b.negated) return a.ranges.some(([lo, hi]) => b.ranges.some(([from, to]) => lo <= to && from <= hi));
67
+ const [positive, negative] = a.negated ? [b, a] : [a, b];
68
+ return positive.ranges.some((range) => !covered(range, negative.ranges));
69
+ }
70
+
71
+ /** This function reads a pattern into parts. A construct that it does not know becomes an atom that can match each character. */
72
+ function parse(pattern: string, ignoreCase: boolean): RegexNode[][] {
73
+ let at = 0;
74
+ const set = (ranges: ReadonlyArray<readonly [number, number]>, negated = false): CharSet => ({ ranges: folded(ranges, ignoreCase), negated });
75
+ const unit = (code: number): CharSet => set([[code, code]]);
76
+
77
+ /** The code unit of an escape that names one character, after the backslash. */
78
+ const escapedCode = (): number => {
79
+ const char = pattern[at++] ?? "\\";
80
+ if (char in CONTROL_ESCAPES) return CONTROL_ESCAPES[char]!;
81
+ if (char === "x" && /^[0-9a-fA-F]{2}/.test(pattern.slice(at))) {
82
+ at += 2;
83
+ return Number.parseInt(pattern.slice(at - 2, at), 16);
84
+ }
85
+ if (char === "u") {
86
+ const braced = /^\{([0-9a-fA-F]+)\}/.exec(pattern.slice(at));
87
+ if (braced) {
88
+ at += braced[0].length;
89
+ const code = Number.parseInt(braced[1]!, 16);
90
+ return code > 0xffff ? 0xd800 + ((code - 0x10000) >> 10) : code;
91
+ }
92
+ if (/^[0-9a-fA-F]{4}/.test(pattern.slice(at))) {
93
+ at += 4;
94
+ return Number.parseInt(pattern.slice(at - 4, at), 16);
95
+ }
96
+ }
97
+ if (char === "c" && /^[a-zA-Z]/.test(pattern.slice(at))) return pattern.charCodeAt(at++) % 32;
98
+ return char.charCodeAt(0);
99
+ };
100
+
101
+ /** The set of a class escape (`\d`, `\W`), or undefined for another escape. The backslash is read. */
102
+ const classEscape = (): CharSet | undefined => {
103
+ const char = pattern[at];
104
+ const ranges = char === "d" || char === "D" ? DIGIT : char === "w" || char === "W" ? WORD : char === "s" || char === "S" ? SPACE : undefined;
105
+ if (ranges !== undefined) {
106
+ at++;
107
+ return set(ranges, char === "D" || char === "W" || char === "S");
108
+ }
109
+ if (char === "p" || char === "P") {
110
+ at++;
111
+ if (pattern[at] === "{") {
112
+ const end = pattern.indexOf("}", at);
113
+ at = end === -1 ? pattern.length : end + 1;
114
+ }
115
+ return ANY;
116
+ }
117
+ return undefined;
118
+ };
119
+
120
+ const parseClass = (): CharSet => {
121
+ const negated = pattern[at] === "^";
122
+ if (negated) at++;
123
+ const ranges: Array<[number, number]> = [];
124
+ let unknown = false;
125
+ const member = (): number | undefined => {
126
+ if (pattern[at] !== "\\") return pattern.charCodeAt(at++);
127
+ at++;
128
+ const escape = classEscape();
129
+ if (escape !== undefined) {
130
+ // A negated escape in a class, or a property: the set is not known here
131
+ if (escape.negated) unknown = true;
132
+ else ranges.push(...(escape.ranges as Array<[number, number]>));
133
+ return undefined;
134
+ }
135
+ if (pattern[at] === "b") {
136
+ at++;
137
+ return 8;
138
+ }
139
+ return escapedCode();
140
+ };
141
+ while (at < pattern.length && pattern[at] !== "]") {
142
+ const low = member();
143
+ if (low === undefined) continue;
144
+ if (pattern[at] === "-" && pattern[at + 1] !== "]" && at + 1 < pattern.length) {
145
+ at++;
146
+ const high = member();
147
+ if (high === undefined) {
148
+ ranges.push([low, low], [0x2d, 0x2d]);
149
+ continue;
150
+ }
151
+ ranges.push([Math.min(low, high), Math.max(low, high)]);
152
+ } else {
153
+ ranges.push([low, low]);
154
+ }
155
+ }
156
+ at++;
157
+ if (unknown) return ANY;
158
+ return set(ranges, negated);
159
+ };
160
+
161
+ const parseAtom = (): RegexNode => {
162
+ const char = pattern[at++]!;
163
+ if (char === "(") {
164
+ let width = true;
165
+ for (const [prefix, zeroWidth] of [["?:", false], ["?=", true], ["?!", true], ["?<=", true], ["?<!", true]] as const) {
166
+ if (pattern.startsWith(prefix, at)) {
167
+ at += prefix.length;
168
+ width = !zeroWidth;
169
+ break;
170
+ }
171
+ }
172
+ if (width && pattern.startsWith("?<", at)) {
173
+ const end = pattern.indexOf(">", at);
174
+ at = end === -1 ? pattern.length : end + 1;
175
+ } else if (width && pattern[at] === "?") {
176
+ // A modifier group, for example (?i:x)
177
+ const colon = pattern.indexOf(":", at);
178
+ at = colon === -1 ? pattern.length : colon + 1;
179
+ }
180
+ const branches = parseAlternatives();
181
+ if (pattern[at] === ")") at++;
182
+ return { kind: "group", branches, width };
183
+ }
184
+ if (char === "[") return { kind: "atom", first: parseClass(), width: true };
185
+ if (char === ".") return { kind: "atom", first: ANY, width: true };
186
+ if (char === "^" || char === "$") return { kind: "atom", first: ANY, width: false };
187
+ if (char === "\\") {
188
+ const escape = classEscape();
189
+ if (escape !== undefined) return { kind: "atom", first: escape, width: true };
190
+ const next = pattern[at];
191
+ if (next === "b" || next === "B") {
192
+ at++;
193
+ return { kind: "atom", first: ANY, width: false };
194
+ }
195
+ // A back reference matches a text that the guard does not know
196
+ if (next !== undefined && /[1-9]/.test(next)) {
197
+ while (/[0-9]/.test(pattern[at] ?? "")) at++;
198
+ return { kind: "atom", first: ANY, width: true };
199
+ }
200
+ if (next === "k" && pattern[at + 1] === "<") {
201
+ const end = pattern.indexOf(">", at);
202
+ at = end === -1 ? pattern.length : end + 1;
203
+ return { kind: "atom", first: ANY, width: true };
204
+ }
205
+ return { kind: "atom", first: unit(escapedCode()), width: true };
206
+ }
207
+ return { kind: "atom", first: unit(char.charCodeAt(0)), width: true };
208
+ };
209
+
210
+ /** The bounds of a quantifier at the position, or undefined. A lazy quantifier has the same bounds. */
211
+ const parseQuantifier = (): { min: number; max: number } | undefined => {
212
+ const char = pattern[at];
213
+ let bounds: { min: number; max: number } | undefined;
214
+ if (char === "*") bounds = { min: 0, max: Infinity };
215
+ else if (char === "+") bounds = { min: 1, max: Infinity };
216
+ else if (char === "?") bounds = { min: 0, max: 1 };
217
+ if (bounds !== undefined) {
218
+ at++;
219
+ } else if (char === "{") {
220
+ const counted = /^\{(\d+)(,(\d*))?\}/.exec(pattern.slice(at));
221
+ if (counted === null) return undefined;
222
+ at += counted[0].length;
223
+ const min = Number(counted[1]);
224
+ bounds = { min, max: counted[2] === undefined ? min : counted[3] === "" ? Infinity : Number(counted[3]) };
225
+ } else {
226
+ return undefined;
227
+ }
228
+ if (pattern[at] === "?") at++;
229
+ return bounds;
230
+ };
231
+
232
+ const parseAlternatives = (): RegexNode[][] => {
233
+ const branches: RegexNode[][] = [[]];
234
+ while (at < pattern.length && pattern[at] !== ")") {
235
+ if (pattern[at] === "|") {
236
+ at++;
237
+ branches.push([]);
238
+ continue;
239
+ }
240
+ const atom = parseAtom();
241
+ const bounds = parseQuantifier();
242
+ branches[branches.length - 1]!.push(bounds === undefined ? atom : { kind: "repeat", node: atom, ...bounds });
243
+ }
244
+ return branches;
245
+ };
246
+
247
+ const top: RegexNode[][] = [];
248
+ while (at < pattern.length) {
249
+ top.push(...parseAlternatives());
250
+ // A ")" without its "(": the RegExp constructor refuses the pattern
251
+ at++;
252
+ }
253
+ return top;
254
+ }
255
+
256
+ /** The characters that a branch can start with. An empty branch, or a start that can be empty, can start with each character. */
257
+ function firstOf(branch: readonly RegexNode[]): CharSet {
258
+ const node = branch[0];
259
+ if (node === undefined) return ANY;
260
+ if (node.kind === "atom") return node.width ? node.first : ANY;
261
+ if (node.kind === "repeat") return node.min >= 1 ? firstOf([node.node]) : ANY;
262
+ if (!node.width) return ANY;
263
+ const sets = node.branches.map(firstOf);
264
+ if (sets.some((one) => one.negated)) return ANY;
265
+ return { ranges: sets.flatMap((one) => one.ranges), negated: false };
266
+ }
267
+
268
+ /** What makes a group match the same text in more than one way. */
269
+ interface Ways {
270
+ /** A repetition without a bound inside the group. */
271
+ unbounded: boolean;
272
+ /** A repetition of variable length inside the group. */
273
+ variable: boolean;
274
+ /** Alternatives inside the group that can start with the same character. */
275
+ overlap: boolean;
276
+ /** An upper bound of the ways to match one time. */
277
+ count: number;
278
+ }
279
+
280
+ /** This function adds the ways of the parts inside a group to `ways`. */
281
+ function collect(nodes: readonly RegexNode[], ways: Ways): void {
282
+ for (const node of nodes) {
283
+ if (node.kind === "repeat") {
284
+ if (node.min !== node.max) {
285
+ ways.variable = true;
286
+ if (node.max === Infinity) ways.unbounded = true;
287
+ ways.count *= node.max - node.min + 1;
288
+ }
289
+ collect([node.node], ways);
290
+ } else if (node.kind === "group") {
291
+ if (node.branches.length > 1) {
292
+ ways.count *= node.branches.length;
293
+ const firsts = node.branches.map(firstOf);
294
+ if (firsts.some((first, index) => firsts.slice(index + 1).some((other) => overlaps(first, other)))) ways.overlap = true;
295
+ }
296
+ for (const branch of node.branches) collect(branch, ways);
297
+ }
298
+ }
299
+ }
300
+
301
+ /** The first problem of a repeated group in the parts, or undefined. */
302
+ function problemOf(nodes: readonly RegexNode[]): string | undefined {
303
+ for (const node of nodes) {
304
+ if (node.kind === "group") {
305
+ for (const branch of node.branches) {
306
+ const problem = problemOf(branch);
307
+ if (problem !== undefined) return problem;
308
+ }
309
+ continue;
310
+ }
311
+ if (node.kind !== "repeat") continue;
312
+ if (node.max > 1 && node.node.kind === "group") {
313
+ const ways: Ways = { unbounded: false, variable: false, overlap: false, count: 1 };
314
+ collect([node.node], ways);
315
+ if (ways.unbounded) return "repeats a group that repeats without a bound";
316
+ // A bounded repetition with few ways to match passes, for example (\d{1,3}\.){3}
317
+ const few = node.max !== Infinity && ways.count ** node.max <= MAX_WAYS;
318
+ if (ways.overlap && !few) return "repeats a group with alternatives that can start with the same character";
319
+ if (ways.variable && !few) return "repeats a group with a repetition of variable length";
320
+ }
321
+ const problem = problemOf([node.node]);
322
+ if (problem !== undefined) return problem;
323
+ }
324
+ return undefined;
325
+ }
326
+
327
+ /**
328
+ * This function gives the reason why a pattern can take an exponential time, or undefined. It
329
+ * reads the pattern with its flags: with `i`, `a` and `A` are the same character.
330
+ */
331
+ export function exponentialRegex(pattern: string, flags = ""): string | undefined {
332
+ return problemOf(parse(pattern, flags.includes("i")).flat());
333
+ }