fix: image optimization content-type (#46219)
Upstream images can have any arbitrary `content-type` header so this PR normalizes the value before checking it.
This commit is contained in:
parent
b8837ad636
commit
0b563e86de
5 changed files with 63 additions and 11 deletions
|
@ -573,17 +573,21 @@ export async function imageOptimizer(
|
|||
}
|
||||
}
|
||||
|
||||
if (upstreamType === SVG && !nextConfig.images.dangerouslyAllowSVG) {
|
||||
console.error(
|
||||
`The requested resource "${href}" has type "${upstreamType}" but dangerouslyAllowSVG is disabled`
|
||||
)
|
||||
throw new ImageError(
|
||||
400,
|
||||
'"url" parameter is valid but image type is not allowed'
|
||||
)
|
||||
}
|
||||
|
||||
if (upstreamType) {
|
||||
upstreamType = upstreamType.toLowerCase().trim()
|
||||
|
||||
if (
|
||||
upstreamType.startsWith('image/svg') &&
|
||||
!nextConfig.images.dangerouslyAllowSVG
|
||||
) {
|
||||
console.error(
|
||||
`The requested resource "${href}" has type "${upstreamType}" but dangerouslyAllowSVG is disabled`
|
||||
)
|
||||
throw new ImageError(
|
||||
400,
|
||||
'"url" parameter is valid but image type is not allowed'
|
||||
)
|
||||
}
|
||||
const vector = VECTOR_TYPES.includes(upstreamType)
|
||||
const animate =
|
||||
ANIMATABLE_TYPES.includes(upstreamType) && isAnimated(upstreamBuffer)
|
||||
|
@ -591,7 +595,7 @@ export async function imageOptimizer(
|
|||
if (vector || animate) {
|
||||
return { buffer: upstreamBuffer, contentType: upstreamType, maxAge }
|
||||
}
|
||||
if (!upstreamType.startsWith('image/')) {
|
||||
if (!upstreamType.startsWith('image/') || upstreamType.includes(',')) {
|
||||
console.error(
|
||||
"The requested resource isn't a valid image for",
|
||||
href,
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
export default function handler(_req, res) {
|
||||
res.setHeader('Content-Type', 'application/svg+xml')
|
||||
res.end(
|
||||
`<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="60" height="60"><text x="20" y="30">hi</text></svg>`
|
||||
)
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export default function handler(_req, res) {
|
||||
res.setHeader('Content-Type', 'image/foo, text/html')
|
||||
res.end(
|
||||
`<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="60" height="60"><text x="20" y="30">hi</text></svg>`
|
||||
)
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
export default function handler(_req, res) {
|
||||
res.setHeader('Content-Type', 'image/SVG+XML')
|
||||
res.end(
|
||||
`<svg version="1.0" xmlns="http://www.w3.org/2000/svg" width="60" height="60"><text x="20" y="30">hi</text></svg>`
|
||||
)
|
||||
}
|
|
@ -264,6 +264,36 @@ export function runTests(ctx) {
|
|||
expect(res.status).toBe(400)
|
||||
expect(await res.text()).toContain('valid but image type is not allowed')
|
||||
})
|
||||
|
||||
it('should not allow svg with application header', async () => {
|
||||
const query = { w: ctx.w, q: 45, url: '/api/application.svg' }
|
||||
const opts = { headers: { accept: 'image/webp' } }
|
||||
const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, opts)
|
||||
expect(res.status).toBe(400)
|
||||
expect(await res.text()).toContain(
|
||||
"The requested resource isn't a valid image"
|
||||
)
|
||||
})
|
||||
|
||||
it('should not allow svg with comma header', async () => {
|
||||
const query = { w: ctx.w, q: 55, url: '/api/comma.svg' }
|
||||
const opts = { headers: { accept: 'image/webp' } }
|
||||
const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, opts)
|
||||
expect(res.status).toBe(400)
|
||||
expect(await res.text()).toContain(
|
||||
"The requested resource isn't a valid image"
|
||||
)
|
||||
})
|
||||
|
||||
it('should not allow svg with uppercase header', async () => {
|
||||
const query = { w: ctx.w, q: 65, url: '/api/uppercase.svg' }
|
||||
const opts = { headers: { accept: 'image/webp' } }
|
||||
const res = await fetchViaHTTP(ctx.appPort, '/_next/image', query, opts)
|
||||
expect(res.status).toBe(400)
|
||||
expect(await res.text()).toContain(
|
||||
'"url" parameter is valid but image type is not allowed'
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
it('should maintain ico format', async () => {
|
||||
|
|
Loading…
Reference in a new issue