Prevent panic in HashHistory::location() on malformed hash URLs#549
Open
ranile wants to merge 2 commits into
Open
Prevent panic in HashHistory::location() on malformed hash URLs#549ranile wants to merge 2 commits into
HashHistory::location() on malformed hash URLs#549ranile wants to merge 2 commits into
Conversation
…ash URLs HashHistory::location() called assert_absolute_path on the URL hash, which panicked if the hash didn't start with #/. Users can edit the URL bar at any time to produce hashes like #aaa or just #, crashing the application on the next location() call. Replace the assertion with graceful normalization: prepend / if missing, log a console warning, and auto-correct the URL via replaceState. This matches how all major JS router libraries (React Router, Vue Router) handle the same problem — none of them throw on a malformed hash. The push/replace methods continue to assert since those are developer-controlled inputs where a relative path is always a bug. Fixes #470 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The browser history state is shared between tests in wasm-pack so separate tests can cause issues
Madoshakalaka
approved these changes
May 8, 2026
Comment on lines
+260
to
+265
| &format!( | ||
| "[gloo_history] HashHistory: URL hash '#{}' does not start with '/'. \ | ||
| The hash was normalized to '#/{}'. \ | ||
| Ensure hash-based routes always begin with '#/'.", | ||
| raw, raw | ||
| ) |
Collaborator
There was a problem hiding this comment.
seems good. except can you inline these two raws? clippy doesn't like it.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
HashHistory::location()called assert_absolute_path on the URL hash, which panicked if the hash didn't start with #/. Users can edit the URL bar at any time to produce hashes like #aaa or just #, crashing the application on the next location() call.Replace the
assert_absolute_pathcall inlocation()with graceful normalization:/, prepend/(or default to/if empty).replaceStateso it stays in canonical#/...form.The
push/replacemethods continue to assert, since those are developer-controlled inputs where a relative path is always a bug.This approach mirrors how every mainstream JS router library handles the same problem. None of them throw on a malformed hash:
historyv4 / React Router 5 (source):addLeadingSlashnormalizes on read;replaceHashPathauto-corrects the URL on everyhashchange.historyv5 / React Router 6 (source):parsePathwith destructuring defaults (pathname = "/") silently falls back to root.pathname = "/" + pathnameprepend with a code comment explaining why.ensureSlash()runs on everyhashchange, prepends/if missing, replaces the URL, and aborts the transition.createWebHashHistorydelegates tocreateWebHistorywith a#-based base, unifying URL parsing across modes.Fixes #470
This prior art was researched by Claude and used to implement the fix in this PR