Skip to content

Commit

Permalink
Fix issues serializing lists of primitives
Browse files Browse the repository at this point in the history
  • Loading branch information
yaakov-h committed Jan 13, 2018
1 parent b8f1031 commit 7cdb8b0
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
"test"
{
"Ints"
{
"0" "1"
"1" "2"
"2" "1"
}
"Strings"
{
"0" "test"
"1" "test"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System.IO;
using System.Collections.Generic;
using System.IO;
using System.Text;
using NUnit.Framework;

namespace ValveKeyValue.Test
Expand Down Expand Up @@ -33,11 +35,40 @@ public void ThrowsException()
}
}

[Test]
public void DuplicatePrimitiveValuesAreNotCircularObjectReference()
{
var dataObject = new DataObjectWithList
{
Strings = { "test", "test" },
Ints = { 1, 2, 1 }
};

string text;
using (var ms = new MemoryStream())
using (var reader = new StreamReader(ms, Encoding.UTF8))
{
KVSerializer.Create(KVSerializationFormat.KeyValues1Text).Serialize(ms, dataObject, "test");

ms.Seek(0, SeekOrigin.Begin);
text = reader.ReadToEnd();
}

var expected = TestDataHelper.ReadTextResource("Text.non_circular_list.vdf");
Assert.That(text, Is.EqualTo(expected));
}

class DataObject
{
public string Name { get; set; }

public DataObject Other { get; set; }
}

public class DataObjectWithList
{
public List<string> Strings { get; set; } = new List<string>();
public List<int> Ints { get; set; } = new List<int>();
}
}
}
12 changes: 11 additions & 1 deletion ValveKeyValue/ValveKeyValue/ObjectCopier.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,11 +74,16 @@ static KVObject FromObjectCore<TObject>(TObject managedObject, string topLevelNa
Require.NotNull(reflector, nameof(reflector));
Require.NotNull(visitedObjects, nameof(visitedObjects));

if (!visitedObjects.Add(managedObject))
if (!typeof(TObject).IsValueType && typeof(TObject) != typeof(string) && !visitedObjects.Add(managedObject))
{
throw new KeyValueException("Serialization failed - circular object reference detected.");
}

if (typeof(IConvertible).IsAssignableFrom(typeof(TObject)))
{
return new KVObject(topLevelName, (string)Convert.ChangeType(managedObject, typeof(string)));
}

var childObjects = new List<KVObject>();

if (typeof(IDictionary).IsAssignableFrom(typeof(TObject)))
Expand Down Expand Up @@ -106,6 +111,11 @@ static KVObject FromObjectCore<TObject>(TObject managedObject, string topLevelNa
{
foreach (var member in reflector.GetMembers(managedObject).OrderBy(p => p.Name))
{
if (!member.MemberType.IsValueType && member.Value is null)
{
continue;
}

var name = member.Name;
if (!member.IsExplicitName && name.Length > 0 && char.IsUpper(name[0]))
{
Expand Down

0 comments on commit 7cdb8b0

Please sign in to comment.