Permalink
Browse files

fixed issue with double unescapin in the key for dictionaries

added ignore for null keys
  • Loading branch information...
1 parent b413919 commit 9ed3e12fab2955a161490d089e4abf4fb26ab89c @desunit desunit committed Mar 28, 2013
View
6 src/ServiceStack.Text/Common/DeserializeDictionary.cs
@@ -84,6 +84,7 @@ public static JsonObject ParseJsonObject(string value)
var keyValue = Serializer.EatMapKey(value, ref index);
Serializer.EatMapKeySeperator(value, ref index);
var elementValue = Serializer.EatValue(value, ref index);
+ if (keyValue == null) continue;
var mapKey = keyValue;
var mapValue = elementValue;
@@ -111,6 +112,7 @@ public static Hashtable ParseHashtable(string value)
var keyValue = Serializer.EatMapKey(value, ref index);
Serializer.EatMapKeySeperator(value, ref index);
var elementValue = Serializer.EatValue(value, ref index);
+ if (keyValue == null) continue;
var mapKey = keyValue;
var mapValue = elementValue;
@@ -138,6 +140,7 @@ public static Hashtable ParseHashtable(string value)
var keyValue = Serializer.EatMapKey(value, ref index);
Serializer.EatMapKeySeperator(value, ref index);
var elementValue = Serializer.EatValue(value, ref index);
+ if (keyValue == null) continue;
var mapKey = Serializer.UnescapeString(keyValue);
var mapValue = Serializer.UnescapeString(elementValue);
@@ -176,8 +179,9 @@ public static Hashtable ParseHashtable(string value)
Serializer.EatMapKeySeperator(value, ref index);
var elementStartIndex = index;
var elementValue = Serializer.EatTypeValue(value, ref index);
+ if (keyValue == null) continue;
- var mapKey = (TKey)parseKeyFn(keyValue);
+ TKey mapKey = (TKey)parseKeyFn(keyValue);
if (tryToParseItemsAsDictionaries)
{
View
36 src/ServiceStack.Text/Json/JsonTypeSerializer.cs
@@ -496,7 +496,41 @@ public bool EatMapStartChar(string value, ref int i)
public string EatMapKey(string value, ref int i)
{
- return ParseJsonString(value, ref i);
+ var valueLength = value.Length;
+ for (; i < value.Length; i++) { var c = value[i]; if (c >= WhiteSpaceFlags.Length || !WhiteSpaceFlags[c]) break; } //Whitespace inline
+
+ var tokenStartPos = i;
+ var valueChar = value[i];
+ var withinQuotes = false;
+ var endsToEat = 1;
+
+ switch (valueChar)
+ {
+ //If we are at the end, return.
+ case JsWriter.ItemSeperator:
+ case JsWriter.MapEndChar:
+ return null;
+
+ //Is Within Quotes, i.e. "..."
+ case JsWriter.QuoteChar:
+ return ParseString(value, ref i);
+ }
+
+ //Is Value
+ while (++i < valueLength)
+ {
+ valueChar = value[i];
+
+ if (valueChar == JsWriter.ItemSeperator
+ //If it doesn't have quotes it's either a keyword or number so also has a ws boundary
+ || (valueChar < WhiteSpaceFlags.Length && WhiteSpaceFlags[valueChar])
+ )
+ {
+ break;
+ }
+ }
+
+ return value.Substring(tokenStartPos, i - tokenStartPos);
}
public bool EatMapKeySeperator(string value, ref int i)
View
48 tests/ServiceStack.Text.Tests/DictionaryTests.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Diagnostics;
using NUnit.Framework;
@@ -325,6 +325,52 @@ public void Can_serialize_Dictionary_with_quotes()
}
[Test]
+ public void Can_serialize_Dictionary_with_escaped_symbols_in_key()
+ {
+ var dto = new Dictionary<string, string> { { @"a\fb", "\"test\"" } };
+ var to = Serialize(dto);
+
+ Assert.That(to.Keys.ToArray()[0], Is.EqualTo(@"a\fb"));
+ }
+
+ [Test]
+ public void Can_serialize_Dictionary_with_escaped_symbols_in_key_and_binary_value()
+ {
+ var dto = new Dictionary<string, byte[]> { { @"a\fb", new byte[]{1} } };
+ var to = Serialize(dto);
+
+ Assert.That(to.Keys.ToArray()[0], Is.EqualTo(@"a\fb"));
+ }
+
+ [Test]
+ public void Can_serialize_Dictionary_with_int_key_and_string_with_quote()
+ {
+ var dto = new Dictionary<int, string> { { 1, @"a""b" } };
+ var to = Serialize(dto);
+
+ Assert.That(to.Keys.ToArray()[0], Is.EqualTo(1));
+ Assert.That(to[1], Is.EqualTo(@"a""b"));
+ }
+
+ [Test]
+ public void Can_serialize_string_byte_Dictionary_with_UTF8()
+ {
+ var dto = new Dictionary<string, byte[]> { { "aфаž\"a", new byte[] { 1 } } };
+ var to = Serialize(dto);
+
+ Assert.That(to.Keys.ToArray()[0], Is.EqualTo( "aфаž\"a"));
+ }
+
+ [Test]
+ public void Can_serialize_string_string_Dictionary_with_UTF8()
+ {
+ var dto = new Dictionary<string, string> { { "aфаž\"a", "abc" } };
+ var to = Serialize(dto);
+
+ Assert.That(to.Keys.ToArray()[0], Is.EqualTo("aфаž\"a"));
+ }
+
+ [Test]
public void Can_Deserialize_Object_To_Dictionary()
{
const string json = "{\"Id\":1}";
View
1 tests/ServiceStack.Text.Tests/DynamicObjectTests.cs
@@ -204,6 +204,7 @@ public void Can_deserialize_object_dictionary_with_line_breaks()
var deserialized = JsonSerializer.DeserializeFromString<object>(json);
Assert.That(deserialized, Is.InstanceOf<Dictionary<string, object>>());
var dict = (Dictionary<string, object>) deserialized;
+ Assert.That(dict.Keys.Count, Is.EqualTo(1));
Assert.That(dict["value"], Is.EqualTo(5));
}
View
2 tests/ServiceStack.Text.Tests/JsonTests/BasicJsonTests.cs
@@ -460,7 +460,7 @@ public void Can_parse_empty_key_value_pair_with_leading_whitespace()
public void Can_parse_nonempty_key_value_pair_with_leading_whitespace()
{
var serializer = new JsonSerializer<KeyValuePair<string, string>>();
- var keyValuePair = serializer.DeserializeFromString(" {\"Key\":\"foo\"\"Value\":\"bar\"}");
+ var keyValuePair = serializer.DeserializeFromString(" {\"Key\":\"foo\",\"Value\":\"bar\"}");
Assert.That(keyValuePair, Is.EqualTo(new KeyValuePair<string, string>("foo", "bar")));
}

0 comments on commit 9ed3e12

Please sign in to comment.