From 49fd97597cd27992ae46e96c475353ab8da343f3 Mon Sep 17 00:00:00 2001 From: Marcus-Rise Date: Sat, 12 Nov 2022 10:32:42 +0400 Subject: [PATCH 1/3] #42398 fix(app-render): escape segment value --- packages/next/server/app-render.tsx | 8 ++- .../app/[slug]/page.js | 12 ++++ .../app/layout.js | 7 +++ .../app-dir-prefetch-non-iso-url/app/page.js | 18 ++++++ .../index.test.ts | 58 +++++++++++++++++++ .../next.config.js | 6 ++ 6 files changed, 108 insertions(+), 1 deletion(-) create mode 100644 test/production/app-dir-prefetch-non-iso-url/app/[slug]/page.js create mode 100644 test/production/app-dir-prefetch-non-iso-url/app/layout.js create mode 100644 test/production/app-dir-prefetch-non-iso-url/app/page.js create mode 100644 test/production/app-dir-prefetch-non-iso-url/index.test.ts create mode 100644 test/production/app-dir-prefetch-non-iso-url/next.config.js diff --git a/packages/next/server/app-render.tsx b/packages/next/server/app-render.tsx index 2aca0f414f8a0f7..a05b37d6d9e3473 100644 --- a/packages/next/server/app-render.tsx +++ b/packages/next/server/app-render.tsx @@ -855,7 +855,13 @@ export async function renderToHTMLOrFlight( } const key = segmentParam.param - const value = pathParams[key] + let value = pathParams[key] + + if (Array.isArray(value)) { + value = value.map((i) => encodeURIComponent(i)) + } else if (typeof value === 'string') { + value = encodeURIComponent(value) + } if (!value) { // Handle case where optional catchall does not have a value, e.g. `/dashboard/[...slug]` when requesting `/dashboard` diff --git a/test/production/app-dir-prefetch-non-iso-url/app/[slug]/page.js b/test/production/app-dir-prefetch-non-iso-url/app/[slug]/page.js new file mode 100644 index 000000000000000..90ee69c678574b3 --- /dev/null +++ b/test/production/app-dir-prefetch-non-iso-url/app/[slug]/page.js @@ -0,0 +1,12 @@ +export default function Slug(props) { + return ( + <> +

/[slug]

+

{JSON.stringify(props)}

