From 2875435ce8052f2b57adcf3c918657a66d5b214e Mon Sep 17 00:00:00 2001 From: D3-LucaPiombino Date: Thu, 23 Oct 2014 16:02:44 +0200 Subject: [PATCH] [FIXED]: Issue #401 - Use reference equality to compare object instances when checking for circular references in a object graph. --- .../PreserveReferencesHandlingTests.cs | 34 +++++++++++++++++++ .../JsonSerializerInternalWriter.cs | 2 +- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs index 4bbe6214f..0121a7463 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/PreserveReferencesHandlingTests.cs @@ -1065,6 +1065,17 @@ public void DuplicateId() MetadataPropertyHandling = MetadataPropertyHandling.Default }), "Error reading object reference '1'. Path 'Data.Prop2.MyProperty', line 9, position 20."); } + + [Test] + public void ShouldCheckForCircularReferencesUsingReferenceEquality() + { + var source = new ValueContainer + { + Value = new object() + }; + + string json = JsonConvert.SerializeObject(source, Formatting.Indented); + } } public class PropertyItemIsReferenceBody @@ -1108,4 +1119,27 @@ public class ReferenceObject public string String { get; set; } public int Integer { get; set; } } + + public class ValueContainer + { + public object Value; + + public override bool Equals(object obj) + { + if (obj == null) + return false; + + var otherContainer = obj as ValueContainer; + + if (otherContainer != null) + return EqualityComparer.Default.Equals(Value, otherContainer.Value); + + return EqualityComparer.Default.Equals(Value, obj); + } + + public override int GetHashCode() + { + return EqualityComparer.Default.GetHashCode(Value); + } + } } \ No newline at end of file diff --git a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs index 84c5358f6..7c53a59b3 100644 --- a/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs +++ b/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalWriter.cs @@ -265,7 +265,7 @@ private bool CheckForCircularReference(JsonWriter writer, object value, JsonProp if (referenceLoopHandling == null && containerContract != null) referenceLoopHandling = containerContract.ItemReferenceLoopHandling; - if (_serializeStack.IndexOf(value) != -1) + if (_serializeStack.IndexOf(itemOnStack => object.ReferenceEquals(itemOnStack,value)) != -1) { string message = "Self referencing loop detected"; if (property != null)