forbid uploading unreadable chars

Massimo Melina committed Jan 19, 2026 at 11:47 UTC 5325dc35c820c5e0411d79c399a8285cff03ac0d
2 files changed +3 -1
src/util-files.ts
+2 -1
@@ -155,8 +155,9 @@ export async function createSafeWriteStream(path: string, options?: Parameters<t
155 })
156 }
157
158 -export function isValidFileName(name: string) {
158 +export function isValidFileName(name: string, acceptUnreadable=false) {
159 return name !== '.' && !(IS_WINDOWS ? /[/:"*?<>|\\]/ : /\//).test(name) && !hasDirTraversal(name)
160 + && (acceptUnreadable || !/[\u0000-\u001F\u007F]/.test(name))
161 }
162
163 export function exists(path: string) {
tests/test.ts
+1
@@ -255,6 +255,7 @@ describe('after-login', () => {
255 test('upload.never', reqUpload('/random', 403))
256 test('upload.ok', reqUpload(UPLOAD_DEST, 200))
257 test('upload.dot name', reqUpload(`${UPLOAD_ROOT}%2e`, 418))
258 + test('upload.unreadable', reqUpload(`${UPLOAD_ROOT}%0a`, 418))
259 test('upload.temp hash traversal', req(`${UPLOAD_ROOT}%2e%2e?get=${UPLOAD_TEMP_HASH}`, 404))
260 test('upload.temp hash requires auth', async () => {
261 const rel = `${UPLOAD_DIR}/partial.png`