From ee9772b7e0fb8e2755b5cd9163a991fe65cde5d2 Mon Sep 17 00:00:00 2001 From: rameel Date: Sun, 25 Oct 2026 23:27:35 +0500 Subject: [PATCH 1/2] plugin/router: stop spreading resolved catch-all values into characters --- src/plugins/router/RoutePattern.js | 7 +++++-- tests/utilities/RoutePattern.test.js | 7 +++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/plugins/router/RoutePattern.js b/src/plugins/router/RoutePattern.js index 9982b9d..61160a5 100644 --- a/src/plugins/router/RoutePattern.js +++ b/src/plugins/router/RoutePattern.js @@ -174,8 +174,11 @@ export class RoutePattern { } if (part.catch_all) { - value = as_array(value); - parts.push(...value.map(v => encodeURIComponent(v)).join("/")); + value = as_array(value).map(v => encodeURIComponent(v)).join("/"); + + // an empty catch-all value adds nothing, + // so a segment consisting of it alone is omitted + value && parts.push(value); } else { parts.push(encodeURIComponent(value)); diff --git a/tests/utilities/RoutePattern.test.js b/tests/utilities/RoutePattern.test.js index 7a6fcb0..bf506d3 100644 --- a/tests/utilities/RoutePattern.test.js +++ b/tests/utilities/RoutePattern.test.js @@ -412,6 +412,13 @@ describe("RoutePattern", () => { expect(route.match("/abcdef")).toBeNull(); }); + test("resolve: /files/{path*}", () => { + const route = new RoutePattern("/files/{path*}"); + expect(route.resolve({ path: ["a", "b c", "d/e"] })).toBe("/files/a/b%20c/d%2Fe"); + expect(route.resolve({ path: [] })).toBe("/files"); + expect(route.resolve({})).toBe("/files"); + }); + test("error: unclosed brace parameter", () => { assert.throws(() => new RoutePattern("/{id"), "Invalid pattern: /{id"); assert.throws(() => new RoutePattern("/{id}/{"), "Invalid pattern: /{"); From 9b721aaaa0025e8fb250cdb75965315928796564 Mon Sep 17 00:00:00 2001 From: rameel Date: Sun, 25 Oct 2026 23:27:50 +0500 Subject: [PATCH 2/2] plugin/router: compare the length constraint arguments strictly --- src/plugins/router/RoutePattern.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plugins/router/RoutePattern.js b/src/plugins/router/RoutePattern.js index 61160a5..9f99e46 100644 --- a/src/plugins/router/RoutePattern.js +++ b/src/plugins/router/RoutePattern.js @@ -52,7 +52,7 @@ const default_constraints = Object.freeze({ "length"(value) { let values = value.split(",").map(v => v.trim()); return { - test: values.length == 2 + test: values.length === 2 ? v => v.length >= +values[0] && v.length <= +values[1] : v => v.length === +values[0] };