querystring: fix unescape override
authorTristan Berger <tristan.berger@gmail.com>
Tue, 26 Aug 2014 08:39:25 +0000 (04:39 -0400)
committerFedor Indutny <fedor@indutny.com>
Wed, 27 Aug 2014 09:49:16 +0000 (13:49 +0400)
Documentation states that `querystring.unescape` may be overridden to
replace unescaper during parsing. However, the function was only
being used as a fallback for when the native decoder throws (on a
malformed URL). This patch moves the call to the native function and
the try/catch around it into querystring.unescape then has the parser
always invoke it, so that an override will always be used.

Fixes #4055

Reviewed-By: Fedor Indutny <fedor@indutny.com>
lib/querystring.js
test/simple/test-querystring.js

index 0ab739a..f8c7921 100644 (file)
@@ -105,7 +105,11 @@ QueryString.unescapeBuffer = function(s, decodeSpaces) {
 
 
 QueryString.unescape = function(s, decodeSpaces) {
-  return QueryString.unescapeBuffer(s, decodeSpaces).toString();
+  try {
+    return decodeURIComponent(s);
+  } catch (e) {
+    return QueryString.unescapeBuffer(s, decodeSpaces).toString();
+  }
 };
 
 
@@ -193,13 +197,8 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) {
       vstr = '';
     }
 
-    try {
-      k = decodeURIComponent(kstr);
-      v = decodeURIComponent(vstr);
-    } catch (e) {
-      k = QueryString.unescape(kstr, true);
-      v = QueryString.unescape(vstr, true);
-    }
+    k = QueryString.unescape(kstr, true);
+    v = QueryString.unescape(vstr, true);
 
     if (!hasOwnProperty(obj, k)) {
       obj[k] = v;
index 2d86625..545c507 100644 (file)
@@ -229,3 +229,11 @@ assert.equal(0xeb, b[16]);
 assert.equal(0xd8, b[17]);
 assert.equal(0xa2, b[18]);
 assert.equal(0xe6, b[19]);
+
+// test overriding .unescape
+var prevUnescape = qs.unescape;
+qs.unescape = function (str) {
+  return str.replace(/o/g, '_');
+};
+assert.deepEqual(qs.parse('foo=bor'), {f__: 'b_r'});
+qs.unescape = prevUnescape;