From e58e9186f8e36d0655bdc0a9087a118414ea9bcb Mon Sep 17 00:00:00 2001 From: Isiah Meadows Date: Sat, 27 Jul 2019 20:53:19 -0400 Subject: [PATCH] Take 2 --- querystring/parse.js | 11 +++++------ querystring/tests/test-parseQueryString.js | 7 +++++-- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/querystring/parse.js b/querystring/parse.js index 60cf454de..2a44e737c 100644 --- a/querystring/parse.js +++ b/querystring/parse.js @@ -19,7 +19,6 @@ module.exports = function(string) { for (var j = 0; j < levels.length; j++) { var level = levels[j], nextLevel = levels[j + 1] var isNumber = nextLevel == "" || !isNaN(parseInt(nextLevel, 10)) - var isValue = j === levels.length - 1 if (level === "") { var key = levels.slice(0, j).join() if (counters[key] == null) { @@ -29,15 +28,15 @@ module.exports = function(string) { } // Disallow direct prototype pollution else if (level === "__proto__") break - if (isValue) cursor[level] = value + if (j === levels.length - 1) cursor[level] = value else { // Read own properties exclusively to disallow indirect // prototype pollution - value = Object.getOwnPropertyDescriptor(cursor, level) - if (value != null) value = value.value - if (value == null) value = cursor[level] = isNumber ? [] : {} + var desc = Object.getOwnPropertyDescriptor(cursor, level) + if (desc != null) desc = desc.value + if (desc == null) cursor[level] = desc = isNumber ? [] : {} + cursor = desc } - cursor = value } } return data diff --git a/querystring/tests/test-parseQueryString.js b/querystring/tests/test-parseQueryString.js index 844af1b42..ca20e2328 100644 --- a/querystring/tests/test-parseQueryString.js +++ b/querystring/tests/test-parseQueryString.js @@ -105,8 +105,11 @@ o.spec("parseQueryString", function() { }) o("doesn't pollute prototype indirectly, retains `constructor`", function() { var prev = Object.prototype.toString - var data = parseQueryString("constructor%5Bprototype%5D%5BtoString%5D=123") + var data = parseQueryString("a=b&constructor%5Bprototype%5D%5BtoString%5D=123") o(Object.prototype.toString).equals(prev) - o(data).deepEquals({a: "b"}) + // The deep matcher is borked here. + o(Object.keys(data)).deepEquals(["a", "constructor"]) + o(data.a).equals("b") + o(data.constructor).deepEquals({prototype: {toString: "123"}}) }) })