|
1 | 1 | // json2.js |
2 | | -// 2017-06-12 |
| 2 | +// 2022-10-30 |
3 | 3 | // Public Domain. |
4 | 4 | // NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. |
5 | 5 |
|
@@ -231,6 +231,29 @@ if (typeof JSON !== "object") { |
231 | 231 | } |
232 | 232 |
|
233 | 233 |
|
| 234 | +// This variable is initialized with an empty array every time |
| 235 | +// JSON.stringify() is invoked and checked by the str() function. It's |
| 236 | +// used to keep references to object structures and capture cyclic |
| 237 | +// objects. Every new object is checked for its existence in this |
| 238 | +// array. If it's found it means the JSON object is cyclic and we have |
| 239 | +// to stop execution and throw a TypeError accordingly the ECMA262 |
| 240 | +// (see NOTE 1 by the link https://tc39.es/ecma262/#sec-json.stringify). |
| 241 | + |
| 242 | + var seen; |
| 243 | + |
| 244 | +// Emulate [].includes(). It's actual for old-fashioned JScript. |
| 245 | + |
| 246 | + function includes(array, value) { |
| 247 | + var i; |
| 248 | + for (i = 0; i < array.length; i += 1) { |
| 249 | + if (value === array[i]) { |
| 250 | + return true; |
| 251 | + } |
| 252 | + } |
| 253 | + return false; |
| 254 | + } |
| 255 | + |
| 256 | + |
234 | 257 | function str(key, holder) { |
235 | 258 |
|
236 | 259 | // Produce a string from holder[key]. |
@@ -295,6 +318,16 @@ if (typeof JSON !== "object") { |
295 | 318 | return "null"; |
296 | 319 | } |
297 | 320 |
|
| 321 | +// Check the value is not circular object. Otherwise throw TypeError. |
| 322 | + |
| 323 | + if (includes(seen, value)) { |
| 324 | + throw new TypeError("Converting circular structure to JSON"); |
| 325 | + } |
| 326 | + |
| 327 | +// Keep the value for the further check on circular references. |
| 328 | + |
| 329 | + seen.push(value); |
| 330 | + |
298 | 331 | // Make an array to hold the partial results of stringifying this object value. |
299 | 332 |
|
300 | 333 | gap += indent; |
@@ -428,6 +461,10 @@ if (typeof JSON !== "object") { |
428 | 461 | throw new Error("JSON.stringify"); |
429 | 462 | } |
430 | 463 |
|
| 464 | +// Initialize the reference keeper. |
| 465 | + |
| 466 | + seen = []; |
| 467 | + |
431 | 468 | // Make a fake root object containing our value under the key of "". |
432 | 469 | // Return the result of stringifying the value. |
433 | 470 |
|
|
0 commit comments