@samitouri / QOSami-HFS / commits / b9889b16

better error code for upload with illegal uri

Massimo Melina committed Jan 24, 2026 at 11:59 UTC b9889b16edf5e7548577137c0f80d59063543eb5
2 files changed +6 -2
src/serveGuiAndSharedFiles.ts
+5 -2
@@ -18,7 +18,10 @@ import { preventAdminAccess, favicon } from './adminApis'
18 import { serveGuiFiles } from './serveGuiFiles'
19 import mount from 'koa-mount'
20 import { baseUrl } from './listen'
21 -import { asyncGeneratorToReadable, filterMapGenerator, isValidFileName, loadFileCached, pathEncode, try_ } from './misc'
21 +import {
22 + asyncGeneratorToReadable, filterMapGenerator, isValidFileName, loadFileCached, pathEncode, safeDecodeURIComponent,
23 + try_,
24 +} from './misc'
25 import XXH from 'xxhashjs'
26 import fs from 'fs'
27 import { rm } from 'fs/promises'
@@ -59,7 +62,7 @@ export const serveGuiAndSharedFiles: Koa.Middleware = async (ctx, next) => {
62 const { get } = ctx.query
63 const getUploadTempHash = get === UPLOAD_TEMP_HASH
64 if (ctx.method === 'PUT' || getUploadTempHash) { // PUT is what you get with `curl -T file url/`
62 - const decPath = decodeURIComponent(path)
65 + const decPath = safeDecodeURIComponent(path, '')
66 const fn = basename(decPath)
67 const folderUri = pathEncode(dirname(decPath)) // re-encode to get readable urls
68 const folder = await urlToNode(folderUri, ctx, vfs, true)
tests/test.ts
+1
@@ -276,6 +276,7 @@ describe('after-login', () => {
276 test('move.dest is file', reqApi('move_files', { uri_from: [UPLOAD_DEST], uri_to: UPLOAD_DEST }, 405))
277 test('upload.dot name', reqUpload(`${UPLOAD_ROOT}%2e`, 418))
278 test('upload.unreadable', reqUpload(`${UPLOAD_ROOT}%0a`, 418))
279 + test('upload.bad encoding', reqUpload(`${UPLOAD_ROOT}%E0%A4%A`, 404))
280 test('upload.temp hash traversal', req(`${UPLOAD_ROOT}%2e%2e?get=${UPLOAD_TEMP_HASH}`, 404))
281 test('upload.temp hash requires auth', async () => {
282 const rel = `${UPLOAD_DIR}/partial.png`