From 0f6af4edf0d4d32721a0f97e163cc694bf14eeb8 Mon Sep 17 00:00:00 2001 From: Chetan Padia Date: Tue, 7 May 2024 11:15:51 +0100 Subject: [PATCH] Fix for files with `%` in filename (#452) * Add a test file with a percent in the filename * Fix `href` encoding in directory listing * Fix for filename with `%` in their filename * Reinstate `path.join` workaround for Windows --- index.js | 3 ++- lib/dirList.js | 2 +- test/dir-list.test.js | 14 ++++++++------ test/static.test.js | 27 +++++++++++++++++++++++++++ test/static/100%.txt | 1 + 5 files changed, 39 insertions(+), 8 deletions(-) create mode 100644 test/static/100%.txt diff --git a/index.js b/index.js index cfa6cb13..f2251fc7 100644 --- a/index.js +++ b/index.js @@ -221,7 +221,8 @@ async function fastifyStatic (fastify, opts) { } } - const stream = send(request.raw, pathnameForSend, options) + // `send(..., path, ...)` will URI-decode path so we pass an encoded path here + const stream = send(request.raw, encodeURI(pathnameForSend), options) let resolvedFilename stream.on('file', function (file) { resolvedFilename = file diff --git a/lib/dirList.js b/lib/dirList.js index 09c2fdfe..7a9cd3f6 100644 --- a/lib/dirList.js +++ b/lib/dirList.js @@ -149,7 +149,7 @@ const dirList = { route = path.normalize(path.join(route, '..')) } return { - href: path.join(prefix, route, entry.name).replace(/\\/gu, '/'), + href: encodeURI(path.join(prefix, route, entry.name).replace(/\\/gu, '/')), name: entry.name, stats: entry.stats, extendedInfo: entry.extendedInfo diff --git a/test/dir-list.test.js b/test/dir-list.test.js index b6e7b56e..7d42202b 100644 --- a/test/dir-list.test.js +++ b/test/dir-list.test.js @@ -154,7 +154,7 @@ t.test('dir list, custom options', t => { } const route = '/public/' - const content = { dirs: ['deep', 'shallow'], files: ['.example', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] } + const content = { dirs: ['deep', 'shallow'], files: ['.example', '100%.txt', 'a .md', 'foo.html', 'foobar.html', 'index.css', 'index.html'] } helper.arrange(t, options, (url) => { t.test(route, t => { @@ -205,7 +205,8 @@ t.test('dir list html format', t => {