shithub: libmujs

Download patch

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);