From c6282083db55e29a4e8c2b5ff8817b3ddf2da61c Mon Sep 17 00:00:00 2001 From: Guillaume Duhamel Date: Wed, 13 Apr 2011 07:27:21 +0200 Subject: [PATCH 1/3] Encode parse_qs input in utf-8 so we make sure the output will be utf-8 too and we don't end up mixing utf-8 characters (from %xx translation) into a non utf-8 sequence. --- oauth2/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 835270e3..87210f7c 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -418,7 +418,7 @@ def to_url(self): except AttributeError: # must be python <2.5 query = base_url[4] - query = parse_qs(query) + query = parse_qs(query.encode('utf-8')) for k, v in self.items(): query.setdefault(k, []).append(v) From 27d1366ed053562e9f7e98b0ea0053084602056b Mon Sep 17 00:00:00 2001 From: Guillaume Duhamel Date: Wed, 13 Apr 2011 09:36:04 +0200 Subject: [PATCH 2/3] Modified _split_url_string to handle multiple instances of the same parameter. This is useful for APIs such as the LinkedIn search API using multiple instances of the "facet" parameter. Also updated get_normalized_parameters to handle the new datatype returned by _split_url_string (list of tuples instead of dict). It doesn't break from_request but it doesn't make it possible to use multiple instance of the sameparameters in from_request. (as they are stored in a dict in that function) --- oauth2/__init__.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 87210f7c..5d0b3633 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -469,7 +469,7 @@ def get_normalized_parameters(self): # Include any query string parameters from the provided URL query = urlparse.urlparse(self.url)[4] - url_items = self._split_url_string(query).items() + url_items = self._split_url_string(query) url_items = [(to_utf8(k), to_utf8(v)) for k, v in url_items if k != 'oauth_signature' ] items.extend(url_items) @@ -606,9 +606,11 @@ def _split_header(header): @staticmethod def _split_url_string(param_str): """Turn URL string into parameters.""" - parameters = parse_qs(param_str.encode('utf-8'), keep_blank_values=True) - for k, v in parameters.iteritems(): - parameters[k] = urllib.unquote(v[0]) + parsed = parse_qs(param_str.encode('utf-8'), keep_blank_values=True) + parameters = [] + for k, v in parsed.iteritems(): + for w in v: + parameters.append((k, urllib.unquote(w))) return parameters From cb872984b2aabf5ab9055fcc8550a3a88633317c Mon Sep 17 00:00:00 2001 From: Guillaume Date: Mon, 7 Jan 2013 12:05:23 +0100 Subject: [PATCH 3/3] Fixed double decoding of url parameters. Also added a new test_split_url_string test. --- oauth2/__init__.py | 2 +- tests/test_oauth.py | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/oauth2/__init__.py b/oauth2/__init__.py index 5d0b3633..1f6d653b 100644 --- a/oauth2/__init__.py +++ b/oauth2/__init__.py @@ -610,7 +610,7 @@ def _split_url_string(param_str): parameters = [] for k, v in parsed.iteritems(): for w in v: - parameters.append((k, urllib.unquote(w))) + parameters.append((k, w)) return parameters diff --git a/tests/test_oauth.py b/tests/test_oauth.py index 099e5794..572432d1 100644 --- a/tests/test_oauth.py +++ b/tests/test_oauth.py @@ -881,7 +881,7 @@ def test_from_request(self): exp = parse_qs(qs, keep_blank_values=False) for k, v in exp.iteritems(): - exp[k] = urllib.unquote(v[0]) + exp[k] = v[0] self.assertEquals(exp, req.copy()) @@ -924,6 +924,14 @@ def test_from_consumer_and_token(self): self.assertEquals(req['oauth_consumer_key'], con.key) self.assertEquals(tok.verifier, req['oauth_verifier']) + def test_split_url_string(self): + param_str = u"foo=bar&bar=édulcoré&baz=%25de" + + params = oauth.Request._split_url_string(param_str) + params.sort() + self.assertEquals(params, [('bar', 'édulcoré'), ('baz', '%de'), ('foo', 'bar')]) + + class SignatureMethod_Bad(oauth.SignatureMethod): name = "BAD"