Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/Newtonsoft.Json.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Newton-King <james@newtonking.com>2012-03-07 13:59:10 +0400
committerJames Newton-King <james@newtonking.com>2012-03-07 13:59:10 +0400
commitd32061cd1659203acacb8bca9e08d15c70d7d3d8 (patch)
tree952f0578909f32ec8c6ee6c6ee6e113afbf5f81f
parentc7f52087690ea8e54e52366f1be2506cb313e45e (diff)
-Improved performance issue fix for deeply nested LINQ to JSON objects
-rw-r--r--Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs9
-rw-r--r--Src/Newtonsoft.Json.Tests/PerformanceTests.cs17
-rw-r--r--Src/Newtonsoft.Json/Linq/JContainer.cs29
3 files changed, 34 insertions, 21 deletions
diff --git a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
index a25c7fc..dc6cd1b 100644
--- a/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
+++ b/Src/Newtonsoft.Json.Tests/Linq/JArrayTests.cs
@@ -21,6 +21,15 @@ namespace Newtonsoft.Json.Tests.Linq
}
[Test]
+ public void AddToSelf()
+ {
+ JArray a = new JArray();
+ a.Add(a);
+
+ Assert.IsFalse(ReferenceEquals(a[0], a));
+ }
+
+ [Test]
public void Contains()
{
JValue v = new JValue(1);
diff --git a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
index 57c9e8e..7d3b8bd 100644
--- a/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
+++ b/Src/Newtonsoft.Json.Tests/PerformanceTests.cs
@@ -704,6 +704,21 @@ namespace Newtonsoft.Json.Tests
}
[Test]
+ public void RecursiveLoop()
+ {
+ JArray a1 = new JArray();
+ JArray a2 = new JArray();
+ JArray a3 = new JArray();
+ JArray a4 = new JArray();
+
+ a1.Add(a2);
+ a2.Add(a3);
+ a3.Add(a4);
+
+
+ }
+
+ [Test]
public void NestedJToken()
{
Stopwatch sw;
@@ -716,7 +731,7 @@ namespace Newtonsoft.Json.Tests
for (int j = 0; j < i; j++)
{
JArray temp = new JArray();
- ija.AddAndSkipParentCheck(temp);
+ ija.Add(temp);
ija = temp;
}
ija.Add(1);
diff --git a/Src/Newtonsoft.Json/Linq/JContainer.cs b/Src/Newtonsoft.Json/Linq/JContainer.cs
index d1f83e0..ec992fe 100644
--- a/Src/Newtonsoft.Json/Linq/JContainer.cs
+++ b/Src/Newtonsoft.Json/Linq/JContainer.cs
@@ -266,27 +266,16 @@ namespace Newtonsoft.Json.Linq
if (item == null)
return new JValue((object) null);
- if (item.Parent != null)
- {
+ if (skipParentCheck)
+ return item;
+
+ // to avoid a token having multiple parents or creating a recursive loop, create a copy if...
+ // the item already has a parent
+ // the item is being added to itself
+ // the item is being added to the root parent of itself
+ if (item.Parent != null || item == this || (item.HasValues && Root == item))
item = item.CloneToken();
- }
- else
- {
- // check whether attempting to add a token to itself
- // not possible with a value, only a container
- if (item is JContainer && !skipParentCheck)
- {
- JContainer parent = this;
- while (parent.Parent != null)
- {
- parent = parent.Parent;
- }
- if (item == parent)
- {
- item = item.CloneToken();
- }
- }
- }
+
return item;
}