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

Fix issues with pre-encoded param names not being properly decoded #11199

Merged
merged 9 commits into from
Feb 6, 2024

Conversation

brophdawg11
Copy link
Contributor

Handle edge cases of pre-ended param values not being properly decoded correctly due to differences in decodeURI/decodeURIComponent/new URL()

Supersedes #11138
Closes #10814

Copy link

changeset-bot bot commented Jan 17, 2024

🦋 Changeset detected

Latest commit: 114cf0b

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 5 packages
Name Type
react-router Patch
@remix-run/router Patch
react-router-dom Patch
react-router-dom-v5-compat Patch
react-router-native Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

{ char: "]", pathChar: "]", searchChar: "]", hashChar: "]", decodedChar: "]" },
{ char: ":", pathChar: ":", searchChar: ":", hashChar: ":", decodedChar: ":" },
{ char: ";", pathChar: ";", searchChar: ";", hashChar: ";", decodedChar: ";" },
{ char: ",", pathChar: ",", searchChar: ",", hashChar: ",", decodedChar: "," },
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added the decodedChar to all existing setups - even though it's the same as the char since we now assert matched param values against decodedChar

searchChar: "a%26b%25c",
hashChar: "a%26b%25c",
decodedChar: "a&b%c",
},
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are the net new tests for the bugs being reported, if you pre-encode because that portion of the URL has URL-sensitive characters - you weren't previously getting back the proper decoded value. These are the only tests right now that have a different char versus decodedChar

@@ -342,7 +404,7 @@ describe("special character tests", () => {
search: "",
hash: "",
},
{ slug: char }
{ slug: decodedChar }
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assert params against decodedChar now

let parentSegments = parentPathnameBase.replace(/^\//, "").split("/");
let segments = pathname.replace(/^\//, "").split("/");
remainingPathname = "/" + segments.slice(parentSegments.length).join("/");
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to ensure we can match down into descendant routes when we get odd encodings coming in

@@ -930,7 +928,7 @@ export function matchPath<
if (isOptional && !value) {
memo[paramName] = undefined;
} else {
memo[paramName] = safelyDecodeURIComponent(value || "", paramName);
memo[paramName] = (value || "").replace(/%2F/g, "/");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't need to call decodeURIComponent on param values here anymore since we matched against a slash-delimited path of segments that already went through decodeURIComponent

return value
.split("/")
.map((v) => decodeURIComponent(v).replace(/\//g, "%2F"))
.join("/");
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

decodeURI here is a bit too aggressive since it assumes a full URI which may have query params and hash values in it. Since we're only operating on a pathname, we should instead decode each component individually in case they have pre-encoded hashes, percent signs, etc. in them.

However, if there was an encoded slash - preserve that as %2F since we can't introduce new segments via this decoding

@RobinClowers
Copy link

@brophdawg11 It would be awesome to merge this, is it waiting for something specific?

@brophdawg11
Copy link
Contributor Author

Mostly just giving it a little time to see if other folks would be able to pull it down and confirm it fixes their issues. You and one other user have confirmed it solves it so that's probably all we're going to get so I'll get this merged 👍

@brophdawg11 brophdawg11 merged commit 241f2d4 into dev Feb 6, 2024
3 checks passed
@brophdawg11 brophdawg11 deleted the brophdawg11/encoding branch February 6, 2024 15:17
Copy link
Contributor

🤖 Hello there,

We just published version 6.22.1-pre.0 which includes this pull request. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

Copy link
Contributor

🤖 Hello there,

We just published version 6.22.1 which includes this pull request. If you'd like to take it for a test run please try it out and let us know what you think!

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants