Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

fix(ngResource): fix query url params encoding #12201

Closed

Conversation

alediaferia
Copy link
Contributor

Encoding URL Query Parameters should be "more aggressive" than the URL Segment encoding.
You can see what I mean in the added test case.

I'm currently using AngularJS 1.3.16 but I found this bug is still there in master.

Review on Reviewable

@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project, in which case you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed, please reply here (e.g. I signed it!) and we'll verify. Thanks.


  • If you've already signed a CLA, it's possible we don't have your GitHub username or you're using a different email address. Check your existing CLA data and verify that your email is set on your git commits.
  • If you signed the CLA as a corporation, please let us know the company's name.

@alediaferia
Copy link
Contributor Author

I signed it!

@googlebot
Copy link

CLAs look good, thanks!

@nacmacfeegle
Copy link

+1 to this fix, thanks @alediaferia

@@ -431,16 +431,20 @@ angular.module('ngResource', ['ng']).
}
if (!(new RegExp("^\\d+$").test(param)) && param &&
(new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
urlParams[param] = true;
urlParams[param] = { isQueryParam: (new RegExp("\\?(.*)\\:" + param)).test(url) };
Copy link
Member

Choose a reason for hiding this comment

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

You need the '(\\W|$)' part or else you might get false positives. (Better yet '(?:\\W|$)'.)
E.g. param: 'foo' and url: '/path/foo?key=:foobar' will lead to a false positive.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I agree my regex is too broad but I'm not sure I completely get the one proposed by you.
Would something like the following be more accurate?
new RegExp("\\?((\\w+)\\=\\w+&)*\\w+=:" + param + "(\\W|$)").test(url)

Copy link
Member

Choose a reason for hiding this comment

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

No need to make it too strict either :)

IMO, new RegExp('\\?(.*):' + param + '(\\W|$)') (or new RegExp('\\?(?:.*):' + param + '(?:\\W|$)')) is fine.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

So what does ?: match exactly? This is the only bit I don't understand. :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ooh, it's the non-capturing group! :)

@alediaferia alediaferia force-pushed the hotfix/query-url-encoding branch from fbd119c to dc1a67c Compare June 29, 2015 14:19
@alediaferia
Copy link
Contributor Author

I've updated the code accordingly and split my commit messages to better comply with contribution guidelines.

@@ -431,16 +431,20 @@ angular.module('ngResource', ['ng']).
}
if (!(new RegExp("^\\d+$").test(param)) && param &&
(new RegExp("(^|[^\\\\]):" + param + "(\\W|$)").test(url))) {
urlParams[param] = true;
urlParams[param] = { isQueryParam: (new RegExp("\\?(?:.*)\\:" + param + "(?:\\W|$)")).test(url) };
Copy link
Member

Choose a reason for hiding this comment

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

Nitpick: You don't need \\ before : (it's not a special character in this context).

@alediaferia alediaferia force-pushed the hotfix/query-url-encoding branch from dc1a67c to cd4a591 Compare June 29, 2015 15:00
@gkalpak
Copy link
Member

gkalpak commented Jun 29, 2015

LGTM

1 similar comment
@davidesantangelo
Copy link

LGTM

@alediaferia alediaferia changed the title Do not encode URL query parameters the same way as URL path components fix(ngResource): fix query url params encoding Jun 30, 2015
@alediaferia alediaferia changed the title fix(ngResource): fix query url params encoding fix(ngResource): fix query url params encoding Jun 30, 2015
@alediaferia
Copy link
Contributor Author

Is there a plan for when this will go in the main line?

@alediaferia
Copy link
Contributor Author

Bump!

@@ -338,6 +338,17 @@ describe("resource", function() {
});


