Skip to content

Commit

Permalink
account for circular references properly, closes #31
Browse files Browse the repository at this point in the history
  • Loading branch information
nlf committed Aug 28, 2014
1 parent 9bc7567 commit 130bdc2
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 20 deletions.
59 changes: 39 additions & 20 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ exports.arrayToObject = function (source) {
};


exports.clone = function (source) {
exports.clone = function (source, refs) {

if (typeof source !== 'object' ||
source === null) {
Expand All @@ -32,14 +32,24 @@ exports.clone = function (source) {
return source.toString();
}

var obj = Array.isArray(source) ? [] : {};
refs = refs || [];

var lookup = refs.indexOf(source);
if (lookup !== -1) {
return refs[lookup];
}

var copy = Array.isArray(source) ? [] : source;

refs.push(source);

for (var i in source) {
if (source.hasOwnProperty(i)) {
obj[i] = exports.clone(source[i]);
copy[i] = exports.clone(source[i], refs);
}
}

return obj;
return copy;
};


Expand Down Expand Up @@ -108,32 +118,41 @@ exports.decode = function (str) {
};


exports.compact = function (obj) {
exports.compact = function (obj, refs) {

if (typeof obj !== 'object' ||
obj === null) {

if (typeof obj !== 'object' || obj === null) {
return obj;
}

var compacted = {};
refs = refs || [];
var lookup = refs.indexOf(obj);
if (lookup !== -1) {
return refs[lookup];
}

for (var key in obj) {
if (obj.hasOwnProperty(key)) {
if (Array.isArray(obj[key])) {
compacted[key] = [];
refs.push(obj);

for (var i = 0, l = obj[key].length; i < l; i++) {
if (typeof obj[key][i] !== 'undefined') {
compacted[key].push(obj[key][i]);
}
}
}
else {
compacted[key] = exports.compact(obj[key]);
if (Array.isArray(obj)) {
var compacted = [];

for (var i = 0, l = obj.length; i < l; ++i) {
if (typeof obj[i] !== 'undefined') {
compacted.push(obj[i]);
}
}

return compacted;
}

for (var key in obj) {
if (obj.hasOwnProperty(key)) {
obj[key] = exports.compact(obj[key], refs);
}
}

return compacted;
return obj;
};


Expand Down
11 changes: 11 additions & 0 deletions test/parse.js
Original file line number Diff line number Diff line change
Expand Up @@ -337,4 +337,15 @@ describe('#parse', function () {
expect(Qs.parse('roomInfoList[0].childrenAges[0]=15&roomInfoList[0].numberOfAdults=2')).to.deep.equal({ roomInfoList: [['15', '2']] });
done();
});

it('does not crash when parsing circular references', function (done) {

var a = {};
a.b = a;
expect(function () {

Qs.parse({ 'foo[bar]': 'baz', 'foo[baz]': a });
}).to.not.throw(Error);
done();
});
});

0 comments on commit 130bdc2

Please sign in to comment.