Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot have encoded % in URL outside of parameter #7554

Closed
benmccann opened this issue Nov 8, 2022 · 6 comments · Fixed by #7644
Closed

Cannot have encoded % in URL outside of parameter #7554

benmccann opened this issue Nov 8, 2022 · 6 comments · Fixed by #7644
Labels
bug Something isn't working
Milestone

Comments

@benmccann
Copy link
Member

benmccann commented Nov 8, 2022

Describe the bug

#7521 will not allow you to have a URL like this:

Screenshot from 2022-11-08 14-27-39

Probably the way to fix this is to replace the parameters with placeholders, decodeURI the altered URL, match with regex, and then decodeURIComponent on the parameters

Reproduction

https://github.com/benmccann/kit/tree/encoded-percent-test

Logs

No response

System Info

`master`

Severity

annoyance

Additional Information

No response

@benmccann benmccann added the bug Something isn't working label Nov 8, 2022
@dmkret
Copy link

dmkret commented Nov 9, 2022

@benmccann here is what i found:

  1. It seems like you forgot to add a link to +page.svelte
<a href="/encoded/99%">99%</a>
  1. Decoding /encoded/99% uri will throw en error, so it should be /encoded/99%25
decodeURI('/encoded/99%')
// Uncaught URIError: URI malformed
//     at decodeURI (<anonymous>)
//     at <anonymous>:1:1

decodeURI('/encoded/99%25')
// '/encoded/99%'
  1. There is an issue with % in directory name, caused by viteTransformMiddleware (at least).
    This middleware uses decodeURI on folder path. /encoded/[percent]%25 becomes /encoded/[percent]% and any attempt to resolve /encoded/[percent]%25 causes 404.

It seems like it is safe to use characters that are ignored by decodeURI: %3B %2F %3F %3A %40 %26 %3D %2B %24 %2C %23 (; / ? : @ & = + $ , #) and others.

P.S. If you remove [percent]%25 folder and use [slug], all will be fine, but % will be part of the slug.

@dmkret
Copy link

dmkret commented Nov 9, 2022

As a solution maybe we can check path segments on build like this:

const decoded = decodeURI(segment);
if (decoded !== segment) {
  throw Error('there is an unavailable encoded character') // and show original and decoded segments
}

@benmccann
Copy link
Member Author

Thanks for catching my mistakes in the test! Sorry about that. I just pushed the fixes you mentioned

I'm not sure I understand what you're suggesting might be wrong with viteTransformMiddleware. Can you explain in more detail?

I'm actually pretty confused at the moment because the Playwright tests are failing, but I can load the page just fine in my browser:

Screenshot from 2022-11-08 21-38-38

@dmkret
Copy link

dmkret commented Nov 9, 2022

@benmccann expects should be updated too:

test('allows %-encoded percent character in directory names', async ({ page, clicknav }) => {
	await page.goto('/encoded');
	await clicknav('[href="/encoded/99%25"]');
	expect(await page.textContent('h1')).toBe('dynamic');
	expect(await page.textContent('h2')).toBe('/encoded/99%25: 99%');
	expect(await page.textContent('h3')).toBe('/encoded/99%25: 99%');
});

@dmkret
Copy link

dmkret commented Nov 9, 2022

About viteTransformMiddleware, sorry, i was wrong.

This is a regression with %25, but placeholders shouldn't help...

@dmkret
Copy link

dmkret commented Nov 9, 2022

It is ok when %2525 used instead of %25 is in folder name ([percent]%2525).
As a solution I see avoid decoding of %25 on segments parsing:

const decoded_segment = decodeURIComponent(segment);

const decoded_segment = segment.split('%25').map(decodeURIComponent).join('%25'));

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment