Skip to content

Commit 5de1622

Browse files
committed
fix regex handling for URLs containing newline characters (%0A) (remix-run#13490)
1 parent a00f3a0 commit 5de1622

File tree

3 files changed

+22
-1
lines changed

3 files changed

+22
-1
lines changed

packages/react-router/__tests__/matchPath-test.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,17 @@ describe("matchPath *", () => {
355355
pathnameBase: "/users/foo*",
356356
});
357357
});
358+
359+
it("matches a URL with %0A (a newline character)", () => {
360+
expect(matchPath("*", "/%0A")).toMatchObject({
361+
pathname: "/%0A",
362+
pathnameBase: "/",
363+
})
364+
expect(matchPath("*", "/new%0Aline")).toMatchObject({
365+
pathname: "/new%0Aline",
366+
pathnameBase: "/",
367+
})
368+
})
358369
});
359370

360371
describe("matchPath warnings", () => {

packages/react-router/__tests__/matchRoutes-test.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ describe("matchRoutes", () => {
6565
expect(pickPaths(routes, "/hometypo")).toEqual(["*"]);
6666
});
6767

68+
it("matches root * routes for URLs containing %0A (a newline character)", () => {
69+
expect(pickPaths(routes, "/%0A")).toEqual(["*"]);
70+
expect(pickPaths(routes, "/new%0Aline")).toEqual(["*"]);
71+
});
72+
6873
it("matches index routes with path correctly", () => {
6974
expect(pickPaths(routes, "/withpath")).toEqual(["/withpath"]);
7075
});

packages/react-router/lib/router/utils.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1255,6 +1255,9 @@ export function compilePath(
12551255
return isOptional ? "/?([^\\/]+)?" : "/([^\\/]+)";
12561256
}
12571257
);
1258+
// If the URL contains %0A (a newline character),
1259+
// the regular expression will not match correctly unless the s (single line) flag is set.
1260+
let regexpFlags = ["s"];
12581261

12591262
if (path.endsWith("*")) {
12601263
params.push({ paramName: "*" });
@@ -1278,7 +1281,9 @@ export function compilePath(
12781281
// Nothing to match for "" or "/"
12791282
}
12801283

1281-
let matcher = new RegExp(regexpSource, caseSensitive ? undefined : "i");
1284+
if (!caseSensitive) regexpFlags.push("i");
1285+
1286+
let matcher = new RegExp(regexpSource, regexpFlags.join(""));
12821287

12831288
return [matcher, params];
12841289
}

0 commit comments

Comments
 (0)