Repository: oauthlib/oauthlib

Issue:
ValueError when query string contains "'"
Similar to Issue #404, `oauthlib.common.urldecode` raises a ValueError if the provided query string contains a "'" character.

```
ValueError: Error trying to decode a non urlencoded string. Found invalid characters: set([u"'"]) in the string: 'url=Schr%C3%B6dinger's%20cat'. Please ensure the request/response body is x-www-form-urlencoded.
```

Per [RFC 3986 section 3.4](
https://tools.ietf.org/html/rfc3986#section-3.4), query strings should be allowed to include the characters defined as `pchar` which in turn allows for characters defined as `sub-delims`.  This includes the "'" character.

Discussion:

Patch:
diff --git a/oauthlib/common.py b/oauthlib/common.py
index f25656f..c1180e6 100644
--- a/oauthlib/common.py
+++ b/oauthlib/common.py
@@ -114,7 +114,7 @@ def decode_params_utf8(params):
     return decoded
 
 
-urlencoded = set(always_safe) | set('=&;:%+~,*@!()/?')
+urlencoded = set(always_safe) | set('=&;:%+~,*@!()/?\'$')
 
 
 def urldecode(query):


Test patch:
diff --git a/tests/test_common.py b/tests/test_common.py
index b0ea20d..fb4bd5b 100644
--- a/tests/test_common.py
+++ b/tests/test_common.py
@@ -39,6 +39,8 @@ class EncodingTest(TestCase):
         self.assertItemsEqual(urldecode('foo=bar@spam'), [('foo', 'bar@spam')])
         self.assertItemsEqual(urldecode('foo=bar/baz'), [('foo', 'bar/baz')])
         self.assertItemsEqual(urldecode('foo=bar?baz'), [('foo', 'bar?baz')])
+        self.assertItemsEqual(urldecode('foo=bar\'s'), [('foo', 'bar\'s')])
+        self.assertItemsEqual(urldecode('foo=$'), [('foo', '$')])
         self.assertRaises(ValueError, urldecode, 'foo bar')
         self.assertRaises(ValueError, urldecode, '%R')
         self.assertRaises(ValueError, urldecode, '%RA')