Skip to content

Commit

Permalink
[Fix] parse: Fix parsing when the global Object prototype is frozen
Browse files Browse the repository at this point in the history
  • Loading branch information
jportner authored and ljharb committed May 7, 2023
1 parent 9dca37f commit 7895b94
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 3 deletions.
3 changes: 2 additions & 1 deletion lib/parse.js
Expand Up @@ -49,7 +49,8 @@ var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓')
var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓')

var parseValues = function parseQueryStringValues(str, options) {
var obj = {};
var obj = { __proto__: null };

var cleanStr = options.ignoreQueryPrefix ? str.replace(/^\?/, '') : str;
var limit = options.parameterLimit === Infinity ? undefined : options.parameterLimit;
var parts = cleanStr.split(options.delimiter, limit);
Expand Down
3 changes: 3 additions & 0 deletions package.json
Expand Up @@ -40,10 +40,13 @@
"eslint": "=8.8.0",
"evalmd": "^0.0.19",
"for-each": "^0.3.3",
"has-override-mistake": "^1.0.0",
"has-property-descriptors": "^1.0.0",
"has-symbols": "^1.0.3",
"iconv-lite": "^0.5.1",
"in-publish": "^2.0.1",
"mkdirp": "^0.5.5",
"mock-property": "^1.0.0",
"npmignore": "^0.3.0",
"nyc": "^10.3.2",
"object-inspect": "^1.12.3",
Expand Down
36 changes: 34 additions & 2 deletions test/parse.js
@@ -1,11 +1,15 @@
'use strict';

var test = require('tape');
var qs = require('../');
var utils = require('../lib/utils');
var hasPropertyDescriptors = require('has-property-descriptors')();
var iconv = require('iconv-lite');
var mockProperty = require('mock-property');
var hasOverrideMistake = require('has-override-mistake')();
var SaferBuffer = require('safer-buffer').Buffer;

var qs = require('../');
var utils = require('../lib/utils');

test('parse()', function (t) {
t.test('parses a simple string', function (st) {
st.deepEqual(qs.parse('0=foo'), { 0: 'foo' });
Expand Down Expand Up @@ -601,6 +605,34 @@ test('parse()', function (t) {
st.end();
});

t.test('does not crash when the global Object prototype is frozen', { skip: !hasPropertyDescriptors || !hasOverrideMistake }, function (st) {
// We can't actually freeze the global Object prototype as that will interfere with other tests, and once an object is frozen, it
// can't be unfrozen. Instead, we add a new non-writable property to simulate this.
st.teardown(mockProperty(Object.prototype, 'frozenProp', { value: 'foo', nonWritable: true, nonEnumerable: true }));

st['throws'](
function () {
var obj = {};
obj.frozenProp = 'bar';
},
// node < 6 has a different error message
/^TypeError: Cannot assign to read only property 'frozenProp' of (?:object '#<Object>'|#<Object>)/,
'regular assignment of an inherited non-writable property throws'
);

var parsed;
st.doesNotThrow(
function () {
parsed = qs.parse('frozenProp', { allowPrototypes: false });
},
'parsing a nonwritable Object.prototype property does not throw'
);

st.deepEqual(parsed, {}, 'bare "frozenProp" results in {}');

st.end();
});

t.test('params starting with a closing bracket', function (st) {
st.deepEqual(qs.parse(']=toString'), { ']': 'toString' });
st.deepEqual(qs.parse(']]=toString'), { ']]': 'toString' });
Expand Down

0 comments on commit 7895b94

Please sign in to comment.