fix(next/image)!: error when src
has leading or trailing space (#65637)
BREAKING CHANGE: Using the built-in image optimization API, the URL is parsed with `new URL()` constructor which automatically trims spaces. However, the developer may choose a 3rd party image optimization API via `loader` or `loaderFile` (or perhaps a deployment platform that has its own built in loader), so we shouldn't assume the API will parse the URL in the same way as [WHATWG](https://url.spec.whatwg.org/#:~:text=If%20input%20contains%20any%20leading%20or%20trailing%20C0%20control%20or%20space%2C%20invalid%2DURL%2Dunit%20validation%20error.). While we could trim on the client, its probably best to fail fast and let the developer make a conscience decision if a trailing space should be removed or remain (by explicitly using `%20`).
This commit is contained in:
parent
46f89b095a
commit
f169b08901
7 changed files with 88 additions and 0 deletions
|
@ -465,6 +465,18 @@ export function getImgProps(
|
|||
`Image with src "${src}" has invalid "height" property. Expected a numeric value in pixels but received "${height}".`
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line no-control-regex
|
||||
if (/^[\x00-\x20]/.test(src)) {
|
||||
throw new Error(
|
||||
`Image with src "${src}" cannot start with a space or control character. Use src.trimStart() to remove it or encodeURIComponent(src) to keep it.`
|
||||
)
|
||||
}
|
||||
// eslint-disable-next-line no-control-regex
|
||||
if (/[\x00-\x20]$/.test(src)) {
|
||||
throw new Error(
|
||||
`Image with src "${src}" cannot end with a space or control character. Use src.trimEnd() to remove it or encodeURIComponent(src) to keep it.`
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!VALID_LOADING_VALUES.includes(loading)) {
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
<h2>Invalid src with leading space</h2>
|
||||
<Image src=" /test.jpg" width={200} height={200} />
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
<h2>Invalid src with trailing space</h2>
|
||||
<Image src="/test.png " width={200} height={200} />
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -915,6 +915,22 @@ function runTests(mode) {
|
|||
)
|
||||
})
|
||||
|
||||
it('should show invalid src with leading space', async () => {
|
||||
const browser = await webdriver(appPort, '/invalid-src-leading-space')
|
||||
expect(await hasRedbox(browser)).toBe(true)
|
||||
expect(await getRedboxHeader(browser)).toContain(
|
||||
'Image with src " /test.jpg" cannot start with a space or control character.'
|
||||
)
|
||||
})
|
||||
|
||||
it('should show invalid src with trailing space', async () => {
|
||||
const browser = await webdriver(appPort, '/invalid-src-trailing-space')
|
||||
expect(await hasRedbox(browser)).toBe(true)
|
||||
expect(await getRedboxHeader(browser)).toContain(
|
||||
'Image with src "/test.png " cannot end with a space or control character.'
|
||||
)
|
||||
})
|
||||
|
||||
it('should show error when string src and placeholder=blur and blurDataURL is missing', async () => {
|
||||
const browser = await webdriver(appPort, '/invalid-placeholder-blur')
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
<h2>Invalid src with leading space</h2>
|
||||
<Image src=" /test.jpg" width={200} height={200} />
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
import React from 'react'
|
||||
import Image from 'next/image'
|
||||
|
||||
export default function Page() {
|
||||
return (
|
||||
<div>
|
||||
<h2>Invalid src with trailing space</h2>
|
||||
<Image src="/test.png " width={200} height={200} />
|
||||
</div>
|
||||
)
|
||||
}
|
|
@ -916,6 +916,22 @@ function runTests(mode) {
|
|||
)
|
||||
})
|
||||
|
||||
it('should show invalid src with leading space', async () => {
|
||||
const browser = await webdriver(appPort, '/invalid-src-leading-space')
|
||||
expect(await hasRedbox(browser)).toBe(true)
|
||||
expect(await getRedboxHeader(browser)).toContain(
|
||||
'Image with src " /test.jpg" cannot start with a space or control character.'
|
||||
)
|
||||
})
|
||||
|
||||
it('should show invalid src with trailing space', async () => {
|
||||
const browser = await webdriver(appPort, '/invalid-src-trailing-space')
|
||||
expect(await hasRedbox(browser)).toBe(true)
|
||||
expect(await getRedboxHeader(browser)).toContain(
|
||||
'Image with src "/test.png " cannot end with a space or control character.'
|
||||
)
|
||||
})
|
||||
|
||||
it('should show error when string src and placeholder=blur and blurDataURL is missing', async () => {
|
||||
const browser = await webdriver(appPort, '/invalid-placeholder-blur')
|
||||
|
||||
|
|
Loading…
Reference in a new issue