Skip to content

Commit e0e2731

Browse files
author
Andrew Robinson
committed
Protect jsv deserialization from indexed properties, add some tests
1 parent 1ad7771 commit e0e2731

6 files changed

Lines changed: 316 additions & 1 deletion

File tree

src/ServiceStack.Text/Common/DeserializeType.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ private static DynamicMethod CreateDynamicSetMethod(MemberInfo memberInfo)
254254

255255
internal static SetPropertyDelegate GetSetPropertyMethod(Type type, PropertyInfo propertyInfo)
256256
{
257-
if (!propertyInfo.CanWrite) return null;
257+
if (!propertyInfo.CanWrite || propertyInfo.GetIndexParameters().Any()) return null;
258258

259259
#if SILVERLIGHT || MONOTOUCH || XBOX
260260
var setMethodInfo = propertyInfo.GetSetMethod(true);

tests/ServiceStack.Text.Tests/JsonTests/BasicJsonTests.cs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ public void Can_parse_json_with_nullable_valuetypes_that_has_included_null_value
7474
Assert.That(item.DateTime, Is.Null, "datetime");
7575
}
7676

77+
[Test]
78+
public void Can_parse_json_with_nulls_or_empty_string_in_nullables()
79+
{
80+
const string json = "{\"Int\":null,\"Boolean\":\"\"}";
81+
var value = JsonSerializer.DeserializeFromString<NullableValueTypes>(json);
82+
83+
Assert.That(value.Int, Is.EqualTo(null));
84+
Assert.That(value.Boolean, Is.EqualTo(null));
85+
}
86+
7787
[Test]
7888
public void Can_parse_json_with_nullable_valuetypes_that_has_no_value_specified()
7989
{
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Globalization;
4+
using System.Runtime.Serialization;
5+
using NUnit.Framework;
6+
using ServiceStack.Text.Tests.DynamicModels;
7+
8+
namespace ServiceStack.Text.Tests.JsonTests
9+
{
10+
[TestFixture]
11+
public class DictionaryTests
12+
{
13+
public class EdgeCaseProperties : Dictionary<string, string>
14+
{
15+
private const string Id = "id";
16+
17+
[DataMember]
18+
public int id
19+
{
20+
get
21+
{
22+
int value;
23+
return (ContainsKey(Id) && int.TryParse(this[Id], out value))
24+
? value
25+
: 0;
26+
}
27+
set { this[Id] = value.ToString(CultureInfo.InvariantCulture); }
28+
}
29+
30+
public static EdgeCaseProperties Create(int i)
31+
{
32+
var value = new EdgeCaseProperties { id = i };
33+
value[i.ToString()] = i.ToString();
34+
return value;
35+
}
36+
}
37+
38+
[Test]
39+
public void Can_Serialize()
40+
{
41+
var model = EdgeCaseProperties.Create(1);
42+
var s = JsonSerializer.SerializeToString(model);
43+
44+
Console.WriteLine(s);
45+
}
46+
47+
[Test]
48+
public void Can_Serialize_list()
49+
{
50+
var model = new List<EdgeCaseProperties>
51+
{
52+
EdgeCaseProperties.Create(1),
53+
EdgeCaseProperties.Create(2)
54+
};
55+
var s = JsonSerializer.SerializeToString(model);
56+
57+
Console.WriteLine(s);
58+
}
59+
60+
[Test]
61+
public void Can_Serialize_map()
62+
{
63+
var model = new Dictionary<string, EdgeCaseProperties>
64+
{
65+
{"A", EdgeCaseProperties.Create(1)},
66+
{"B", EdgeCaseProperties.Create(2)},
67+
};
68+
var s = JsonSerializer.SerializeToString(model);
69+
70+
Console.WriteLine(s);
71+
}
72+
73+
[Test]
74+
public void Can_Deserialize()
75+
{
76+
const string json = "{\"id\":\"1\",\"1\":\"1\"}";
77+
78+
var model = EdgeCaseProperties.Create(1);
79+
80+
var fromJson = JsonSerializer.DeserializeFromString<EdgeCaseProperties>(json);
81+
82+
Assert.That(fromJson, Is.EqualTo(model));
83+
}
84+
85+
[DataContract]
86+
public class Tree
87+
{
88+
[DataMember]
89+
public string Value { get; set; }
90+
91+
[DataMember]
92+
public List<Tree> Nodes { get; set; }
93+
}
94+
95+
[Test]
96+
public void CanSerializeAndDeserializeTree()
97+
{
98+
var original = new Tree
99+
{
100+
Value = "root",
101+
Nodes = new List<Tree>
102+
{
103+
new Tree {Value = "foo"},
104+
new Tree {Value = "bar"},
105+
new Tree {Value = "baz"}
106+
}
107+
};
108+
var json = original.ToJson();
109+
Console.WriteLine(json);
110+
var result = JsonSerializer.DeserializeFromString<Tree>(json);
111+
var resultJson = result.ToJson();
112+
Assert.AreEqual(json, resultJson);
113+
}
114+
}
115+
}

tests/ServiceStack.Text.Tests/JsvTests/JsvDeserializeTypeTest.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Reflection;
34
using NUnit.Framework;
45
using ServiceStack.Text.Common;
@@ -20,6 +21,19 @@ public void Get_setter_method_for_simple_properties()
2021
Assert.AreEqual("test", test.TestProperty);
2122
}
2223

