Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Fix runtime router handling of encoded query parameters
Browse files Browse the repository at this point in the history
  • Loading branch information
bermi committed Dec 14, 2020
1 parent ae15d6d commit 07b97ef
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 12 deletions.
27 changes: 20 additions & 7 deletions runtime/src/app/router/index.ts
Expand Up @@ -67,17 +67,30 @@ export function init(base: string, handler: (dest: Target) => Promise<void>): vo
addEventListener('popstate', handle_popstate);
}

export function extract_query(search: string) {
// IE11 does not support URLSearchParams so we'll fall back to a custom
// RegExp that mimics the standard URLSearchParams method
const _get_query_array = (search: string): string[][] => {
if (typeof URLSearchParams !== 'undefined') {
return [...new URLSearchParams(search).entries()];
}
return search.slice(1).split('&').map(searchParam => {
// Instead of `.*` we'll use \s\S to allow characters and non characters
// such as [\r\n\v\f]
const [, key, value = ''] = /([^=]*)(?:=([\S\s]*))?/.exec(decodeURIComponent(searchParam.replace(/\+/g, ' ')));
return [ key, value ];
});
};

export function extract_query(search: string): Query {
const query: Query = Object.create(null);
if (search.length > 0) {
search.slice(1).split('&').forEach(searchParam => {
const [, key, value = ''] = /([^=]*)(?:=(.*))?/.exec(decodeURIComponent(searchParam.replace(/\+/g, ' ')));
return search.length ? _get_query_array(search).reduce(
(query, [key, value]) => {
if (typeof query[key] === 'string') query[key] = [<string>query[key]];
if (typeof query[key] === 'object') (query[key] as string[]).push(value);
else query[key] = value;
});
}
return query;
return query;
}, query) :
query;
}

export function select_target(url: URL): Target {
Expand Down
2 changes: 1 addition & 1 deletion test/apps/encoding/src/routes/index.html
@@ -1,3 +1,3 @@
<h1>Great success!</h1>

<a href="echo/page/encöded?message=hëllö+wörld&föo=bar&=baz&tel=%2B123456789">link</a>
<a href="echo/page/encöded?message=hëllö+wörld&föo=bar&=baz&tel=%2B123456789&multiline=multi%0Aline">link</a>
6 changes: 3 additions & 3 deletions test/apps/encoding/test.ts
Expand Up @@ -26,11 +26,11 @@ describe('encoding', function() {
});

it('encodes req.params and req.query for server-rendered pages', async () => {
await r.load('/echo/page/encöded?message=hëllö+wörld&föo=bar&=baz&tel=%2B123456789');
await r.load('/echo/page/encöded?message=hëllö+wörld&föo=bar&=baz&tel=%2B123456789&multiline=multi%0Aline');

assert.strictEqual(
await r.text('h1'),
'encöded {"message":"hëllö wörld","föo":"bar","":"baz","tel":"+123456789"}'
'encöded {"message":"hëllö wörld","föo":"bar","":"baz","tel":"+123456789","multiline":"multi\\nline"}'
);
});

Expand All @@ -44,7 +44,7 @@ describe('encoding', function() {

assert.strictEqual(
await r.text('h1'),
'encöded {"message":"hëllö wörld","föo":"bar","":"baz","tel":"+123456789"}'
'encöded {"message":"hëllö wörld","föo":"bar","":"baz","tel":"+123456789","multiline":"multi\\nline"}'
);
});

Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Expand Up @@ -7,7 +7,7 @@
"moduleResolution": "Node",
"resolveJsonModule": true,
"skipLibCheck": true,
"lib": ["es5", "es6", "dom"],
"lib": ["es5", "es6", "dom", "dom.iterable"],
"importHelpers": true,
"target": "ES6",
"baseUrl": ".",
Expand Down

0 comments on commit 07b97ef

Please sign in to comment.