Skip to content

Commit 2f4771e

Browse files
committed
Better recursive encoding protection
1 parent 1fe307c commit 2f4771e

File tree

3 files changed

+21
-9
lines changed

3 files changed

+21
-9
lines changed

src/ParseObject.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,13 +367,14 @@ export default class ParseObject {
367367
* @return {Object}
368368
*/
369369
toJSON(): AttributeMap {
370+
var seenEntry = this.id ? this.className + ':' + this.id : this;
370371
var json = {};
371372
var attrs = this.attributes;
372373
for (var attr in attrs) {
373374
if ((attr === 'createdAt' || attr === 'updatedAt') && attrs[attr].toJSON) {
374375
json[attr] = attrs[attr].toJSON();
375376
} else {
376-
json[attr] = encode(attrs[attr], false, true);
377+
json[attr] = encode(attrs[attr], false, false, [seenEntry]);
377378
}
378379
}
379380
var pending = this._getPendingOps();

src/__tests__/ParseObject-test.js

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -558,9 +558,14 @@ describe('ParseObject', () => {
558558
expect(o.toJSON()).toEqual({
559559
objectId: 'recurParent',
560560
child: {
561-
__type: 'Pointer',
561+
__type: 'Object',
562562
className: 'Item',
563-
objectId: 'recurChild'
563+
objectId: 'recurChild',
564+
parent: {
565+
__type: 'Pointer',
566+
className: 'Item',
567+
objectId: 'recurParent'
568+
}
564569
}
565570
});
566571
});

src/encode.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,23 @@ function encode(value: mixed, disallowObjects: boolean, forcePointers: boolean,
2323
if (disallowObjects) {
2424
throw new Error('Parse Objects not allowed here');
2525
}
26+
var seenEntry = value.id ? value.className + ':' + value.id : value;
2627
if (forcePointers ||
2728
!seen ||
28-
seen.indexOf(value) > -1 ||
29+
seen.indexOf(seenEntry) > -1 ||
2930
value.dirty() ||
3031
Object.keys(value._getServerData()).length < 1
3132
) {
3233
return value.toPointer();
3334
}
34-
seen = seen.concat(value);
35-
var json = value._toFullJSON(seen);
36-
return encode(json, disallowObjects, forcePointers, seen);
35+
seen = seen.concat(seenEntry);
36+
var json = encode(value.attributes, disallowObjects, forcePointers, seen);
37+
json.className = value.className;
38+
json.__type = 'Object';
39+
if (value.id) {
40+
json.objectId = value.id;
41+
}
42+
return json;
3743
}
3844
if (value instanceof Op ||
3945
value instanceof ParseACL ||
@@ -75,6 +81,6 @@ function encode(value: mixed, disallowObjects: boolean, forcePointers: boolean,
7581
return value;
7682
}
7783

78-
export default function(value: mixed, disallowObjects?: boolean, forcePointers?: boolean) {
79-
return encode(value, !!disallowObjects, !!forcePointers, []);
84+
export default function(value: mixed, disallowObjects?: boolean, forcePointers?: boolean, seen?: Array<mixed>) {
85+
return encode(value, !!disallowObjects, !!forcePointers, seen || []);
8086
}

0 commit comments

Comments
 (0)