From 34627a9edd9a1183a374967898b43b401d83d454 Mon Sep 17 00:00:00 2001 From: aerin-png <238979893+aerin-png@users.noreply.github.com> Date: Wed, 20 May 2026 13:57:45 +0300 Subject: [PATCH] Fix client upload file key sanitization --- .../payload/src/utilities/sanitizeFilename.ts | 7 +++++++ .../src/utilities/getFileKey.spec.ts | 15 +++++++++++++++ 2 files changed, 22 insertions(+) diff --git a/packages/payload/src/utilities/sanitizeFilename.ts b/packages/payload/src/utilities/sanitizeFilename.ts index a1dea683a98..1d99087014e 100644 --- a/packages/payload/src/utilities/sanitizeFilename.ts +++ b/packages/payload/src/utilities/sanitizeFilename.ts @@ -1,3 +1,5 @@ +import sanitize from 'sanitize-filename' + import { APIError } from '../errors/APIError.js' /** @@ -19,6 +21,11 @@ export function sanitizeFilename(filename: string): string { // eslint-disable-next-line no-control-regex sanitized = sanitized.replace(/[\x00-\x1f\x80-\x9f]/g, '') + const ext = sanitized.includes('.') ? sanitized.split('.').pop()?.split('?')[0] : '' + const baseFilename = sanitize(sanitized.substring(0, sanitized.lastIndexOf('.')) || sanitized) + + sanitized = `${baseFilename}${ext ? `.${ext}` : ''}` + if (!sanitized) { throw new APIError('Invalid filename', 400) } diff --git a/packages/plugin-cloud-storage/src/utilities/getFileKey.spec.ts b/packages/plugin-cloud-storage/src/utilities/getFileKey.spec.ts index 7ee6e8d2ea1..d6419c548e8 100644 --- a/packages/plugin-cloud-storage/src/utilities/getFileKey.spec.ts +++ b/packages/plugin-cloud-storage/src/utilities/getFileKey.spec.ts @@ -180,5 +180,20 @@ describe('getFileKey', () => { }) expect(result.fileKey).not.toContain('..') }) + + it('should sanitize filenames with trailing dots consistently with upload filename generation', () => { + const result = getFileKey({ + collectionPrefix: 'collection', + filename: 'My Photo...png', + useCompositePrefixes: false, + }) + + expect(result).toEqual({ + fileKey: 'collection/My Photo.png', + sanitizedCollectionPrefix: 'collection', + sanitizedDocPrefix: '', + sanitizedFilename: 'My Photo.png', + }) + }) }) })