Skip to content

Commit

Permalink
Add backtrack protection to 6.x (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
blakeembrey authored Sep 12, 2024
1 parent 28a5b27 commit f1253b4
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 55 deletions.
102 changes: 102 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 36,7 @@
"@types/node": "^20.4.9",
"@types/semver": "^7.3.1",
"@vitest/coverage-v8": "^1.4.0",
"recheck": "^4.4.5",
"semver": "^7.3.5",
"size-limit": "^11.1.2",
"typescript": "^5.1.6"
Expand All @@ -46,7 47,7 @@
"size-limit": [
{
"path": "dist.es2015/index.js",
"limit": "2 kB"
"limit": "2.1 kB"
}
],
"ts-scripts": {
Expand Down
21 changes: 21 additions & 0 deletions redos.ts
Original file line number Diff line number Diff line change
@@ -0,0 1,21 @@
import { checkSync } from "recheck";
import { pathToRegexp } from "./src/index.js";

let safe = 0;
let fail = 0;

const tests = ["/:x{/foobar/:y}?-:z"];

for (const path of tests) {
const regexp = pathToRegexp(path);
const result = checkSync(regexp.source, regexp.flags);
if (result.status === "safe") {
safe ;
console.log("Safe:", path, String(regexp));
} else {
fail ;
console.log("Fail:", path, String(regexp));
}
}

console.log("Safe:", safe, "Fail:", fail);
79 changes: 32 additions & 47 deletions src/index.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1353,7 1353,7 @@ const TESTS: Test[] = [
prefix: ".",
suffix: "",
modifier: " ",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\.)[^\\/#\\?]) ?",
},
],
[
Expand Down Expand Up @@ -1397,7 1397,7 @@ const TESTS: Test[] = [
prefix: ".",
suffix: "",
modifier: "",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\.)[^\\/#\\?]) ?",
},
".",
],
Expand Down Expand Up @@ -1430,13 1430,13 @@ const TESTS: Test[] = [
prefix: ".",
suffix: "",
modifier: "",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\.)[^\\/#\\?]) ?",
},
],
[
["/route.html", ["/route.html", "route", "html"]],
["/route", null],
["/route.html.json", ["/route.html.json", "route", "html.json"]],
["/route.html.json", ["/route.html.json", "route.html", "json"]],
],
[
[{}, null],
Expand All @@ -1459,13 1459,13 @@ const TESTS: Test[] = [
prefix: ".",
suffix: "",
modifier: "?",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\.)[^\\/#\\?]) ?",
},
],
[
["/route", ["/route", "route", undefined]],
["/route.json", ["/route.json", "route", "json"]],
["/route.json.html", ["/route.json.html", "route", "json.html"]],
["/route.json.html", ["/route.json.html", "route.json", "html"]],
],
[
[{ test: "route" }, "/route"],
Expand All @@ -1491,13 1491,13 @@ const TESTS: Test[] = [
prefix: ".",
suffix: "",
modifier: "?",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\.)[^\\/#\\?]) ?",
},
],
[
["/route", ["/route", "route", undefined]],
["/route.json", ["/route.json", "route", "json"]],
["/route.json.html", ["/route.json.html", "route", "json.html"]],
["/route.json.html", ["/route.json.html", "route.json", "html"]],
],
[
[{ test: "route" }, "/route"],
Expand Down Expand Up @@ -2084,7 2084,7 @@ const TESTS: Test[] = [
prefix: "",
suffix: "",
modifier: "?",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\()[^\\/#\\?]) ?",
},
")",
],
Expand Down Expand Up @@ -2290,7 2290,7 @@ const TESTS: Test[] = [
prefix: ".",
suffix: "",
modifier: "",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\.)[^\\/#\\?]) ?",
},
],
[
Expand Down Expand Up @@ -2356,14 2356,14 @@ const TESTS: Test[] = [
[
{
name: "foo",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\$)[^\\/#\\?]) ?",
prefix: "$",
suffix: "",
modifier: "",
},
{
name: "bar",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!\\$)[^\\/#\\?]) ?",
prefix: "$",
suffix: "",
modifier: "?",
Expand Down Expand Up @@ -2392,14 2392,14 @@ const TESTS: Test[] = [
},
{
name: "attr2",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!-)[^\\/#\\?]) ?",
prefix: "-",
suffix: "",
modifier: "?",
},
{
name: "attr3",
pattern: "[^\\/#\\?] ?",
pattern: "(?:(?!-)[^\\/#\\?]) ?",
prefix: "-",
suffix: "",
modifier: "?",
Expand Down Expand Up @@ -2597,39 2597,6 @@ const TESTS: Test[] = [
[{ foo: "#" }, null],
],
],
/**
* https://github.com/pillarjs/path-to-regexp/issues/260
*/
[
":name*",
undefined,
[
{
name: "name",
prefix: "",
suffix: "",
modifier: "*",
pattern: "[^\\/#\\?] ?",
},
],
[["foobar", ["foobar", "foobar"]]],
[[{ name: "foobar" }, "foobar"]],
],
[
":name ",
undefined,
[
{
name: "name",
prefix: "",
suffix: "",
modifier: " ",
pattern: "[^\\/#\\?] ?",
},
],
[["foobar", ["foobar", "foobar"]]],
[[{ name: "foobar" }, "foobar"]],
],
];

/**
Expand Down Expand Up @@ -2799,6 2766,24 @@ describe("path-to-regexp", () => {
pathToRegexp.pathToRegexp("/foo?");
}).toThrow(new TypeError("Unexpected MODIFIER at 4, expected END"));
});

it("should throw on parameters without text between them", () => {
expect(() => {
pathToRegexp.pathToRegexp("/:x:y");
}).toThrow(
new TypeError(
`Must have text between two parameters, missing text after "x"`,
),
);
});

it("should throw on unrepeatable params", () => {
expect(() => {
pathToRegexp.pathToRegexp("/foo:x*");
}).toThrow(
new TypeError(`Can not repeat "x" without a prefix and suffix`),
);
});
});

describe("tokens", () => {
Expand Down
Loading

0 comments on commit f1253b4

Please sign in to comment.