diff --git a/packages/next/src/shared/lib/get-img-props.ts b/packages/next/src/shared/lib/get-img-props.ts
index f0fcad0cde..cdd0cf03a6 100644
--- a/packages/next/src/shared/lib/get-img-props.ts
+++ b/packages/next/src/shared/lib/get-img-props.ts
@@ -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)) {
diff --git a/test/integration/next-image-new/app-dir/app/invalid-src-leading-space/page.js b/test/integration/next-image-new/app-dir/app/invalid-src-leading-space/page.js
new file mode 100644
index 0000000000..b7682cbc7a
--- /dev/null
+++ b/test/integration/next-image-new/app-dir/app/invalid-src-leading-space/page.js
@@ -0,0 +1,11 @@
+import React from 'react'
+import Image from 'next/image'
+
+export default function Page() {
+ return (
+
+
Invalid src with leading space
+
+
+ )
+}
diff --git a/test/integration/next-image-new/app-dir/app/invalid-src-trailing-space/page.js b/test/integration/next-image-new/app-dir/app/invalid-src-trailing-space/page.js
new file mode 100644
index 0000000000..279729491a
--- /dev/null
+++ b/test/integration/next-image-new/app-dir/app/invalid-src-trailing-space/page.js
@@ -0,0 +1,11 @@
+import React from 'react'
+import Image from 'next/image'
+
+export default function Page() {
+ return (
+
+
Invalid src with trailing space
+
+
+ )
+}
diff --git a/test/integration/next-image-new/app-dir/test/index.test.ts b/test/integration/next-image-new/app-dir/test/index.test.ts
index ebff18725d..25a8250144 100644
--- a/test/integration/next-image-new/app-dir/test/index.test.ts
+++ b/test/integration/next-image-new/app-dir/test/index.test.ts
@@ -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')
diff --git a/test/integration/next-image-new/default/pages/invalid-src-leading-space.js b/test/integration/next-image-new/default/pages/invalid-src-leading-space.js
new file mode 100644
index 0000000000..b7682cbc7a
--- /dev/null
+++ b/test/integration/next-image-new/default/pages/invalid-src-leading-space.js
@@ -0,0 +1,11 @@
+import React from 'react'
+import Image from 'next/image'
+
+export default function Page() {
+ return (
+
+
Invalid src with leading space
+
+
+ )
+}
diff --git a/test/integration/next-image-new/default/pages/invalid-src-trailing-space.js b/test/integration/next-image-new/default/pages/invalid-src-trailing-space.js
new file mode 100644
index 0000000000..279729491a
--- /dev/null
+++ b/test/integration/next-image-new/default/pages/invalid-src-trailing-space.js
@@ -0,0 +1,11 @@
+import React from 'react'
+import Image from 'next/image'
+
+export default function Page() {
+ return (
+
+
Invalid src with trailing space
+
+
+ )
+}
diff --git a/test/integration/next-image-new/default/test/index.test.ts b/test/integration/next-image-new/default/test/index.test.ts
index 539b1a8111..7796fc98a0 100644
--- a/test/integration/next-image-new/default/test/index.test.ts
+++ b/test/integration/next-image-new/default/test/index.test.ts
@@ -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')