24+
[Test]
25+
public void Get_setter_method_for_dictionary_properties()
26+
{
27+
var dict = new Dictionary<string, string>();
28+
Type type = typeof (Dictionary<string,string>);
29+
foreach (var propertyInfo in type.GetProperties()) {
30+
SetPropertyDelegate setMethod = JsvDeserializeType.GetSetPropertyMethod(type, propertyInfo);
31+
if (setMethod == null) continue;
32+
Console.WriteLine(propertyInfo.Name);
33+
setMethod.Invoke(dict, propertyInfo.Name);
34+
}
35+
}
36+
2337
private class Test
2438
{
2539
public string TestProperty { get; set; }

tests/ServiceStack.Text.Tests/ServiceStack.Text.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@
176176
<Compile Include="CsvStreamTests.cs" />
177177
<Compile Include="CsvTests\CustomHeaderTests.cs" />
178178
<Compile Include="JsonTests\ContractByInterfaceTests.cs" />
179+
<Compile Include="JsonTests\EdgeCasePropertyTypesTests.cs" />
179180
<Compile Include="JsonTests\JsonDateTimeTests.cs" />
180181
<Compile Include="JsonTests\PolymorphicListTests.cs" />
181182
<Compile Include="JsonTests\ThrowOnDeserializeErrorTest.cs" />
@@ -235,6 +236,7 @@
235236
<Compile Include="StringSerializerTranslationTests.cs" />
236237
<Compile Include="TestBase.cs" />
237238
<Compile Include="TypeConverterTests.cs" />
239+
<Compile Include="XmlSerializerTests.cs" />
238240
</ItemGroup>
239241
<ItemGroup>
240242
<BootstrapperPackage Include="Microsoft.Net.Client.3.5">
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
using System;
2+
using Northwind.Common.DataModel;
3+
using NUnit.Framework;
4+
using ServiceStack.Text.Tests.Support;
5+
6+
namespace ServiceStack.Text.Tests
7+
{
8+
[TestFixture]
9+
public class XmlSerializerTests
10+
{
11+
static XmlSerializerTests()
12+
{
13+
NorthwindData.LoadData(false);
14+
}
15+
16+
public void Serialize<T>(T data)
17+
{
18+
//TODO: implement serializer and test properly
19+
var xml = XmlSerializer.SerializeToString(data);
20+
Console.WriteLine(xml);
21+
}
22+
23+
[Test]
24+
public void Can_Serialize_Movie()
25+
{
26+
Serialize(MoviesData.Movies[0]);
27+
}
28+
29+
[Test]
30+
public void Can_Serialize_Movies()
31+
{
32+
Serialize(MoviesData.Movies);
33+
}
34+
35+
[Test]
36+
public void Can_Serialize_MovieResponse_Dto()
37+
{
38+
Serialize(new MovieResponse { Movie = MoviesData.Movies[0] });
39+
}
40+
41+
[Test]
42+
public void serialize_Category()
43+
{
44+
Serialize(NorthwindData.Categories[0]);
45+
}
46+
47+
[Test]
48+
public void serialize_Categories()
49+
{
50+
Serialize(NorthwindData.Categories);
51+
}
52+
53+
[Test]
54+
public void serialize_Customer()
55+
{
56+
Serialize(NorthwindData.Customers[0]);
57+
}
58+
59+
[Test]
60+
public void serialize_Customers()
61+
{
62+
Serialize(NorthwindData.Customers);
63+
}
64+
65+
[Test]
66+
public void serialize_Employee()
67+
{
68+
Serialize(NorthwindData.Employees[0]);
69+
}
70+
71+
[Test]
72+
public void serialize_Employees()
73+
{
74+
Serialize(NorthwindData.Employees);
75+
}
76+
77+
[Test]
78+
public void serialize_EmployeeTerritory()
79+
{
80+
Serialize(NorthwindData.EmployeeTerritories[0]);
81+
}
82+
83+
[Test]
84+
public void serialize_EmployeeTerritories()
85+
{
86+
Serialize(NorthwindData.EmployeeTerritories);
87+
}
88+
89+
[Test]
90+
public void serialize_OrderDetail()
91+
{
92+
Serialize(NorthwindData.OrderDetails[0]);
93+
}
94+
95+
[Test]
96+
public void serialize_OrderDetails()
97+
{
98+
Serialize(NorthwindData.OrderDetails);
99+
}
100+
101+
[Test]
102+
public void serialize_Order()
103+
{
104+
Serialize(NorthwindData.Orders[0]);
105+
}
106+
107+
[Test]
108+
public void serialize_Orders()
109+
{
110+
Serialize(NorthwindData.Orders);
111+
}
112+
113+
[Test]
114+
public void serialize_Product()
115+
{
116+
Serialize(NorthwindData.Products[0]);
117+
}
118+
119+
[Test]
120+
public void serialize_Products()
121+
{
122+
Serialize(NorthwindData.Products);
123+
}
124+
125+
[Test]
126+
public void serialize_Region()
127+
{
128+
Serialize(NorthwindData.Regions[0]);
129+
}
130+
131+
[Test]
132+
public void serialize_Regions()
133+
{
134+
Serialize(NorthwindData.Regions);
135+
}
136+
137+
[Test]
138+
public void serialize_Shipper()
139+
{
140+
Serialize(NorthwindData.Shippers[0]);
141+
}
142+
143+
[Test]
144+
public void serialize_Shippers()
145+
{
146+
Serialize(NorthwindData.Shippers);
147+
}
148+
149+
[Test]
150+
public void serialize_Supplier()
151+
{
152+
Serialize(NorthwindData.Suppliers[0]);
153+
}
154+
155+
[Test]
156+
public void serialize_Suppliers()
157+
{
158+
Serialize(NorthwindData.Suppliers);
159+
}
160+
161+
[Test]
162+
public void serialize_Territory()
163+
{
164+
Serialize(NorthwindData.Territories[0]);
165+
}
166+
167+
[Test]
168+
public void serialize_Territories()
169+
{
170+
Serialize(NorthwindData.Territories);
171+
}
172+
173+
}
174+
}

0 commit comments

Comments
 (0)