Merge pull request #132 from ildar-shaimordanov/master

Detect cyclic objects
This commit is contained in:
Douglas Crockford 2022-10-30 05:34:55 -07:00 committed by GitHub
commit 8da84c4041
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -1,5 +1,5 @@
// json2.js
// 2017-06-12
// 2022-10-30
// Public Domain.
// NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
@ -231,6 +231,29 @@ if (typeof JSON !== "object") {
}
// This variable is initialized with an empty array every time
// JSON.stringify() is invoked and checked by the str() function. It's
// used to keep references to object structures and capture cyclic
// objects. Every new object is checked for its existence in this
// array. If it's found it means the JSON object is cyclic and we have
// to stop execution and throw a TypeError accordingly the ECMA262
// (see NOTE 1 by the link https://tc39.es/ecma262/#sec-json.stringify).
var seen;
// Emulate [].includes(). It's actual for old-fashioned JScript.
function includes(array, value) {
var i;
for (i = 0; i < array.length; i += 1) {
if (value === array[i]) {
return true;
}
}
return false;
}
function str(key, holder) {
// Produce a string from holder[key].
@ -295,6 +318,16 @@ if (typeof JSON !== "object") {
return "null";
}
// Check the value is not circular object. Otherwise throw TypeError.
if (includes(seen, value)) {
throw new TypeError("Converting circular structure to JSON");
}
// Keep the value for the further check on circular references.
seen.push(value);
// Make an array to hold the partial results of stringifying this object value.
gap += indent;
@ -428,6 +461,10 @@ if (typeof JSON !== "object") {
throw new Error("JSON.stringify");
}
// Initialize the reference keeper.
seen = [];
// Make a fake root object containing our value under the key of "".
// Return the result of stringifying the value.