From f64b4bb08a18c705f0f4d9cc966ded2270e0edc5 Mon Sep 17 00:00:00 2001 From: Luke Edwards Date: Fri, 13 Aug 2021 17:26:16 -0700 Subject: [PATCH] fix(url): ensure `toDecode` involved in cache match; - Related: https://github.com/sveltejs/kit/issues/2166 --- packages/url/index.js | 6 ++-- packages/url/test/index.js | 56 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/packages/url/index.js b/packages/url/index.js index a7c4322..2631601 100644 --- a/packages/url/index.js +++ b/packages/url/index.js @@ -21,8 +21,8 @@ export function parse(req, toDecode) { let raw = req.url; if (raw == null) return; - let prev = req._parsedUrl; - if (prev && prev.raw === raw) return prev; + let prev=req._parsedUrl, encoded=!req._decoded; + if (prev && prev.raw === raw && !toDecode === encoded) return prev; let pathname=raw, search='', query; @@ -37,7 +37,7 @@ export function parse(req, toDecode) { } } - if (!!toDecode && !req._decoded) { + if (!!toDecode && encoded) { req._decoded = true; if (pathname.indexOf('%') !== -1) { try { pathname = decodeURIComponent(pathname) } diff --git a/packages/url/test/index.js b/packages/url/test/index.js index 694ae16..d9646af 100644 --- a/packages/url/test/index.js +++ b/packages/url/test/index.js @@ -210,4 +210,60 @@ test('url :: decode :: URI malformed', () => { }); }); +test('url :: decode :: cache :: hit', () => { + /** @type any */ + let req = { url: '/foo/hell%C3%B6' }; + let out1 = parse(req, true); + + // @ts-ignore + out1.foobar = 123; + + let out2 = parse(req, true); + + // @ts-ignore + assert.is(out2.foobar, 123); + assert.is(out1, out2, 'referential'); + assert.is(out1.pathname, '/foo/hellö'); +}); + +test('url :: decode :: cache :: miss #1', () => { + /** @type any */ + let req = { url: '/foo/hell%C3%B6?fizz=buzz' }; + let out1 = parse(req); + + assert.is(req._parsedUrl, out1); + assert.is(out1.pathname, '/foo/hell%C3%B6'); + + // @ts-ignore + out1.foobar = 123; + + let out2 = parse(req, true); + + // @ts-ignore + assert.is(out2.foobar, undefined); + assert.is.not(req._parsedUrl, out1); + assert.is.not(out1, out2, 'referential'); + assert.is(out2.pathname, '/foo/hellö'); +}); + +test('url :: decode :: cache :: miss #2', () => { + /** @type any */ + let req = { url: '/foo/hell%C3%B6?fizz=buzz' }; + let out1 = parse(req, true); + + assert.is(req._parsedUrl, out1); + assert.is(out1.pathname, '/foo/hellö'); + + // @ts-ignore + out1.foobar = 123; + + let out2 = parse(req); + + // @ts-ignore + assert.is(out2.foobar, undefined); + assert.is.not(req._parsedUrl, out1); + assert.is.not(out1, out2, 'referential'); + assert.is(out2.pathname, '/foo/hell%C3%B6'); +}); + test.run();