diff --git a/lib/querystring.js b/lib/querystring.js index efd2969229..f48ee5802f 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -29,21 +29,22 @@ QueryString.stringify = QueryString.encode = function (obj, sep, eq, munge, name munge = typeof munge == "undefined" || munge; sep = sep || "&"; eq = eq || "="; - if (obj == null || typeof obj == "function") { + var type = Object.prototype.toString.call(obj); + if (obj == null || type == "[object Function]" || type == "[object Number]" && !isFinite(obj)) { return name ? QueryString.escape(name) + eq : ""; } - if (isBool(obj)) { - obj = +obj; - } - if (isNumber(obj) || isString(obj)) { - return QueryString.escape(name) + eq + QueryString.escape(obj); - } - if (isA(obj, [])) { - name = name + (munge ? "[]" : ""); - return obj.map(function (item) { - return QueryString.stringify(item, sep, eq, munge, name); - }).join(sep); + switch (type) { + case '[object Boolean]': + obj = +obj; // fall through + case '[object Number]': + case '[object String]': + return QueryString.escape(name) + eq + QueryString.escape(obj); + case '[object Array]': + name = name + (munge ? "[]" : ""); + return obj.map(function (item) { + return QueryString.stringify(item, sep, eq, munge, name); + }).join(sep); } // now we know it's an object. @@ -109,20 +110,3 @@ QueryString.parse = QueryString.decode = function (qs, sep, eq) { }); return obj; }; - -function isA (thing, canon) { - // special case for null and undefined - if (thing == null || canon == null) { - return thing === canon; - } - return Object.getPrototypeOf(Object(thing)) == Object.getPrototypeOf(Object(canon)); -} -function isBool (thing) { - return isA(thing, true); -} -function isNumber (thing) { - return isA(thing, 0) && isFinite(thing); -} -function isString (thing) { - return isA(thing, ""); -} \ No newline at end of file diff --git a/test/simple/test-querystring.js b/test/simple/test-querystring.js index 961c1ec35e..40f68d83da 100644 --- a/test/simple/test-querystring.js +++ b/test/simple/test-querystring.js @@ -67,17 +67,24 @@ var qsWeirdObjects = [ [ {d:Date}, "d=", {"d":""} ], [ {f:new Boolean(false), t:new Boolean(true)}, "f=0&t=1", {"f":0, "t":1} ], [ {f:false, t:true}, "f=0&t=1", {"f":0, "t":1} ], + [ {n:null}, "n=", {"n":""} ], + [ {nan:NaN}, "nan=", {"nan":""} ], + [ {inf:Infinity}, "inf=", {"inf":""} ] ]; } +var Script = process.binding('evals').Script; +var foreignObject = Script.runInContext('({"foo": ["bar", "baz"]})', Script.createContext()); + var qsNoMungeTestCases = [ ["", {}], ["foo=bar&foo=baz", {"foo": ["bar", "baz"]}], + ["foo=bar&foo=baz", foreignObject], ["blah=burp", {"blah": "burp"}], ["gragh=1&gragh=3&goo=2", {"gragh": ["1", "3"], "goo": "2"}], ["frappucino=muffin&goat%5B%5D=scone&pond=moose", {"frappucino": "muffin", "goat[]": "scone", "pond": "moose"}], - ["obj%5Btrololol%5D=yes&obj%5Blololo%5D=no", {"obj": {"trololol": "yes", "lololo": "no"}}], + ["obj%5Btrololol%5D=yes&obj%5Blololo%5D=no", {"obj": {"trololol": "yes", "lololo": "no"}}] ]; // test that the canonical qs is parsed properly.