fix(web): interpret encoded Next route paths

This commit is contained in:
morluto committed 2026-10-27 07:17:10 +08:00
1 parent 087acf26e8
commit 0dea08fb07
3 files changed
+152 -5

No files matched your search

+30 -5
View File
@@ -62,10 +62,10 @@ export const classifyNextAppRoutePath = (
): NextAppRoutePath | undefined => {
if (raw.includes("\\") || context.kind === "source-reference") return;
let value = raw;
if (
const urlPath =
context.kind === "script-url" ||
(context.kind === "source-literal" && raw.includes("://"))
) {
(context.kind === "source-literal" && raw.includes("://"));
if (urlPath) {
try {
value = new URL(raw).pathname;
} catch {
@@ -118,11 +118,36 @@ export const classifyNextAppRoutePath = (
};
return;
}
if (urlPath) {
// Captured script URLs encode filesystem segments. Decode once here, after
// selecting the Next asset root; source paths retain their literal spelling.
if (/%(?:2f|5c)/iu.test(relative))
return {
kind: "unknown",
reason: "A Next script URL contains an encoded path separator.",
};
try {
relative = decodeURIComponent(relative);
} catch (cause: unknown) {
if (!(cause instanceof URIError)) throw cause;
return {
kind: "unknown",
reason: "A Next script URL contains malformed percent encoding.",
};
}
}
const match =
/^(?:(.*?)\/)?page(?:-([^/?#]+)\.js|\.(?:[cm]?jsx?|tsx?)|)(?:[?#].*)?$/u.exec(
/^(?:(.*?)\/)?page(?:-([^/?#]+)\.js|\.(?:[cm]?jsx?|tsx?)|)([?#].*)?$/u.exec(
relative,
);
if (match === null || (match[2] !== undefined && !chunk)) return;
if (
match === null ||
(match[2] !== undefined && !chunk) ||
// URL parsing already removed URL suffixes. Any decoded delimiter is a
// filename byte, as it is in an inventoried filesystem source path.
(match[3] !== undefined && (urlPath || context.kind === "source-path"))
)
return;
const sourceSegments = (match[1] ?? "").split("/");
// A private folder excludes the whole page, including intercepted ancestors.
// Keep filesystem segment spelling: only Next's explicit %5F escape is