Skip to content

Commit

Permalink
fix redirect to url with semicolon (#65165)
Browse files Browse the repository at this point in the history
Closes #64904

---------

Co-authored-by: JJ Kasper <jj@jjsweb.site>
  • Loading branch information
AbhiShake1 and ijjk authored May 1, 2024
1 parent ad0c5bb commit dcb7e68
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 3 deletions.
9 changes: 6 additions & 3 deletions packages/next/src/client/components/redirect.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,10 @@ export function isRedirectError<U extends string>(
return false
}

const [errorCode, type, destination, status] = error.digest.split(';', 4)
const digest = error.digest.split(';')
const [errorCode, type] = digest
const destination = digest.slice(2, -2).join(';')
const status = digest.at(-2)

const statusCode = Number(status)

Expand Down Expand Up @@ -134,7 +137,7 @@ export function getURLFromRedirectError(error: unknown): string | null {

// Slices off the beginning of the digest that contains the code and the
// separating ';'.
return error.digest.split(';', 3)[2]
return error.digest.split(';').slice(2, -2).join(';')
}

export function getRedirectTypeFromError<U extends string>(
Expand All @@ -154,5 +157,5 @@ export function getRedirectStatusCodeFromError<U extends string>(
throw new Error('Not a redirect error')
}

return Number(error.digest.split(';', 4)[3])
return Number(error.digest.split(';').at(-2))
}
7 changes: 7 additions & 0 deletions test/e2e/app-dir/navigation/app/redirect/semicolon/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { redirect } from 'next/navigation'

export const dynamic = 'force-dynamic'

export default function Page() {
return redirect('/?a=b;c')
}
11 changes: 11 additions & 0 deletions test/e2e/app-dir/navigation/navigation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ describe('app dir - navigation', () => {
expect(url.searchParams.toString()).toMatchInlineSnapshot(`"a=b&c=d"`)
})

it('should set query with semicolon correctly', async () => {
const browser = await next.browser('/redirect/semicolon')

await retry(() =>
expect(browser.elementById('query').text()).resolves.toEqual('a=b%3Bc')
)

const url = new URL(await browser.url())
expect(url.searchParams.toString()).toBe('a=b%3Bc')
})

it('should handle unicode search params', async () => {
const requests: Array<{
pathname: string
Expand Down

0 comments on commit dcb7e68

Please sign in to comment.