+ + ) +} + +export function generateStaticParams() { + return [{ slug: 'iso-url' }, { slug: 'кириллица' }] +} diff --git a/test/production/app-dir-prefetch-non-iso-url/app/layout.js b/test/production/app-dir-prefetch-non-iso-url/app/layout.js new file mode 100644 index 000000000000000..750eb927b198012 --- /dev/null +++ b/test/production/app-dir-prefetch-non-iso-url/app/layout.js @@ -0,0 +1,7 @@ +export default function Layout({ children }) { + return ( + + {children} + + ) +} diff --git a/test/production/app-dir-prefetch-non-iso-url/app/page.js b/test/production/app-dir-prefetch-non-iso-url/app/page.js new file mode 100644 index 000000000000000..786b1ea934a51de --- /dev/null +++ b/test/production/app-dir-prefetch-non-iso-url/app/page.js @@ -0,0 +1,18 @@ +import Link from 'next/link' + +export default function Page(props) { + return ( + <> +

index

+

{JSON.stringify(props)}

+ + /iso-url + +
+ + /кириллица + +
+ + ) +} diff --git a/test/production/app-dir-prefetch-non-iso-url/index.test.ts b/test/production/app-dir-prefetch-non-iso-url/index.test.ts new file mode 100644 index 000000000000000..6ac83c44517e801 --- /dev/null +++ b/test/production/app-dir-prefetch-non-iso-url/index.test.ts @@ -0,0 +1,58 @@ +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' +import { join } from 'path' +import { BrowserInterface } from '../../lib/browsers/base' +import webdriver from 'next-webdriver' +import { waitFor } from 'next-test-utils' + +describe('app-dir-prefetch-non-iso-url', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: { + 'next.config.js': new FileRef(join(__dirname, 'next.config.js')), + app: new FileRef(join(__dirname, 'app')), + }, + }) + }) + afterAll(() => next.destroy()) + + it('should go to iso url', async () => { + let browser: BrowserInterface + + try { + browser = await webdriver(next.appPort, '/') + await browser.elementByCss('#to-iso').click() + + const text = await browser.elementByCss('#page').text() + + await waitFor(3000) + + expect(text).toBe('/[slug]') + } finally { + if (browser) { + await browser.close() + } + } + }) + + it('should go to non-iso url', async () => { + let browser: BrowserInterface + + try { + browser = await webdriver(next.appPort, '/') + await browser.elementByCss('#to-non-iso').click() + + const text = await browser.elementByCss('#page').text() + + await waitFor(3000) + + expect(text).toBe('/[slug]') + } finally { + if (browser) { + await browser.close() + } + } + }) +}) diff --git a/test/production/app-dir-prefetch-non-iso-url/next.config.js b/test/production/app-dir-prefetch-non-iso-url/next.config.js new file mode 100644 index 000000000000000..426499ce6de355c --- /dev/null +++ b/test/production/app-dir-prefetch-non-iso-url/next.config.js @@ -0,0 +1,6 @@ +/** @type {import("next").NextConfig} */ +const nextConfig = { + experimental: { appDir: true }, +} + +module.exports = nextConfig From 1371bc0f974d3a75b1b3914059d14010cffe668a Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 17 Nov 2022 14:07:28 -0800 Subject: [PATCH 2/3] update test --- .../app-dir-prefetch-non-iso-url/index.test.ts | 16 +++------------- 1 file changed, 3 insertions(+), 13 deletions(-) diff --git a/test/production/app-dir-prefetch-non-iso-url/index.test.ts b/test/production/app-dir-prefetch-non-iso-url/index.test.ts index 6ac83c44517e801..337e6f1c15fdbb5 100644 --- a/test/production/app-dir-prefetch-non-iso-url/index.test.ts +++ b/test/production/app-dir-prefetch-non-iso-url/index.test.ts @@ -3,7 +3,7 @@ import { NextInstance } from 'test/lib/next-modes/base' import { join } from 'path' import { BrowserInterface } from '../../lib/browsers/base' import webdriver from 'next-webdriver' -import { waitFor } from 'next-test-utils' +import { check, waitFor } from 'next-test-utils' describe('app-dir-prefetch-non-iso-url', () => { let next: NextInstance @@ -24,12 +24,7 @@ describe('app-dir-prefetch-non-iso-url', () => { try { browser = await webdriver(next.appPort, '/') await browser.elementByCss('#to-iso').click() - - const text = await browser.elementByCss('#page').text() - - await waitFor(3000) - - expect(text).toBe('/[slug]') + await check(() => browser.elementByCss('#page').text(), '/[slug]') } finally { if (browser) { await browser.close() @@ -43,12 +38,7 @@ describe('app-dir-prefetch-non-iso-url', () => { try { browser = await webdriver(next.appPort, '/') await browser.elementByCss('#to-non-iso').click() - - const text = await browser.elementByCss('#page').text() - - await waitFor(3000) - - expect(text).toBe('/[slug]') + await check(() => browser.elementByCss('#page').text(), '/[slug]') } finally { if (browser) { await browser.close() From e84108986ec3c357088cf456d5daa491ac69ea84 Mon Sep 17 00:00:00 2001 From: JJ Kasper Date: Thu, 17 Nov 2022 14:19:55 -0800 Subject: [PATCH 3/3] fix lint --- test/production/app-dir-prefetch-non-iso-url/index.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/production/app-dir-prefetch-non-iso-url/index.test.ts b/test/production/app-dir-prefetch-non-iso-url/index.test.ts index 337e6f1c15fdbb5..6acf21db99096b8 100644 --- a/test/production/app-dir-prefetch-non-iso-url/index.test.ts +++ b/test/production/app-dir-prefetch-non-iso-url/index.test.ts @@ -3,7 +3,7 @@ import { NextInstance } from 'test/lib/next-modes/base' import { join } from 'path' import { BrowserInterface } from '../../lib/browsers/base' import webdriver from 'next-webdriver' -import { check, waitFor } from 'next-test-utils' +import { check } from 'next-test-utils' describe('app-dir-prefetch-non-iso-url', () => { let next: NextInstance