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(router): fix URL serialization so special characters are only enc… #22337

Closed
wants to merge 2 commits into from

Conversation

jasonaden
Copy link
Contributor

…oded where needed

Fixes: #10280

This PR might cause breaking changes. While it shouldn't generally cause any issues, if an application were relying on the over-aggressive encoding Angular previously used, this PR is less aggressive leaving more of the URL intact.

@@ -336,32 +336,41 @@ function serializeSegment(segment: UrlSegmentGroup, root: boolean): string {
* sub-delims = "!" / "$" / "&" / "'" / "(" / ")"
* / "*" / "+" / "," / ";" / "="
*/
export function encode(s: string): string {
return encodeURIComponent(s)
export function encodeUriParams(s: string, type: 'query' | 'segment' = 'query'): string {
Copy link
Contributor

Choose a reason for hiding this comment

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

please update the API doc

.replace(/%5B/gi, '[')
.replace(/%5D/gi, ']');

encoded = type === 'segment' ?
Copy link
Contributor

Choose a reason for hiding this comment

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

could we have a common internal function with the replace up there and 2 exported functions for query and segment with more docs ?

@mary-poppins
Copy link

You can preview dc0de4a at https://pr22337-dc0de4a.ngbuilds.io/.

@mary-poppins
Copy link

You can preview b5d4bdf at https://pr22337-b5d4bdf.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 0e008dd at https://pr22337-0e008dd.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 5431d29 at https://pr22337-5431d29.ngbuilds.io/.

.replace(/%2C/gi, ',')
.replace(/%3B/gi, ';');
function encodeUriString(s: string, type: 'query' | 'segment' = 'query'): string {
let encoded = encodeURIComponent(s)
Copy link
Contributor

Choose a reason for hiding this comment

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

drop the local var

}

/**
* Encodes a string for use in the query string or fragment. This function should be used to
Copy link
Contributor

Choose a reason for hiding this comment

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

could we be more explicit:

Used to encode:
- URL fragments,
- parameter keys,
- parameter values.

*/
export function encodeUriSegment(s: string): string {
return encodeUriString(s)
.replace(/\(/g, '%28')
Copy link
Contributor

Choose a reason for hiding this comment

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

add a note on why we have to do it (in the header comment or inline)

The name tells me that this is used to encode a segment (the part between 2 "/") while the comment tell me it encodes the path ?

Copy link
Contributor

@vicb vicb left a comment

Choose a reason for hiding this comment

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

in person review

@vicb vicb added the action: merge The PR is ready for merge by the caretaker label Feb 21, 2018
@ngbot
Copy link

ngbot bot commented Feb 21, 2018

I see that you just added the PR action: merge label, but the following checks are still failing:
    failure missing required label: "PR target: *"
    failure missing required status "code-review/pullapprove"
    pending status "ci/circleci: build" is pending
    pending status "ci/circleci: lint" is pending
    pending status "google3" is pending
    pending status "continuous-integration/travis-ci/pr" is pending
    pending 1 pending code review

If you want your PR to be merged, it has to pass all the CI checks.

If you can't get the PR to a green state due to flakes or broken master, please try rebasing to master and/or restarting the CI job. If that fails and you believe that the issue is not due to your change, please contact the caretaker and ask for help.

@jasonaden jasonaden added the target: major This PR is targeted for the next major release label Feb 21, 2018
@mary-poppins
Copy link

You can preview 6c6af62 at https://pr22337-6c6af62.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 36319d2 at https://pr22337-36319d2.ngbuilds.io/.

@mary-poppins
Copy link

You can preview 7dae85c at https://pr22337-7dae85c.ngbuilds.io/.

Copy link
Contributor

@IgorMinar IgorMinar left a comment

Choose a reason for hiding this comment

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

please document the changed behavior in the commit message. otherwise nobody will be able to decipher it from the diff.

the rest we reviewed in person and it LGTM.

@IgorMinar IgorMinar added action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews and removed action: merge The PR is ready for merge by the caretaker labels Feb 22, 2018
@IgorMinar
Copy link
Contributor

I realized that I don't see in this diff is two more changes we discussed:

  • decode chars in query params that are erroneously being encoded (I think it was? and ;)
  • decode # in fragment that is erroneously encoded

I see this PR being marked as "breaking change" but that's not the case as far as I can tell. As we discussed, all the previously serialized urls will be correctly parsed and recognized (so bookmarked urls will keep on working). And urls that were previously incorrectly serialized will now work correctly - that's not a breaking change.

@jasonaden jasonaden removed the action: cleanup The PR is in need of cleanup, either due to needing a rebase or in response to comments from reviews label Feb 22, 2018
This was referenced Mar 15, 2018
leo6104 pushed a commit to leo6104/angular that referenced this pull request Mar 25, 2018
…oded where needed (angular#22337)

Fixes: angular#10280

This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on [RFC 3986](http://tools.ietf.org/html/rfc3986) and resolves issues such as the above angular#10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* Query strings will now serialize with decoded slash (`/`) and question mark (`?`)
* URI fragments will now serialize the same as query strings, but hash sign (`#`) will also appear decoded
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

PR Close angular#22337
leo6104 pushed a commit to leo6104/angular that referenced this pull request Mar 25, 2018
leo6104 pushed a commit to leo6104/angular that referenced this pull request Mar 25, 2018
…oded where needed (angular#22337)

This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on RFC 3986 and resolves issues such as the above angular#10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* URI fragments will now serialize the same as query strings
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

Fixes: angular#10280

PR Close angular#22337
leo6104 pushed a commit to leo6104/angular that referenced this pull request Mar 25, 2018
jmleoni pushed a commit to jmleoni/angular that referenced this pull request Oct 6, 2018
…oded where needed (angular#22337)

Fixes: angular#10280

This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on [RFC 3986](http://tools.ietf.org/html/rfc3986) and resolves issues such as the above angular#10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* Query strings will now serialize with decoded slash (`/`) and question mark (`?`)
* URI fragments will now serialize the same as query strings, but hash sign (`#`) will also appear decoded
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

PR Close angular#22337
jmleoni pushed a commit to jmleoni/angular that referenced this pull request Oct 6, 2018
jmleoni pushed a commit to jmleoni/angular that referenced this pull request Oct 6, 2018
…oded where needed (angular#22337)

This change brings Angular largely in line with how AngularJS previously serialized URLs. This is based on RFC 3986 and resolves issues such as the above angular#10280 where URLs could be parsed, re-serialized, then parsed again producing a different result on the second parsing.

Adjustments to be aware of in this commit:

* URI fragments will now serialize the same as query strings
* In the URI path or segments (portion prior to query string and/or fragment), the plus sign (`+`) and ampersand (`&`) will appear decoded
* In the URL path or segments, parentheses values (`(` and `)`) will now appear percent encoded as `%28` and `%29` respectively
* In the URL path or segments, semicolons will be encoded in their percent encoding `%3B`

NOTE: Parentheses and semicolons denoting auxillary routes or matrix params will still appear in their decoded form -- only parentheses and semicolons used as values in a segment or key/value pair for matrix params will be encoded.

While these changes are not considered breaking because applications should be decoding URLs and key/value pairs, it is possible that some unit tests will break if comparing hard-coded URLs in tests since that hard coded string will represent the old encoding. Therefore we are releasing this fix in the upcoming Angular v6 rather than adding it to a patch for v5.

Fixes: angular#10280

PR Close angular#22337
jmleoni pushed a commit to jmleoni/angular that referenced this pull request Oct 6, 2018
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 13, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
action: merge The PR is ready for merge by the caretaker area: router cla: yes hotlist: google target: patch This PR is targeted for the next patch release type: bug/fix
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Using parenthesis in parameters throws an exception in RC4
9 participants