ref: 9321f8fec69afe99e15c1e06ad588d319fa7a1e7
parent: e676a871f07b0d80c6791a2db0b4b361f277d8e8
author: Tor Andersson <tor.andersson@gmail.com>
date: Wed Apr 19 19:49:27 EDT 2017
Check for cyclic structures in JSON.stringify.
--- a/json.c
+++ b/json.c
@@ -210,10 +210,15 @@
{
const char *key;
int save;
- int n = 0;
+ int i, n;
- /* TODO: check stack for duplicate value (cyclical structure) */
+ n = js_gettop(J) - 1;
+ for (i = 4; i < n; ++i)
+ if (js_isobject(J, i))
+ if (js_toobject(J, i) == js_toobject(J, -1))
+ js_typeerror(J, "cyclic object value");
+ n = 0;
js_putc(J, sb, '{');
js_pushiterator(J, -1, 1);
while ((key = js_nextiterator(J, -1))) {
@@ -237,17 +242,21 @@
static void fmtarray(js_State *J, js_Buffer **sb, const char *gap, int level)
{
- int n, k;
+ int n, i;
char buf[32];
- /* TODO: check stack for duplicate value (cyclical structure) */
+ n = js_gettop(J) - 1;
+ for (i = 4; i < n; ++i)
+ if (js_isobject(J, i))
+ if (js_toobject(J, i) == js_toobject(J, -1))
+ js_typeerror(J, "cyclic object value");
js_putc(J, sb, '[');
n = js_getlength(J, -1);
- for (k = 0; k < n; ++k) {
- if (k) js_putc(J, sb, ',');
+ for (i = 0; i < n; ++i) {
+ if (i) js_putc(J, sb, ',');
if (gap) fmtindent(J, sb, gap, level + 1);
- if (!fmtvalue(J, sb, js_itoa(buf, k), gap, level + 1))
+ if (!fmtvalue(J, sb, js_itoa(buf, i), gap, level + 1))
js_puts(J, sb, "null");
}
if (gap && n) fmtindent(J, sb, gap, level);