Browse Source

Fixing cyclic reference handling in Json serialization (#499)

Fixes #351
Pranay Kumar 7 years ago
parent
commit
2e87a5643c
2 changed files with 40 additions and 0 deletions
  1. 39 0
      Jint.Tests/Runtime/EngineTests.cs
  2. 1 0
      Jint/Native/Json/JsonSerializer.cs

+ 39 - 0
Jint.Tests/Runtime/EngineTests.cs

@@ -1976,6 +1976,45 @@ namespace Jint.Tests.Runtime
             Assert.True(val.AsString() == "53.6841659");
         }
 
+        [Fact]
+        public void ShouldStringifyObjectWithPropertiesToSameRef()
+        {
+            var engine = new Engine();
+            var res = engine.Execute(@"
+                var obj = {
+                    a : [],
+                    a1 : ['str'],
+                    a2 : {},
+                    a3 : { 'prop' : 'val' }
+                };
+                obj.b = obj.a;
+                obj.b1 = obj.a1;
+                JSON.stringify(obj);
+            ").GetCompletionValue();
+
+            Assert.True(res == "{\"a\":[],\"a1\":[\"str\"],\"a2\":{},\"a3\":{\"prop\":\"val\"},\"b\":[],\"b1\":[\"str\"]}");
+        }
+
+        [Fact]
+        public void ShouldThrowOnSerializingCyclicRefObject()
+        {
+            var engine = new Engine();
+            var res = engine.Execute(@"
+                (function(){
+                    try{
+                        a = [];
+                        a[0] = a;
+                        my_text = JSON.stringify(a);
+                    }
+                    catch(ex){
+                        return ex.message;
+                    }
+                })();
+            ").GetCompletionValue();
+
+            Assert.True(res == "Cyclic reference detected.");
+        }
+
         [Theory]
         [InlineData("", "escape('')")]
         [InlineData("%u0100%u0101%u0102", "escape('\u0100\u0101\u0102')")]

+ 1 - 0
Jint/Native/Json/JsonSerializer.cs

@@ -272,6 +272,7 @@ namespace Jint.Native.Json
             }
             if (partial.Count == 0)
             {
+                _stack.Pop();
                 return "[]";
             }