-
Notifications
You must be signed in to change notification settings - Fork 27.5k
AngularJS unescapes matrix parameters #16312
Comments
This sounds like a valid bug. Thanks for reporting @bourey ! |
Is it |
@petebacondarwin I think it's |
I think the exact problem here is that we are unescaping forward slashes, right? |
I have created a PR for this: #16316 - please take a look. As with all things related to the can of worms that is |
I just want to flag, without much information as I don't have it right now but finally found out that this update was causing of an issue we were having with https://github.com/angular-ui/ui-router which wasn't there before. For some reason |
@petebacondarwin I just tried master and it didn't fix my problem. Not sure if I am testing it correctly. I copied over the built angular.js and angular-sanitize.js, but not the other bits, but I think the issue is within angular.js anyway. |
Hey 👋 , Why not using |
This fix works, thx 👍 |
The original fix for angular#16312 including changing how `$location.url(value)` decoded the special characters passed to it as a setter. This broke a number of use cases (mostly involving the ui-router). Further analysis appears to show that we can solve angular#16312, to prevent urls being rewritten with decoded values, without modifying the behaviour of `$location.url`. This commit reverts changes to `$location.url(value)` so that encoded chars will be decoded and passed to `$location.path(value)` is updated. In particular it will convert encoded forward slashes, which changes how the path is updated, since `a/b/%2Fc%2Fd while become `a/b/c/d`. While this is arguably not "correct", appears that there are too many use cases relying upon this behaviour.
The original fix for angular#16312 included changing how `$location.url(value)` decoded the special characters passed to it as a setter. This broke a number of use cases (mostly involving the ui-router). Further analysis appears to show that we can solve angular#16312, to prevent urls being rewritten with decoded values, without modifying the behaviour of `$location.url`. This commit reverts changes to `$location.url(value)` so that encoded chars will once again be decoded and passed to `$location.path(value)`. In particular it will convert encoded forward slashes, which changes how the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`. While this is arguably not "correct", it appears that there are too many use cases relying upon this behaviour.
@Narretz at least I tried it and the issue I was having on #16312 (comment) seems to have gone with master + patch #16354 |
The original fix for angular#16312 included changing how `$location.url(value)` decoded the special characters passed to it as a setter. This broke a number of use cases (mostly involving the ui-router). Further analysis appears to show that we can solve angular#16312, to prevent urls being rewritten with decoded values, without modifying the behaviour of `$location.url`. This commit reverts changes to `$location.url(value)` so that encoded chars will once again be decoded and passed to `$location.path(value)`. In particular it will convert encoded forward slashes, which changes how the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`. While this is arguably not "correct", it appears that there are too many use cases relying upon this behaviour.
The original fix for #16312 included changing how `$location.url(value)` decoded the special characters passed to it as a setter. This broke a number of use cases (mostly involving the ui-router). Further analysis appears to show that we can solve #16312, to prevent urls being rewritten with decoded values, without modifying the behaviour of `$location.url`. This commit reverts changes to `$location.url(value)` so that encoded chars will once again be decoded and passed to `$location.path(value)`. In particular it will convert encoded forward slashes, which changes how the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`. While this is arguably not "correct", it appears that there are too many use cases relying upon this behaviour.
The original fix for #16312 included changing how `$location.url(value)` decoded the special characters passed to it as a setter. This broke a number of use cases (mostly involving the ui-router). Further analysis appears to show that we can solve #16312, to prevent urls being rewritten with decoded values, without modifying the behaviour of `$location.url`. This commit reverts changes to `$location.url(value)` so that encoded chars will once again be decoded and passed to `$location.path(value)`. In particular it will convert encoded forward slashes, which changes how the path is updated, since e.g. `a/b/%2Fc%2Fd` will become `a/b/c/d`. While this is arguably not "correct", it appears that there are too many use cases relying upon this behaviour.
I am definitely seeing issues related to this with AngularJS 1.7.2 and legacy ui-router 0.4.3. In html5 mode, trying to access a url directly gets rerouted to my fallback state because the the slashes are converted to EDIT: In my particular case, the problem observed was related to the change in default hashPrefix. Setting it to its previous value of |
I personally don’t think that RFC3986§6.2.2.2 recommends that percent normalization only the normalize unreserved characters listed in RFC3986§2.3. These unreserved characters are RFC3986§3.3 permits the entirety of the path to consist of This means that the specification defines three categories of characters used within a path:
This last category may be further broken down for JavaScript programmers in terms of what encodeURIComponent('/!$^\'()*+,;=:@')
"%2F!%24%5E'()*%2B%2C%3B%3D%3A%40" And, additionally, I’m sure that the HTML spec also further defines/alters how the URI should be handled. This patch/PR adds For example, a function like this could be used instead of /**
* This takes any percent-encoded character which is listed in
* RFC3986§2.3 (https://tools.ietf.org/html/rfc3986#section-2.3)
* and normalizes them to their decoded form. The below is the
* list of characters:
*
* unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
*
* "-" = %2d
*
* "." = %2e
*
* "_" = %5f
*
* ~ = %7e
*
* ALPHA = %41–%5A
*
* DIGIT = %30–%39
*
* RFC3986§6.2.2.2
* (https://tools.ietf.org/html/rfc3986#section-6.2.2.2) states
* that the above characters should be considered equivalent when
* both encoded and not. Thus, the application is not allowed to
* treat their escaped and unescaped versions differently. For
* example, none of those characters may be used as path
* separators because URI implementations are allowed to normalize
* them away.
*
* To avoid accidentally relying on these characters as path
* separators, normalize them away.
*/
function normalizePathPercentEncoding(s) {
// For incoming URIs, we expect all of these characters to already
// be decoded. This replace should be basically free when the path
// is already percent encoding normalized.
return s.replace(/%(?:2d|2e|5f|7e|4[1-9a-f]|5[0-9a]|3[0-9])/gi, decodeURIComponent);
} It is not the place of AngularJS to decode the entire path. Whatever is handling the path and giving significance to segments—e.g., ui-router which considers the |
Additionally, I see that this is only applied for html5Mode. I actually came here because I was having this same exact problem except in hashbang mode. |
Here’s a demo of this same problem existing in 1.7.3 in |
Thx for the thorough write-up, @binki. You are probably correct. Unfortunately, changing the behavior of Given that AngularJS has now entered an LTS period, such breaking changes are out of scope. If someone desperately needs this different (more correct) behavior, it is not too difficult to overwrite |
@gkalpak Thanks for the response and advice. I understand the LTS period issue and compat issues. I was surprised that some of the changes discussed in this thread actually appeared to go out in minor releases during the LTS period :-p. I was pulled away from working on the project where I was having trouble with |
We in our application have embedded callback urls in path itself and hence decodePath in non html mode (hash bang) has been causing the trouble. Any reason why in native implementation; decodePath re-encodes the forward slashes to %2F only for htmlMode and not for hashbang mode? |
I'm submitting a ...
Current behavior:
AngularJS un-escapes matrix parameters, preventing matrix parameters with slashes from being used in dual-router AngularJS / Angular applications.
Expected / new behavior:
AngularJS should not un-escape matrix parameters.
Minimal reproduction of the problem with instructions:
In a hybrid setup, add a link like: <a [routerLink]="['/a/ng2', {path: '/some/path'}]">ANGULAR A
While Angular properly renders this link as "http://localhost:4200/a/ng2;path=%2Fsome%2Fpath", AngularJS rewrites it as http://localhost:4200/a/ng2;path=/some/path during navigation. Depending on the setup, this causes the application to display either a missing route mapping or a redirect loop.
AngularJS version: 1.5+
Browser: all
The text was updated successfully, but these errors were encountered: