diff --git a/src/core/create_routes.ts b/src/core/create_routes.ts index 3888b873a..6fdc7d266 100644 --- a/src/core/create_routes.ts +++ b/src/core/create_routes.ts @@ -33,7 +33,7 @@ export default function create_routes({ files } = { files: glob.sync('**/*.*', { let i = parts.length; let nested = true; while (i--) { - const part = encodeURIComponent(parts[i].normalize()).replace(/%5B/g, '[').replace(/%5D/g, ']'); + const part = encodeURI(parts[i].normalize()).replace(/\?/g, '%3F').replace(/#/g, '%23').replace(/%5B/g, '[').replace(/%5D/g, ']'); const dynamic = ~part.indexOf('['); if (dynamic) { diff --git a/test/unit/create_routes.test.js b/test/unit/create_routes.test.js index 5b70ffe96..112e95c6b 100644 --- a/test/unit/create_routes.test.js +++ b/test/unit/create_routes.test.js @@ -2,6 +2,25 @@ const assert = require('assert'); const { create_routes } = require('../../dist/core.ts.js'); describe('create_routes', () => { + it('encodes caharcters not allowed in path', () => { + const routes = create_routes({ + files: [ + '"', + '#', + '?' + ] + }); + + assert.deepEqual( + routes.map(r => r.pattern), + [ + /^\/%22\/?$/, + /^\/%23\/?$/, + /^\/%3F\/?$/ + ] + ); + }); + it('sorts routes correctly', () => { const routes = create_routes({ files: ['index.html', 'about.html', 'post/f[xx].html', '[wildcard].html', 'post/foo.html', 'post/[id].html', 'post/bar.html', 'post/[id].json.js']