@ericcornelissen/lregexp 1.0.5 → 1.0.7
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/LICENSE +1 -1
- package/README.md +69 -13
- package/SECURITY.md +11 -0
- package/index.cjs +19 -3
- package/index.d.ts +3 -3
- package/index.js +19 -3
- package/is-supported-regexp-flag.cjs +2 -0
- package/package.json +2 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,21 +1,35 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: CC0-1.0 -->
|
|
2
|
+
|
|
1
3
|
# lRegExp
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
Transparent linear-time ([non-backtracking]) regular expressions for libraries.
|
|
4
6
|
|
|
5
7
|
[non-backtracking]: https://v8.dev/blog/non-backtracking-regexp
|
|
6
8
|
|
|
7
9
|
## Usage
|
|
8
10
|
|
|
9
|
-
This library exports a drop-in replacement for the built-in RegExp
|
|
11
|
+
This library exports a drop-in replacement for the built-in RegExp ([caveats]
|
|
12
|
+
apply).
|
|
10
13
|
|
|
11
|
-
|
|
12
|
-
npm install @ericcornelissen/lregexp
|
|
13
|
-
```
|
|
14
|
+
1. Install
|
|
14
15
|
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
```shell
|
|
17
|
+
npm install @ericcornelissen/lregexp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
2. Import
|
|
21
|
+
|
|
22
|
+
```javascript
|
|
23
|
+
import RegExp from "@ericcornelissen/lregexp";
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
3. Use
|
|
27
|
+
|
|
28
|
+
```javascript
|
|
29
|
+
new RegExp("[linear]{6}");
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
[caveats]: #caveats
|
|
19
33
|
|
|
20
34
|
## Why
|
|
21
35
|
|
|
@@ -23,9 +37,51 @@ Backtracking regular expressions can take exponential time to evaluate, leading
|
|
|
23
37
|
to the dreaded _ReDoS_ vulnerability. Linear-time regular expressions avoid this
|
|
24
38
|
by not backtracking.
|
|
25
39
|
|
|
40
|
+
In Node.js, linear-time regular expressions can be created using the `l` flag
|
|
41
|
+
provided the `--enable-experimental-regexp-engine` CLI option is used. This
|
|
42
|
+
makes it difficult for library authors to tap into. Using this package, a
|
|
43
|
+
library can use the RegExp constructor as usual and benefit from the linear time
|
|
44
|
+
regular expression engine when its users enable it. If they don't, it gracefully
|
|
45
|
+
falls back to the default constructor.
|
|
46
|
+
|
|
26
47
|
## Caveats
|
|
27
48
|
|
|
28
|
-
Not all regular
|
|
29
|
-
|
|
30
|
-
incompatible unless you run it with
|
|
31
|
-
|
|
49
|
+
Not all valid JavaScript regular expressions are supported when using the
|
|
50
|
+
`--enable-experimental-regexp-engine` CLI option. This library won't tell you if
|
|
51
|
+
your regular expressions are incompatible, unless you run it with that CLI
|
|
52
|
+
option. If a regular expression is incompatible the constructor will throw a
|
|
53
|
+
SyntaxError.
|
|
54
|
+
|
|
55
|
+
To support users of this package in writing compatible regular expressions we're
|
|
56
|
+
interested in:
|
|
57
|
+
|
|
58
|
+
- an ESLint plugin to lint regular expressions and raise warnings for the use of
|
|
59
|
+
regex features not supported by the non-backtracing engine; ([#4])
|
|
60
|
+
- a tool (CLI/web) to check a given regular expression for compatibility with
|
|
61
|
+
the non-backtracing engine. ([#21])
|
|
62
|
+
|
|
63
|
+
[#4]: https://github.com/ericcornelissen/lregexp/issues/4
|
|
64
|
+
[#21]: https://github.com/ericcornelissen/lregexp/issues/21
|
|
65
|
+
|
|
66
|
+
## How
|
|
67
|
+
|
|
68
|
+
If `--enable-experimental-regexp-engine` is used, the RegExp constructor from
|
|
69
|
+
this package automatically adds the `l` flag to all regular expressions it
|
|
70
|
+
constructs. If not, the RegExp constructor behavior is unchanged.
|
|
71
|
+
|
|
72
|
+
## Example
|
|
73
|
+
|
|
74
|
+
A classic example of a ReDoS-vulnerable regular expression is `(a*)*b`. Using
|
|
75
|
+
this with vanilla Node.js on a pathological input string takes some time, test
|
|
76
|
+
it for yourself with (add an `a` and the runtime doubles):
|
|
77
|
+
|
|
78
|
+
```shell
|
|
79
|
+
node -e '/(a*)*b/.test("aaaaaaaaaaaaaaaaaaaaaaaaac")'
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
When the non-backtracking regular expression engine is enabled, the expression
|
|
83
|
+
evaluates instantly:
|
|
84
|
+
|
|
85
|
+
```shell
|
|
86
|
+
node -e '/(a*)*b/l.test("aaaaaaaaaaaaaaaaaaaaaaaaac")' --enable-experimental-regexp-engine
|
|
87
|
+
```
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
<!-- SPDX-License-Identifier: CC0-1.0 -->
|
|
2
|
+
|
|
3
|
+
# Security Policy
|
|
4
|
+
|
|
5
|
+
All security issues in `@ericcornelissen/lregexp` should be reported publicly as
|
|
6
|
+
bugs. Private reports will be made public by the maintainers after 7 days with
|
|
7
|
+
best-effort attribution.
|
|
8
|
+
|
|
9
|
+
This document should be considered expired after 2026-06-01. If you are reading
|
|
10
|
+
this after that date you should try to find an up-to-date version in the source
|
|
11
|
+
repository.
|
package/index.cjs
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
1
3
|
const isSupportedRegexpFlag = require("./is-supported-regexp-flag.cjs");
|
|
2
4
|
|
|
5
|
+
/**
|
|
6
|
+
* The `RegExp()` constructor creates {@link RegExp} objects.
|
|
7
|
+
*
|
|
8
|
+
* @param {string|RegExp} pattern The text of the regular expression. This can also be another RegExp object.
|
|
9
|
+
* @param {string} [flags] If specified, flags is a string that contains the flags to add. Alternatively, if a RegExp object is supplied for the pattern, the flags string will replace any of that object's flags.
|
|
10
|
+
* @returns {RegExp} A {@link RegExp} object constructed from `pattern` and `flags`.
|
|
11
|
+
* @throws {SyntaxError} Thrown in one of the following cases: `pattern` cannot be parsed as a valid regular expression, or `flags` contains repeated characters or any character outside of those allowed.
|
|
12
|
+
*/
|
|
3
13
|
let lRegExp = RegExp;
|
|
4
14
|
|
|
5
15
|
if (isSupportedRegexpFlag("l")) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
16
|
+
lRegExp = function(pattern, flags) {
|
|
17
|
+
if (flags === undefined) {
|
|
18
|
+
flags = "";
|
|
19
|
+
if (pattern instanceof RegExp && pattern.flags) {
|
|
20
|
+
flags = pattern.flags.replace(/l/g, "");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return new RegExp(pattern, `${flags}l`);
|
|
9
25
|
};
|
|
10
26
|
}
|
|
11
27
|
|
package/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
3
|
+
export default RegExp;
|
package/index.js
CHANGED
|
@@ -1,11 +1,27 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
|
|
1
3
|
import isSupportedRegexpFlag from "is-supported-regexp-flag";
|
|
2
4
|
|
|
5
|
+
/**
|
|
6
|
+
* The `RegExp()` constructor creates {@link RegExp} objects.
|
|
7
|
+
*
|
|
8
|
+
* @param {string|RegExp} pattern The text of the regular expression. This can also be another RegExp object.
|
|
9
|
+
* @param {string} [flags] If specified, flags is a string that contains the flags to add. Alternatively, if a RegExp object is supplied for the pattern, the flags string will replace any of that object's flags.
|
|
10
|
+
* @returns {RegExp} A {@link RegExp} object constructed from `pattern` and `flags`.
|
|
11
|
+
* @throws {SyntaxError} Thrown in one of the following cases: `pattern` cannot be parsed as a valid regular expression, or `flags` contains repeated characters or any character outside of those allowed.
|
|
12
|
+
*/
|
|
3
13
|
let lRegExp = RegExp;
|
|
4
14
|
|
|
5
15
|
if (isSupportedRegexpFlag("l")) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
16
|
+
lRegExp = function(pattern, flags) {
|
|
17
|
+
if (flags === undefined) {
|
|
18
|
+
flags = "";
|
|
19
|
+
if (pattern instanceof RegExp && pattern.flags) {
|
|
20
|
+
flags = pattern.flags.replace(/l/g, "");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return new RegExp(pattern, `${flags}l`);
|
|
9
25
|
};
|
|
10
26
|
}
|
|
11
27
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ericcornelissen/lregexp",
|
|
3
|
-
"description": "
|
|
4
|
-
"version": "1.0.
|
|
3
|
+
"description": "Transparent linear-time (non-backtracking) regular expressions for libraries",
|
|
4
|
+
"version": "1.0.7",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"exports": {
|