Skip to content

Commit 3966f58

Browse files
authored
Merge pull request #142 from preactjs/fix-double-decode
Fix double decode w/ nested router
2 parents 3cdf432 + b15f35e commit 3966f58

3 files changed

Lines changed: 35 additions & 1 deletion

File tree

src/router.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export const exec = (url, route, matches = {}) => {
7676
if (!m && param == val) continue;
7777
// /foo/* match
7878
if (!m && val && flag == '*') {
79-
matches.rest = '/' + url.slice(i).map(decodeURIComponent).join('/');
79+
matches.rest = '/' + url.slice(i).join('/');
8080
break;
8181
}
8282
// segment mismatch / missing required field:

test/node/router-match.test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,11 @@ test('Handles leading/trailing slashes', () => {
116116
});
117117
});
118118

119+
test('Percent-encoded characters in rest are not decoded', () => {
120+
const result = execPath('/nested/child/%25', '/nested/*');
121+
assert.equal(result, { path: '/nested/child/%25', params: {}, query: {}, rest: '/child/%25' });
122+
});
123+
119124
test('should not overwrite existing properties', () => {
120125
const result = execPath('/foo/bar', '/:path/:query', { path: '/custom-path' });
121126
assert.equal(result, {

test/router.test.js

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,35 @@ describe('Router', () => {
927927
expect(params).to.deep.include({ id: 'bar' });
928928
});
929929

930+
it('should not double-decode percent-encoded characters in nested routes', async () => {
931+
let route;
932+
const Inner = () => (
933+
<Router>
934+
<Route
935+
path="/child/:id"
936+
component={() => {
937+
route = useRoute();
938+
return null;
939+
}}
940+
/>
941+
</Router>
942+
);
943+
944+
render(
945+
<LocationProvider>
946+
<Router>
947+
<Route path="/nested/*" component={Inner} />
948+
</Router>
949+
<a href="/nested/child/%25"></a>
950+
</LocationProvider>,
951+
scratch
952+
);
953+
954+
scratch.querySelector('a[href="/nested/child/%25"]').click();
955+
await sleep(1);
956+
expect(route).to.deep.include({ params: { id: '%' } });
957+
});
958+
930959
it('should replace the current URL', async () => {
931960
const pushState = sinon.spy(history, 'pushState');
932961
const replaceState = sinon.spy(history, 'replaceState');

0 commit comments

Comments
 (0)