Skip to content

fix(router): fix = not parsed in router segment name#47332

Closed
DW8Reaper wants to merge 4 commits intoangular:mainfrom
DW8Reaper:router-equals
Closed

fix(router): fix = not parsed in router segment name#47332
DW8Reaper wants to merge 4 commits intoangular:mainfrom
DW8Reaper:router-equals

Conversation

@DW8Reaper
Copy link
Copy Markdown
Contributor

fix router segment name parsing to allow segements to container an unscaped = character. Currently if you have a url like /some-site/folder=/some-file then then middle segment "folder=" will stop parsing at the = sign and register that part of the path as just "folder"

Fixes #21381

PR Checklist

Please check if your PR fulfills the following requirements:

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • angular.io application / infrastructure changes
  • Other... Please describe:

What is the current behavior?

As outlined in this issue (#21381) when you have a url where a path segment contains an = character angular will parse that segment as only the characters before the =. For example password/de/MDAtMNTk= the last segment will be parsed in angular as only MDAtMNTk without the = character

Issue Number: 21381

What is the new behavior?

After this change you may include any number of = characters in a segment name and correspondingly define those as route paths in your route configuration.

Does this PR introduce a breaking change?

  • Yes
  • No

I think this PR could potentially be a breaking change since someone might have specifically handled cases where = was ignored by angular. Suppose they had path segments that were base 64 encoded strings for example IMz3bg==, those could possibly end with one or two = characters. It is therefore conceivable that someone might have implemented a workaround where if they received the id as IMz3bg they could infer based on the missing bit count that two == characters should be added. In that case if angular now accepted = their resource names could suddenly become IMz3bg====

A counter argument would be that if you had logic to determine the number of missing bits if angular now parsed the = there wouldn't be any missing bits and your logic would not trigger

Other information

Based off of comments in the issue here (#21381 (comment)) and (#21381 (comment)) I looked into RFC 3986 and RFC 1630 and it would seem that there isn't any specific limitation on using = in a segment name. Consider this excerpt from RFC 3986:

For example, the semicolon (";") and equals ("=") reserved characters are often used to delimit parameters and parameter values applicable to that segment. The comma (",") reserved character is often used for similar purposes. For example, one URI producer might use a segment such as "name;v=1.1" to indicate a reference to version 1.1 of "name", whereas another might use a segment such as "name,1.1" to indicate the same. Parameter types may be defined by scheme-specific semantics, but in most cases the syntax of a parameter is specific to the implementation of the URI's dereferencing algorithm.

This seems to clearly indicate that you can use = and that is further substantiated by angulars special handling of matric parameters which uses the name;v=1.1 syntax from this excerpt

@pullapprove pullapprove bot requested a review from AndrewKushnir September 2, 2022 05:12
@AndrewKushnir AndrewKushnir added area: router target: major This PR is targeted for the next major release flag: breaking change labels Sep 2, 2022
@ngbot ngbot bot added this to the Backlog milestone Sep 2, 2022
@AndrewKushnir AndrewKushnir added the action: review The PR is still awaiting reviews from at least one requested reviewer label Sep 2, 2022
@ngbot ngbot bot modified the milestone: Backlog Sep 2, 2022
@pullapprove pullapprove bot removed the request for review from atscott September 2, 2022 17:03
@DW8Reaper
Copy link
Copy Markdown
Contributor Author

I did some testing in a sample app and when I have my routing configured as

const routes: Routes = [
  {path: 'another=test', component: TestComponent}
];

then it correctly loads TestComponent when I go to http://localhost;4200/another=test where previously it would have tried to got to a route another.

There is one thing that may be unexpected and that is after routing completes the new URL will encode the = so the URL becomes http://localhost:4200/another%3Dtest (that route also works though if you try load it). So now I'm wondering if that result after loading the page should keep the = unencoded it kinda seems like it should any opinion on that?

@pkozlowski-opensource
Copy link
Copy Markdown
Member

@DW8Reaper sorry for the delay on reviewing / merging this one. It is likely that this change introduces a breaking change so we need to run some internal tests and go over their results.

@pkozlowski-opensource pkozlowski-opensource added the action: global presubmit The PR is in need of a google3 global presubmit label Sep 12, 2022
@pullapprove pullapprove bot removed the request for review from atscott September 12, 2022 18:46
@atscott
Copy link
Copy Markdown
Contributor

atscott commented Sep 19, 2022

Note: This is related to the internal issue b/234604699. These issues are related but actually solve distinctly separate parts of the parsing.

The solution here parses = in the segment path but specifically excludes it from matrix params.
The internal issue requires the = to be parsed in the matrix param value but does not attempt to parse it elsewhere in the path.

We'll need to evaluate both scenarios and may want to include both in the single solution. The matrix proposal does not appear to take a stance on the = character in parameter values (i.e. /a/b;myKey=myValueWithAn=InTheMiddle).

@DW8Reaper
Copy link
Copy Markdown
Contributor Author

@atscott I'd be happy to update mine if you can provide some details on where the other place was that this was changed on your side. Of course if it is simpler to just update things internally that makes sense to and then I can decline this PR

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Sep 19, 2022

@DW8Reaper I think essentially you just need to update const valueMatch = matchMatrixParamSegments(this.remaining); to be const valueMatch = matchSegments(this.remaining);. We can leave this open and give you the credit for the fix. We're testing the change internally, but that'll take a fair bit of time to roll out safely.

@DW8Reaper
Copy link
Copy Markdown
Contributor Author

Cool I can do that, not sure if you saw my other comment @atscott about it not preserving the = when the page navigation completes instead it the % escapes it.

Should I see if I can fix that as well to make this more complete?

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Sep 19, 2022

Cool I can do that, not sure if you saw my other comment @atscott about it not preserving the = when the page navigation completes instead it the % escapes it.

Should I see if I can fix that as well to make this more complete?

I didn't see that. Yea, that seems like something we might want to address at the same time if possible.

@DW8Reaper
Copy link
Copy Markdown
Contributor Author

@atscott sorry that it took a while to update this PR but I have changed it so that if now will keep the = sign after routing in the URL bar of the browser

@DW8Reaper
Copy link
Copy Markdown
Contributor Author

@atscott just following up is there anything else I need to do from my side for this PR?

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Oct 17, 2022

@DW8Reaper No, I'm just waiting to hear back about the results from the internal experiment.

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

As alluded to in #47332 (comment) we've got an internal bug using = in matrix parameter values that would be convenient to fix in this PR, all that's needed is to leave this line as calling matchSegments

That will also make it worth renaming matchMatrixParamSegments to add more precision, maybe something like matchMatrixKeySegment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

After some additional discussion with @atscott we think it would be better to leave this change for a separate PR, i.e. this PR will handle parsing = in router segments and leave them encoded (the same way = are currently handled in query parameters), and in a different PR we can look into leaving them unencoded (sorry for the back and forth!)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Man I hope I got this straight I think all an all after you comments I was supposed to remove the URL encoding part then which I did by just reverting that whole second commit.

I wasn't sure if I was still supposed to remove the second call to matchMatrixParamSegments in the parseParam function from this comment:

As alluded to in #47332 (comment) we've got an internal bug using = in matrix parameter values that would be convenient to fix in this PR, all that's needed is to leave this line as calling matchSegments

That will also make it worth renaming matchMatrixParamSegments to add more precision, maybe something like matchMatrixKeySegment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Sorry for the delay! I was down with the flu

Yep these are the only changes left to do now:

  1. Change the second matchMatrixParamSegments call to matchSegments (which will let = be an allowed character in matrix parameter values)
  2. With (1), matchMatrixParamSegments will only be used for matrix keys so it is probably worth renaming it to matchMatrixKeySegment
  3. A test to cover the functionality mentioned in (1), I mentioned one option in this comment: https://github.com/angular/angular/pull/47332/files#r1029601032

After those I think the PR will be good to go!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cool I'll update it then but it'll probably only be in about 2 weeks I'm traveling and don't have my notebook with me

DW

fix router segment name parsing to allow segements to container an unscaped = character. Currently if you have a url like /some-site/folder=/some-file then then middle segment "folder=" will stop parsing at the = sign and register that part of the path as just "folder"

Fixes angular#21381
This reverts commit 2279f4d4620eba083a9832ed096890b69a25ec42.

Reverting that commit based off PR feedback that this change should only affect the parsing of sergments and node encoding of the url
Copy link
Copy Markdown

@michaelgriscom michaelgriscom left a comment

Choose a reason for hiding this comment

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

Looks great!

@atscott this looks ready to merge to me

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Apr 10, 2023

@michaelgriscom Great, thanks for helping out on the review here! I'll take one last look and run a global presubmit

@atscott atscott added action: merge The PR is ready for merge by the caretaker and removed action: review The PR is still awaiting reviews from at least one requested reviewer action: global presubmit The PR is in need of a google3 global presubmit labels Apr 10, 2023
@ngbot
Copy link
Copy Markdown

ngbot bot commented Apr 10, 2023

I see that you just added the action: merge label, but the following checks are still failing:
    failure status "ci/angular: size" is failing
    pending 2 pending code reviews

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 main, please try rebasing to main 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.

@atscott
Copy link
Copy Markdown
Contributor

atscott commented Apr 10, 2023

Green TGP

@AndrewKushnir AndrewKushnir added target: rc This PR is targeted for the next release-candidate and removed target: major This PR is targeted for the next major release labels Apr 11, 2023
@AndrewKushnir
Copy link
Copy Markdown
Contributor

This PR was merged into the repository by commit ee816e1.

AndrewKushnir pushed a commit that referenced this pull request Apr 11, 2023
…47332)

This reverts commit 2279f4d4620eba083a9832ed096890b69a25ec42.

Reverting that commit based off PR feedback that this change should only affect the parsing of sergments and node encoding of the url

PR Close #47332
AndrewKushnir pushed a commit that referenced this pull request Apr 11, 2023
fix router segment name parsing to allow segements to container an unscaped = character. Currently if you have a url like /some-site/folder=/some-file then then middle segment "folder=" will stop parsing at the = sign and register that part of the path as just "folder"

Fixes #21381

PR Close #47332
AndrewKushnir pushed a commit that referenced this pull request Apr 11, 2023
…47332)

This reverts commit 2279f4d4620eba083a9832ed096890b69a25ec42.

Reverting that commit based off PR feedback that this change should only affect the parsing of sergments and node encoding of the url

PR Close #47332
@angular-automatic-lock-bot
Copy link
Copy Markdown

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 May 12, 2023
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 target: rc This PR is targeted for the next release-candidate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Router Segments parsing error with =

5 participants