Skip to content

Commit 015b363

Browse files
authored
fix: should exclude svg files from file buffer mime validation (#14751)
### What? Fix bug of `svg` files throwing an error when `mimeTypes: ['image/*']` is set. ### Why? We recently added an additional mime type check on the buffer however the `file-buffer` package that we use to detect file type does not support svgs. ### How? Updates `expectsDetectableType` logic to exclude svgs. Fixes #14743
1 parent a07cf47 commit 015b363

File tree

2 files changed

+42
-14
lines changed

2 files changed

+42
-14
lines changed

packages/payload/src/uploads/checkFileRestrictions.ts

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -65,13 +65,20 @@ export const checkFileRestrictions = async ({
6565
? (uploadConfig as { allowRestrictedFileTypes?: boolean }).allowRestrictedFileTypes
6666
: false
6767

68-
const expectsDetectableType = configMimeTypes.some(
69-
(type) =>
70-
type.startsWith('image/') ||
71-
type === 'application/pdf' ||
72-
type.startsWith('video/') ||
73-
type.startsWith('audio/'),
74-
)
68+
const expectsDetectableType = (mimeType: string): boolean => {
69+
const textBasedTypes = ['/svg', 'image/svg+xml', 'image/x-xbitmap', 'image/x-xpixmap']
70+
71+
if (textBasedTypes.includes(mimeType)) {
72+
return false
73+
}
74+
75+
return (
76+
mimeType.startsWith('image/') ||
77+
mimeType.startsWith('video/') ||
78+
mimeType.startsWith('audio/') ||
79+
mimeType === 'application/pdf'
80+
)
81+
}
7582

7683
// Skip validation if `allowRestrictedFileTypes` is true
7784
if (allowRestrictedFileTypes) {
@@ -81,20 +88,23 @@ export const checkFileRestrictions = async ({
8188
// Secondary mimetype check to assess file type from buffer
8289
if (configMimeTypes.length > 0) {
8390
let detected = await fileTypeFromBuffer(file.data)
84-
85-
if (!detected && expectsDetectableType && !useTempFiles) {
86-
errors.push(`File buffer returned no detectable MIME type.`)
87-
}
91+
const typeFromExtension = file.name.split('.').pop() || ''
8892

8993
// Handle SVG files that are detected as XML due to <?xml declarations
9094
if (
9195
detected?.mime === 'application/xml' &&
9296
configMimeTypes.some(
9397
(type) => type.includes('image/') && (type.includes('svg') || type === 'image/*'),
94-
) &&
95-
detectSvgFromXml(file.data)
98+
)
9699
) {
97-
detected = { ext: 'svg' as any, mime: 'image/svg+xml' as any }
100+
const isSvg = detectSvgFromXml(file.data)
101+
if (isSvg) {
102+
detected = { ext: 'svg' as any, mime: 'image/svg+xml' as any }
103+
}
104+
}
105+
106+
if (!detected && expectsDetectableType(typeFromExtension) && !useTempFiles) {
107+
errors.push(`File buffer returned no detectable MIME type.`)
98108
}
99109

100110
const passesMimeTypeCheck = detected?.mime && validateMimeType(detected.mime, configMimeTypes)

test/uploads/int.spec.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,24 @@ describe('Collections - Uploads', () => {
151151
expect(doc.height).toBeDefined()
152152
})
153153

154+
it('should upload svg in an image mimetype restricted collection', async () => {
155+
const filePath = path.join(dirname, './image.svg')
156+
const formData = new FormData()
157+
const { file, handle } = await createStreamableFile(filePath)
158+
formData.append('file', file)
159+
160+
const response = await restClient.POST(`/any-images`, {
161+
body: formData,
162+
file,
163+
})
164+
165+
const { doc } = await response.json()
166+
await handle.close()
167+
168+
expect(response.status).toBe(201)
169+
expect(doc.mimeType).toEqual('image/svg+xml')
170+
})
171+
154172
it('should have valid image url', async () => {
155173
const formData = new FormData()
156174
const filePath = path.join(dirname, './image.svg')

0 commit comments

Comments
 (0)