From 4255589d8b9fdec6314d14503caa3f5d74662134 Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Tue, 26 Oct 2021 01:42:08 +0200 Subject: [PATCH 01/10] Image content disposition --- packages/next/package.json | 2 ++ packages/next/server/image-optimizer.ts | 6 +++++- yarn.lock | 6 ++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/packages/next/package.json b/packages/next/package.json index e884837d712fd..d8f952e6a1c7a 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -80,6 +80,7 @@ "chalk": "2.4.2", "chokidar": "3.5.1", "constants-browserify": "1.0.0", + "content-disposition": "0.5.3", "crypto-browserify": "3.12.0", "cssnano-simple": "3.0.0", "domain-browser": "4.19.0", @@ -166,6 +167,7 @@ "@types/babel__traverse": "7.11.0", "@types/ci-info": "2.0.0", "@types/compression": "0.0.36", + "@types/content-disposition": "0.5.4", "@types/content-type": "1.1.3", "@types/cookie": "0.3.3", "@types/cross-spawn": "6.0.0", diff --git a/packages/next/server/image-optimizer.ts b/packages/next/server/image-optimizer.ts index 8689b5e026d20..005513fe42a31 100644 --- a/packages/next/server/image-optimizer.ts +++ b/packages/next/server/image-optimizer.ts @@ -1,4 +1,5 @@ import { mediaType } from '@hapi/accept' +import contentDisposition from 'content-disposition' import { createHash } from 'crypto' import { createReadStream, promises } from 'fs' import { getOrientation, Orientation } from 'get-orientation' @@ -541,7 +542,10 @@ function setResponseHeaders( const fileName = getFileNameWithExtension(url, contentType) if (fileName) { - res.setHeader('Content-Disposition', `inline; filename="${fileName}"`) + res.setHeader( + 'Content-Disposition', + contentDisposition(fileName, { type: 'inline' }) + ) } res.setHeader('Content-Security-Policy', `script-src 'none'; sandbox;`) diff --git a/yarn.lock b/yarn.lock index 0202d94e4fdbf..0ba4d574d3660 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4443,6 +4443,11 @@ dependencies: "@types/node" "*" +"@types/content-disposition@0.5.4": + version "0.5.4" + resolved "https://registry.yarnpkg.com/@types/content-disposition/-/content-disposition-0.5.4.tgz#de48cf01c79c9f1560bcfd8ae43217ab028657f8" + integrity sha512-0mPF08jn9zYI0n0Q/Pnz7C4kThdSt+6LD4amsrYDDpgBfrVWa3TcCOxKX1zkGgYniGagRv8heN2cbh+CAn+uuQ== + "@types/content-type@1.1.3": version "1.1.3" resolved "https://registry.yarnpkg.com/@types/content-type/-/content-type-1.1.3.tgz#3688bd77fc12f935548eef102a4e34c512b03a07" @@ -7423,6 +7428,7 @@ contains-path@^0.1.0: content-disposition@0.5.3: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" + integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== dependencies: safe-buffer "5.1.2" From 41a949837556e8132b5c1ce2b6cb533fe78166a0 Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Wed, 27 Oct 2021 12:30:44 +0200 Subject: [PATCH 02/10] Add tests --- packages/next/package.json | 2 +- packages/next/server/image-optimizer.ts | 4 ++-- packages/next/taskfile.js | 11 +++++++++++ readme.md | 2 +- .../image-component/unicode/pages/index.js | 6 +++--- ...266\303\274\305\241\304\215\305\231\303\255.png" | Bin test/integration/image-optimizer/test/index.test.js | 2 +- 7 files changed, 19 insertions(+), 8 deletions(-) rename "test/integration/image-optimizer/app/public/\303\244\303\266\303\274.png" => "test/integration/image-optimizer/app/public/\303\244\303\266\303\274\305\241\304\215\305\231\303\255.png" (100%) diff --git a/packages/next/package.json b/packages/next/package.json index 6397f378c4f7c..f15931aa92acc 100644 --- a/packages/next/package.json +++ b/packages/next/package.json @@ -81,7 +81,6 @@ "chalk": "2.4.2", "chokidar": "3.5.1", "constants-browserify": "1.0.0", - "content-disposition": "0.5.3", "crypto-browserify": "3.12.0", "cssnano-simple": "3.0.0", "domain-browser": "4.19.0", @@ -207,6 +206,7 @@ "comment-json": "3.0.3", "compression": "1.7.4", "conf": "5.0.0", + "content-disposition": "0.5.3", "content-type": "1.0.4", "cookie": "0.4.1", "cross-spawn": "6.0.5", diff --git a/packages/next/server/image-optimizer.ts b/packages/next/server/image-optimizer.ts index 005513fe42a31..42a9c5a430b42 100644 --- a/packages/next/server/image-optimizer.ts +++ b/packages/next/server/image-optimizer.ts @@ -1,5 +1,5 @@ import { mediaType } from '@hapi/accept' -import contentDisposition from 'content-disposition' +import ContentDisposition from 'next/dist/compiled/content-disposition' import { createHash } from 'crypto' import { createReadStream, promises } from 'fs' import { getOrientation, Orientation } from 'get-orientation' @@ -544,7 +544,7 @@ function setResponseHeaders( if (fileName) { res.setHeader( 'Content-Disposition', - contentDisposition(fileName, { type: 'inline' }) + ContentDisposition(fileName, { type: 'inline' }) ) } diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js index ad4d1c9294ef0..cb627912df091 100644 --- a/packages/next/taskfile.js +++ b/packages/next/taskfile.js @@ -207,6 +207,16 @@ export async function ncc_content_type(task, opts) { .target('compiled/content-type') } // eslint-disable-next-line camelcase +externals['content-disposition'] = 'next/dist/compiled/content-disposition' +export async function ncc_content_disposition(task, opts) { + await task + .source( + opts.src || relative(__dirname, require.resolve('content-disposition')) + ) + .ncc({ packageName: 'content-disposition', externals }) + .target('compiled/content-disposition') +} +// eslint-disable-next-line camelcase externals['cookie'] = 'next/dist/compiled/cookie' export async function ncc_cookie(task, opts) { await task @@ -887,6 +897,7 @@ export async function ncc(task, opts) { 'ncc_comment_json', 'ncc_compression', 'ncc_conf', + 'ncc_content_disposition', 'ncc_content_type', 'ncc_cookie', 'ncc_cross_spawn', diff --git a/readme.md b/readme.md index 29e4f3032d3dd..50c7f2bd6a22e 120000 --- a/readme.md +++ b/readme.md @@ -1 +1 @@ -packages/next/README.md \ No newline at end of file +packages/next/README.md diff --git a/test/integration/image-component/unicode/pages/index.js b/test/integration/image-component/unicode/pages/index.js index bdc4ea840f65b..da3178409a3ec 100644 --- a/test/integration/image-component/unicode/pages/index.js +++ b/test/integration/image-component/unicode/pages/index.js @@ -1,16 +1,16 @@ import React from 'react' import Image from 'next/image' -import img from '../public/äöü.png' +import img from '../public/äöüščří.png' const Page = () => { return (

Unicode Image URL

- + diff --git "a/test/integration/image-optimizer/app/public/\303\244\303\266\303\274.png" "b/test/integration/image-optimizer/app/public/\303\244\303\266\303\274\305\241\304\215\305\231\303\255.png" similarity index 100% rename from "test/integration/image-optimizer/app/public/\303\244\303\266\303\274.png" rename to "test/integration/image-optimizer/app/public/\303\244\303\266\303\274\305\241\304\215\305\231\303\255.png" diff --git a/test/integration/image-optimizer/test/index.test.js b/test/integration/image-optimizer/test/index.test.js index 6460c604aedc7..519a27715f6d4 100644 --- a/test/integration/image-optimizer/test/index.test.js +++ b/test/integration/image-optimizer/test/index.test.js @@ -63,7 +63,7 @@ function runTests({ }) it('should handle non-ascii characters in image url', async () => { - const query = { w, q: 90, url: '/äöü.png' } + const query = { w, q: 90, url: '/äöüščří.png' } const res = await fetchViaHTTP(appPort, '/_next/image', query, {}) expect(res.status).toBe(200) }) From 4890abdbd049b3ef42efc64ad151d52e807673bd Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Wed, 27 Oct 2021 12:36:40 +0200 Subject: [PATCH 03/10] Fixed import --- packages/next/server/image-optimizer.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/next/server/image-optimizer.ts b/packages/next/server/image-optimizer.ts index 42a9c5a430b42..782a8be1aa179 100644 --- a/packages/next/server/image-optimizer.ts +++ b/packages/next/server/image-optimizer.ts @@ -1,5 +1,4 @@ import { mediaType } from '@hapi/accept' -import ContentDisposition from 'next/dist/compiled/content-disposition' import { createHash } from 'crypto' import { createReadStream, promises } from 'fs' import { getOrientation, Orientation } from 'get-orientation' @@ -7,6 +6,7 @@ import imageSizeOf from 'image-size' import { IncomingMessage, ServerResponse } from 'http' // @ts-ignore no types for is-animated import isAnimated from 'next/dist/compiled/is-animated' +import contentDisposition from 'next/dist/compiled/content-disposition' import { join } from 'path' import Stream from 'stream' import nodeUrl, { UrlWithParsedQuery } from 'url' @@ -544,7 +544,7 @@ function setResponseHeaders( if (fileName) { res.setHeader( 'Content-Disposition', - ContentDisposition(fileName, { type: 'inline' }) + contentDisposition(fileName, { type: 'inline' }) ) } From 182215f01071578134b45b2f0a70a710a59b805c Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Wed, 27 Oct 2021 12:55:21 +0200 Subject: [PATCH 04/10] Add TS types --- packages/next/types/misc.d.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/next/types/misc.d.ts b/packages/next/types/misc.d.ts index dd0a9cd27dff4..4ed3782c94494 100644 --- a/packages/next/types/misc.d.ts +++ b/packages/next/types/misc.d.ts @@ -89,6 +89,10 @@ declare module 'next/dist/compiled/conf' { import m from 'conf' export = m } +declare module 'next/dist/compiled/content-disposition' { + import m from 'content-disposition' + export = m +} declare module 'next/dist/compiled/content-type' { import m from 'content-type' export = m From 4bd86d4aa3c890d11213887d3e5296fa4f49421f Mon Sep 17 00:00:00 2001 From: Steven Date: Wed, 27 Oct 2021 19:11:13 -0400 Subject: [PATCH 05/10] Revert readme.md --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 50c7f2bd6a22e..29e4f3032d3dd 120000 --- a/readme.md +++ b/readme.md @@ -1 +1 @@ -packages/next/README.md +packages/next/README.md \ No newline at end of file From 936957c2565fb538d55228a7f4dc4a27464a0915 Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Thu, 28 Oct 2021 02:05:21 +0200 Subject: [PATCH 06/10] Alphabet sorting --- packages/next/taskfile.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/packages/next/taskfile.js b/packages/next/taskfile.js index 1c1db9cc456f0..780de7c96a3ce 100644 --- a/packages/next/taskfile.js +++ b/packages/next/taskfile.js @@ -199,14 +199,6 @@ export async function ncc_conf(task, opts) { .target('compiled/conf') } // eslint-disable-next-line camelcase -externals['content-type'] = 'next/dist/compiled/content-type' -export async function ncc_content_type(task, opts) { - await task - .source(opts.src || relative(__dirname, require.resolve('content-type'))) - .ncc({ packageName: 'content-type', externals }) - .target('compiled/content-type') -} -// eslint-disable-next-line camelcase externals['content-disposition'] = 'next/dist/compiled/content-disposition' export async function ncc_content_disposition(task, opts) { await task @@ -217,6 +209,14 @@ export async function ncc_content_disposition(task, opts) { .target('compiled/content-disposition') } // eslint-disable-next-line camelcase +externals['content-type'] = 'next/dist/compiled/content-type' +export async function ncc_content_type(task, opts) { + await task + .source(opts.src || relative(__dirname, require.resolve('content-type'))) + .ncc({ packageName: 'content-type', externals }) + .target('compiled/content-type') +} +// eslint-disable-next-line camelcase externals['cookie'] = 'next/dist/compiled/cookie' export async function ncc_cookie(task, opts) { await task From 6c72dad85870be1be57c7ee62374c4d091672c10 Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Fri, 29 Oct 2021 13:07:14 +0200 Subject: [PATCH 07/10] Compile `content-disposition` --- .../next/compiled/content-disposition/LICENSE | 22 +++++++++++++++++++ .../compiled/content-disposition/index.js | 1 + .../compiled/content-disposition/package.json | 1 + 3 files changed, 24 insertions(+) create mode 100644 packages/next/compiled/content-disposition/LICENSE create mode 100644 packages/next/compiled/content-disposition/index.js create mode 100644 packages/next/compiled/content-disposition/package.json diff --git a/packages/next/compiled/content-disposition/LICENSE b/packages/next/compiled/content-disposition/LICENSE new file mode 100644 index 0000000000000..84441fbb57092 --- /dev/null +++ b/packages/next/compiled/content-disposition/LICENSE @@ -0,0 +1,22 @@ +(The MIT License) + +Copyright (c) 2014-2017 Douglas Christopher Wilson + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +'Software'), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, +TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE +SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/packages/next/compiled/content-disposition/index.js b/packages/next/compiled/content-disposition/index.js new file mode 100644 index 0000000000000..cb908fd8853e3 --- /dev/null +++ b/packages/next/compiled/content-disposition/index.js @@ -0,0 +1 @@ +module.exports=(()=>{var r={565:(r,e,t)=>{"use strict";r.exports=contentDisposition;r.exports.parse=parse;var a=t(622).basename;var n=t(505).Buffer;var o=/[\x00-\x20"'()*,/:;<=>?@[\\\]{}\x7f]/g;var i=/%[0-9A-Fa-f]{2}/;var f=/%([0-9A-Fa-f]{2})/g;var s=/[^\x20-\x7e\xa0-\xff]/g;var p=/\\([\u0000-\u007f])/g;var u=/([\\"])/g;var c=/;[\x09\x20]*([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*=[\x09\x20]*("(?:[\x20!\x23-\x5b\x5d-\x7e\x80-\xff]|\\[\x20-\x7e])*"|[!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*/g;var v=/^[\x20-\x7e\x80-\xff]+$/;var x=/^[!#$%&'*+.0-9A-Z^_`a-z|~-]+$/;var l=/^([A-Za-z0-9!#$%&+\-^_`{}~]+)'(?:[A-Za-z]{2,3}(?:-[A-Za-z]{3}){0,3}|[A-Za-z]{4,8}|)'((?:%[0-9A-Fa-f]{2}|[A-Za-z0-9!#$&+.^_`|~-])+)$/;var w=/^([!#$%&'*+.0-9A-Z^_`a-z|~-]+)[\x09\x20]*(?:$|;)/;function contentDisposition(r,e){var t=e||{};var a=t.type||"attachment";var n=createparams(r,t.fallback);return format(new ContentDisposition(a,n))}function createparams(r,e){if(r===undefined){return}var t={};if(typeof r!=="string"){throw new TypeError("filename must be a string")}if(e===undefined){e=true}if(typeof e!=="string"&&typeof e!=="boolean"){throw new TypeError("fallback must be a string or boolean")}if(typeof e==="string"&&s.test(e)){throw new TypeError("fallback must be ISO-8859-1 string")}var n=a(r);var o=v.test(n);var f=typeof e!=="string"?e&&getlatin1(n):a(e);var p=typeof f==="string"&&f!==n;if(p||!o||i.test(n)){t["filename*"]=n}if(o||p){t.filename=p?f:n}return t}function format(r){var e=r.parameters;var t=r.type;if(!t||typeof t!=="string"||!x.test(t)){throw new TypeError("invalid type")}var a=String(t).toLowerCase();if(e&&typeof e==="object"){var n;var o=Object.keys(e).sort();for(var i=0;i{var a=t(293);var n=a.Buffer;function copyProps(r,e){for(var t in r){e[t]=r[t]}}if(n.from&&n.alloc&&n.allocUnsafe&&n.allocUnsafeSlow){r.exports=a}else{copyProps(a,e);e.Buffer=SafeBuffer}function SafeBuffer(r,e,t){return n(r,e,t)}copyProps(n,SafeBuffer);SafeBuffer.from=function(r,e,t){if(typeof r==="number"){throw new TypeError("Argument must not be a number")}return n(r,e,t)};SafeBuffer.alloc=function(r,e,t){if(typeof r!=="number"){throw new TypeError("Argument must be a number")}var a=n(r);if(e!==undefined){if(typeof t==="string"){a.fill(e,t)}else{a.fill(e)}}else{a.fill(0)}return a};SafeBuffer.allocUnsafe=function(r){if(typeof r!=="number"){throw new TypeError("Argument must be a number")}return n(r)};SafeBuffer.allocUnsafeSlow=function(r){if(typeof r!=="number"){throw new TypeError("Argument must be a number")}return a.SlowBuffer(r)}},293:r=>{"use strict";r.exports=require("buffer")},622:r=>{"use strict";r.exports=require("path")}};var e={};function __nccwpck_require__(t){if(e[t]){return e[t].exports}var a=e[t]={exports:{}};var n=true;try{r[t](a,a.exports,__nccwpck_require__);n=false}finally{if(n)delete e[t]}return a.exports}__nccwpck_require__.ab=__dirname+"/";return __nccwpck_require__(565)})(); \ No newline at end of file diff --git a/packages/next/compiled/content-disposition/package.json b/packages/next/compiled/content-disposition/package.json new file mode 100644 index 0000000000000..f5c3c0e8108f2 --- /dev/null +++ b/packages/next/compiled/content-disposition/package.json @@ -0,0 +1 @@ +{"name":"content-disposition","main":"index.js","author":"Douglas Christopher Wilson ","license":"MIT"} From 15e5e76bf9c60c49f0d26cd5298407d74202ad64 Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Fri, 29 Oct 2021 15:36:40 +0200 Subject: [PATCH 08/10] Rename for tests --- ...266\303\274\305\241\304\215\305\231\303\255.png" | Bin 1 file changed, 0 insertions(+), 0 deletions(-) rename "test/integration/image-component/unicode/public/\303\244\303\266\303\274.png" => "test/integration/image-component/unicode/public/\303\244\303\266\303\274\305\241\304\215\305\231\303\255.png" (100%) diff --git "a/test/integration/image-component/unicode/public/\303\244\303\266\303\274.png" "b/test/integration/image-component/unicode/public/\303\244\303\266\303\274\305\241\304\215\305\231\303\255.png" similarity index 100% rename from "test/integration/image-component/unicode/public/\303\244\303\266\303\274.png" rename to "test/integration/image-component/unicode/public/\303\244\303\266\303\274\305\241\304\215\305\231\303\255.png" From 4e4125519571d1e839a20bcc6e8e592c47cb92ca Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Mon, 1 Nov 2021 21:31:50 +0100 Subject: [PATCH 09/10] Fix test --- .../image-component/unicode/test/index.test.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/test/integration/image-component/unicode/test/index.test.js b/test/integration/image-component/unicode/test/index.test.js index ee8c84e67b04f..4c288bd4fbea6 100644 --- a/test/integration/image-component/unicode/test/index.test.js +++ b/test/integration/image-component/unicode/test/index.test.js @@ -20,7 +20,9 @@ let browser function runTests() { it('should load static unicode image', async () => { const src = await browser.elementById('static').getAttribute('src') - expect(src).toMatch(/_next%2Fstatic%2Fmedia%2F%C3%A4%C3%B6%C3%BC(.+)png/) + expect(src).toMatch( + /_next%2Fstatic%2Fmedia%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%ADC(.+)png/ + ) const fullSrc = new URL(src, `http://localhost:${appPort}`) const res = await fetch(fullSrc) expect(res.status).toBe(200) @@ -28,7 +30,9 @@ function runTests() { it('should load internal unicode image', async () => { const src = await browser.elementById('internal').getAttribute('src') - expect(src).toMatch('/_next/image?url=%2F%C3%A4%C3%B6%C3%BC.png') + expect(src).toMatch( + '/_next/image?url=%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%ADC.png' + ) const fullSrc = new URL(src, `http://localhost:${appPort}`) const res = await fetch(fullSrc) expect(res.status).toBe(200) @@ -37,7 +41,7 @@ function runTests() { it('should load external unicode image', async () => { const src = await browser.elementById('external').getAttribute('src') expect(src).toMatch( - '/_next/image?url=https%3A%2F%2Fimage-optimization-test.vercel.app%2F%C3%A4%C3%B6%C3%BC.png' + '/_next/image?url=https%3A%2F%2Fimage-optimization-test.vercel.app%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%ADC.png' ) const fullSrc = new URL(src, `http://localhost:${appPort}`) const res = await fetch(fullSrc) From 8e13629639be5823b87f414682dd576f3daca02a Mon Sep 17 00:00:00 2001 From: Pavel Ihm Date: Mon, 1 Nov 2021 23:06:06 +0100 Subject: [PATCH 10/10] Fix accidentally added letter --- test/integration/image-component/unicode/test/index.test.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/integration/image-component/unicode/test/index.test.js b/test/integration/image-component/unicode/test/index.test.js index 4c288bd4fbea6..9c686c50ab448 100644 --- a/test/integration/image-component/unicode/test/index.test.js +++ b/test/integration/image-component/unicode/test/index.test.js @@ -21,7 +21,7 @@ function runTests() { it('should load static unicode image', async () => { const src = await browser.elementById('static').getAttribute('src') expect(src).toMatch( - /_next%2Fstatic%2Fmedia%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%ADC(.+)png/ + /_next%2Fstatic%2Fmedia%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%AD(.+)png/ ) const fullSrc = new URL(src, `http://localhost:${appPort}`) const res = await fetch(fullSrc) @@ -31,7 +31,7 @@ function runTests() { it('should load internal unicode image', async () => { const src = await browser.elementById('internal').getAttribute('src') expect(src).toMatch( - '/_next/image?url=%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%ADC.png' + '/_next/image?url=%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%AD.png' ) const fullSrc = new URL(src, `http://localhost:${appPort}`) const res = await fetch(fullSrc) @@ -41,7 +41,7 @@ function runTests() { it('should load external unicode image', async () => { const src = await browser.elementById('external').getAttribute('src') expect(src).toMatch( - '/_next/image?url=https%3A%2F%2Fimage-optimization-test.vercel.app%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%ADC.png' + '/_next/image?url=https%3A%2F%2Fimage-optimization-test.vercel.app%2F%C3%A4%C3%B6%C3%BC%C5%A1%C4%8D%C5%99%C3%AD.png' ) const fullSrc = new URL(src, `http://localhost:${appPort}`) const res = await fetch(fullSrc)