it('should handle url encoding in mapped params', function() {
Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer a more descriptive testcase name (e.g. should encode & in query params unless in query param value or something).

@gkalpak
Copy link
Member

gkalpak commented Sep 14, 2015

@alediaferia, thx for the update. I left a couple of comments (mostly minor).
Feel free to ping me once you've pushed changes, so I can take another look.

@alediaferia
Copy link
Contributor Author

@gkalpak BTW do you have any hint on why now my grunt package fails with stderr maxBuffer exceeded ?

@gkalpak
Copy link
Member

gkalpak commented Sep 14, 2015

@alediaferia, no idea :) Does it happen with the code currently on the PR ?
(If not, you can push the code somewhere so I can take a look.)

@petebacondarwin
Copy link
Contributor

Sounds like something to do with the closure compiler?

@alediaferia
Copy link
Contributor Author

@gkalpak @petebacondarwin sorry for not getting back earlier. It's happening with the current PR but it's happening with updated master as well. It may be something wrong with my npm/node configuration, but not sure. I'm not much into JavaScript :)

@gkalpak
Copy link
Member

gkalpak commented Sep 16, 2015

@alediaferia, (un)fortunately, I'm not getting any issues with grunt package 😞

@@ -338,6 +338,17 @@ describe("resource", function() {
});


it('should encode & in query params unless in query param value', function() {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm wondering if part of this test is a duplicate of the one preceding this test.

'should encode & in url params'

Copy link
Member

Choose a reason for hiding this comment

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

I would say close but not quite.
I would be happy to have them merged into one it block (keeping all 3 cases).

Feel free to merge them.

@alediaferia
Copy link
Contributor Author

@gkalpak ping

@@ -10,7 +10,7 @@ if diff -q $SHRINKWRAP_FILE $SHRINKWRAP_CACHED_FILE; then
else
echo 'Blowing away node_modules and reinstalling npm dependencies...'
rm -rf node_modules
npm install
npm install --registry http://registry.npmjs.org/
Copy link
Member

Choose a reason for hiding this comment

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

I guess this has to do with your grunt package issues, but it definitely does not belong in this PR :)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Woops! sorry :)

Similar e2e tests assessing URL params
encoding have been merged
Dropped unwanted changes on install-dependencies.sh script
@gkalpak
Copy link
Member

gkalpak commented Sep 17, 2015

LGTM, thx @alediaferia !

/cc @petebacondarwin

@alediaferia
Copy link
Contributor Author

If this is ok, shall I clean up the git history squashing the latest commits and following your commit message conventions?

@petebacondarwin
Copy link
Contributor

OK, LGTM. @alediaferia thanks for your work on this. If you want to squash and tidy up the commit message that would be great. Otherwise, perhaps @gkalpak could do it when merging?

@gkalpak
Copy link
Member

gkalpak commented Sep 17, 2015

Sure, I'll take care of squashing and merging !

@alediaferia
Copy link
Contributor Author

Thank you @gkalpak @petebacondarwin

@petebacondarwin petebacondarwin modified the milestones: 1.4.6, 1.4.7 Sep 17, 2015
@gkalpak gkalpak closed this in 1c97a60 Sep 18, 2015
@gkalpak
Copy link
Member

gkalpak commented Sep 18, 2015

@petebacondarwin, should this be backported to 1.4.x ?

@petebacondarwin
Copy link
Contributor

If you are confident it is not a breaking change.

@gkalpak
Copy link
Member

gkalpak commented Sep 18, 2015

It's one of those times that I find it hard to distinguish between a fix and a BC.

The only change introduced is when a param (:xyz) is used as the value part of a URL query key-value pair. In any other case, there is no difference. But it could still break an app (theoretically).

E.g., assuming $resource('/path?key=:val').get({val: 'foo&bar'}), the request is sent to this URL:

1.4.x: /path?key=foo&bar
1.5.x: /path?key=foo%26bar

@alediaferia
Copy link
Contributor Author

Although I feel the "new" behaviour is the right one I unfortunately think there may be a lot of apps out there relying on a workaround for this "issue".

If you look for e.g. "angularjs ngresource query parameters" on Google there are some issues open on SO with a few workarounds that usually involve using $http directly.

Just my 2 cents.

Happy to have contributed to such a big project anyway :)

@petebacondarwin
Copy link
Contributor

OK, so no backport.

@gkalpak
Copy link
Member

gkalpak commented Sep 18, 2015

@alediaferia, I couldn't find any SO questions/answers that would be broken by this "fix". Relying on a workaround isn't a problem (it won't get broken).
Do you have any specific SO question/answer in mind ?

The problem is if someone has as a URL template such as /path?key=:val and expects to set other query param via :val (e.g. /path?key=1&key2=2&key3=3). It is a weird usecase imo (but theoretically possible nontheless).

@alediaferia
Copy link
Contributor Author

@gkalpak I cannot manage to find the question I had in mind, strange. Anyway, as you point out, relying on a workaround won't make things break. That's true. I don't have further objections.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants