Skip to content

Commit 779a8cf

Browse files
committed
Tests and correct scheme parsing
1 parent 9a8d9d6 commit 779a8cf

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

packages/next/src/client/resolve-href.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export function resolveHref(
3434

3535
// repeated slashes and backslashes in the URL are considered
3636
// invalid and will never match a Next.js page/file
37-
const urlProtoMatch = urlAsString.match(/^[a-zA-Z+]{1,}:\/\//)
37+
// https://datatracker.ietf.org/doc/html/rfc1738#section-2.1
38+
const urlProtoMatch = urlAsString.match(/^[a-zA-Z][a-zA-Z+.-]*:\/\//)
3839
const urlAsStringNoProto = urlProtoMatch
3940
? urlAsString.slice(urlProtoMatch[0].length)
4041
: urlAsString
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import Link from 'next/link'
2+
3+
export default function Page() {
4+
return (
5+
<>
6+
<Link href="flatpak+https://dl.flathub.org/repo/appstream/net.krafting.Playlifin.flatpakref">
7+
flatpak+https
8+
</Link>
9+
<Link href="com.apple.tv://">com.apple.tv</Link>
10+
<Link href="itms-apps://">itms-apps</Link>
11+
</>
12+
)
13+
}

test/integration/invalid-href/pages/second.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ export default function Page() {
1212
id="click-me"
1313
onClick={(e) => {
1414
e.preventDefault()
15+
// this should throw an error on load since prefetch
16+
// receives the invalid href
1517
router[method](invalidLink)
1618
}}
1719
>
1820
invalid link :o
1921
</a>
2022
) : (
21-
// this should throw an error on load since prefetch
22-
// receives the invalid href
2323
<Link href={invalidLink} id="click-me">
24-
invalid link :o
24+
valid link :o
2525
</Link>
2626
)
2727
}

test/integration/invalid-href/test/index.test.js renamed to test/integration/invalid-href/test/index.test.ts

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import cheerio from 'cheerio'
1616
import webdriver from 'next-webdriver'
1717
import { join } from 'path'
1818

19-
let app
20-
let appPort
19+
let app: Awaited<ReturnType<typeof nextStart>>
20+
let appPort: number
2121
const appDir = join(__dirname, '..')
2222

2323
// This test doesn't seem to benefit from retries, let's disable them until the test gets fixed
@@ -98,10 +98,18 @@ describe('Invalid hrefs', () => {
9898
await noError('/first')
9999
})
100100

101-
it('does not show error in production when https://google.com is used as href on Link', async () => {
101+
it('does not show error in production when https:// is used in href on Link', async () => {
102102
await noError('/second')
103103
})
104104

105+
it('does not show error in production when exotic protocols are used in href in Link', async () => {
106+
const browser = await webdriver(appPort, '/exotic-href')
107+
108+
expect(
109+
(await browser.log()).filter((x) => x.source === 'error')
110+
).toEqual([])
111+
})
112+
105113
it('does not show error when internal href is used with external as', async () => {
106114
await noError('/invalid-relative', true)
107115
})
@@ -160,10 +168,18 @@ describe('Invalid hrefs', () => {
160168
await noError('/first')
161169
})
162170

163-
it('does not show error when https://google.com is used as href on Link', async () => {
171+
it('does not show error when https:// is used as href in Link', async () => {
164172
await noError('/second')
165173
})
166174

175+
it('does not show error when exotic protocols are used in href in Link', async () => {
176+
const browser = await webdriver(appPort, '/exotic-href')
177+
178+
expect(
179+
(await browser.log()).filter((x) => x.source === 'error')
180+
).toEqual([])
181+
})
182+
167183
// eslint-disable-next-line jest/no-identical-title
168184
it('shows error when dynamic route mismatch is used on Link', async () => {
169185
await showsError(

0 commit comments

Comments
 (0)