Skip to content

Commit

Permalink
Add defensiveless for malformed hash urls without a leading slash (#1…
Browse files Browse the repository at this point in the history
  • Loading branch information
brophdawg11 authored Aug 1, 2023
1 parent 4bdd6b4 commit 2ab24cc
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 0 deletions.
5 changes: 5 additions & 0 deletions .changeset/hash-leading-slash.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@remix-run/router": patch
---

Ensure hash history always includes a leading slash on hash pathnames
16 changes: 16 additions & 0 deletions packages/router/__tests__/hash-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,22 @@ describe("a hash history", () => {
expect(unencodedHref).toEqual("#/#abc");
});

it("prefixes raw hash values with /", () => {
dom.window.history.replaceState(null, "", "#hello");
history = createHashHistory({ window: dom.window as unknown as Window });
expect(history.location.pathname).toBe("/hello");

history.push("world");
expect(history.location.pathname).toBe("/world");

// Not supported but ensure we don't prefix here
history.push("./relative");
expect(history.location.pathname).toBe("./relative");

history.push("../relative");
expect(history.location.pathname).toBe("../relative");
});

describe("listen", () => {
it("does not immediately call listeners", () => {
Listen(history);
Expand Down
11 changes: 11 additions & 0 deletions packages/router/history.ts
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,17 @@ export function createHashHistory(
search = "",
hash = "",
} = parsePath(window.location.hash.substr(1));

// Hash URL should always have a leading / just like window.location.pathname
// does, so if an app ends up at a route like /#something then we add a
// leading slash so all of our path-matching behaves the same as if it would
// in a browser router. This is particularly important when there exists a
// root splat route (<Route path="*">) since that matches internally against
// "/*" and we'd expect /#something to 404 in a hash router app.
if (!pathname.startsWith("/") && !pathname.startsWith(".")) {
pathname = "/" + pathname;
}

return createLocation(
"",
{ pathname, search, hash },
Expand Down

0 comments on commit 2ab24cc

Please sign in to comment.