diff --git a/benchmark/querystring/querystring-parse-proto.js b/benchmark/querystring/querystring-parse-proto.js new file mode 100644 index 00000000000000..aaf9cfa97946f9 --- /dev/null +++ b/benchmark/querystring/querystring-parse-proto.js @@ -0,0 +1,25 @@ +'use strict'; +var common = require('../common.js'); +var querystring = require('querystring'); +var v8 = require('v8'); + +var bench = common.createBenchmark(main, { + n: [1e6], +}); + +function main(conf) { + var n = conf.n | 0; + + const input = 'a=b&__proto__=1'; + + v8.setFlagsFromString('--allow_natives_syntax'); + querystring.parse(input); + eval('%OptimizeFunctionOnNextCall(querystring.parse)'); + querystring.parse(input); + + var i; + bench.start(); + for (i = 0; i < n; i += 1) + querystring.parse(input); + bench.end(n); +} diff --git a/lib/querystring.js b/lib/querystring.js index ad1b5861a0f063..e628a626315b15 100644 --- a/lib/querystring.js +++ b/lib/querystring.js @@ -212,12 +212,13 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { sep = sep || '&'; eq = eq || '='; - const obj = {}; - if (typeof qs !== 'string' || qs.length === 0) { - return obj; + return {}; } + var obj = {}; + Object.setPrototypeOf(obj, null); + if (typeof sep !== 'string') sep += ''; @@ -387,6 +388,7 @@ QueryString.parse = QueryString.decode = function(qs, sep, eq, options) { } } + Object.setPrototypeOf(obj, Object.prototype); return obj; }; diff --git a/test/parallel/test-querystring-proto.js b/test/parallel/test-querystring-proto.js new file mode 100644 index 00000000000000..0695a30d2f6050 --- /dev/null +++ b/test/parallel/test-querystring-proto.js @@ -0,0 +1,13 @@ +/* eslint-disable no-proto */ +'use strict'; + +require('../common'); +const assert = require('assert'); +const qs = require('querystring'); + +const obj = qs.parse('a=b&__proto__=1'); + +assert.equal(obj.a, 'b'); +assert.equal(obj.__proto__, 1); +assert(typeof Object.getPrototypeOf(obj) === 'object'); +assert.strictEqual(Object.getPrototypeOf(obj), Object.prototype);