diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs index e9c5ec8f..bceff741 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs @@ -2785,6 +2785,13 @@ new Date()")); Assert.AreEqual(12.34d, reader.ReadAsDouble()); } + [Test] + public void ReadAsDouble_Hex() + { + JsonTextReader reader = new JsonTextReader(new StringReader("0XCAFEBABE")); + Assert.AreEqual(3405691582d, reader.ReadAsDouble()); + } + [Test] public void ReadAsDouble_AllowThousands() { diff --git a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs index 4c32aad5..2955641a 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/JsonSerializerTest.cs @@ -6969,6 +6969,70 @@ Path '', line 1, position 1."); Assert.AreEqual(d1[0], d2[0]); } + internal class HasByteArray + { + public byte[] EncryptedPassword { get; set; } + } + + [Test] + public void DeserializeByteArrayWithTypeName() + { + string json = @"{ + ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+HasByteArray, Newtonsoft.Json.Tests"", + ""EncryptedPassword"": { + ""$type"": ""System.Byte[], mscorlib"", + ""$value"": ""cGFzc3dvcmQ="" + } +}"; + HasByteArray value = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + + CollectionAssert.AreEquivalent(Convert.FromBase64String("cGFzc3dvcmQ="), value.EncryptedPassword); + } + + [Test] + public void DeserializeByteArrayWithTypeName_BadAdditionalContent() + { + string json = @"{ + ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+HasByteArray, Newtonsoft.Json.Tests"", + ""EncryptedPassword"": { + ""$type"": ""System.Byte[], mscorlib"", + ""$value"": ""cGFzc3dvcmQ="", + ""$value"": ""cGFzc3dvcmQ="" + } +}"; + + ExceptionAssert.Throws(() => + { + JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + }, "Error reading bytes. Unexpected token: PropertyName. Path 'EncryptedPassword.$value', line 6, position 13."); + } + + [Test] + public void DeserializeByteArrayWithTypeName_ExtraProperty() + { + string json = @"{ + ""$type"": ""Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+HasByteArray, Newtonsoft.Json.Tests"", + ""EncryptedPassword"": { + ""$type"": ""System.Byte[], mscorlib"", + ""$value"": ""cGFzc3dvcmQ="" + }, + ""Pie"": null +}"; + HasByteArray value = JsonConvert.DeserializeObject(json, new JsonSerializerSettings + { + TypeNameHandling = TypeNameHandling.Objects + }); + + Assert.IsNotNull(value.EncryptedPassword); + CollectionAssert.AreEquivalent(Convert.FromBase64String("cGFzc3dvcmQ="), value.EncryptedPassword); + } + [Test] public void SerializeInheritanceHierarchyWithDuplicateProperty() { diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs index 5a2e1ca7..ce71c23e 100644 --- a/Src/Newtonsoft.Json/JsonReader.cs +++ b/Src/Newtonsoft.Json/JsonReader.cs @@ -523,7 +523,13 @@ namespace Newtonsoft.Json ReadIntoWrappedTypeObject(); byte[] data = ReadAsBytes(); - Read(); + ReaderReadAndAssert(); + + if (TokenType != JsonToken.EndObject) + { + throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + SetToken(JsonToken.Bytes, data, false); return data; } diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs index dc459396..89cc68e2 100644 --- a/Src/Newtonsoft.Json/JsonTextReader.cs +++ b/Src/Newtonsoft.Json/JsonTextReader.cs @@ -449,6 +449,7 @@ namespace Newtonsoft.Json public override byte[] ReadAsBytes() { EnsureBuffer(); + bool isWrappedArray = false; switch (_currentState) { @@ -475,11 +476,22 @@ namespace Newtonsoft.Json case '"': case '\'': ParseString(currentChar, ReadType.ReadAsBytes); - return (byte[])Value; + byte[] data = (byte[])Value; + if (isWrappedArray) + { + ReaderReadAndAssert(); + if (TokenType != JsonToken.EndObject) + { + throw JsonReaderException.Create(this, "Error reading bytes. Unexpected token: {0}.".FormatWith(CultureInfo.InvariantCulture, TokenType)); + } + SetToken(JsonToken.Bytes, data, false); + } + return data; case '{': _charPos++; SetToken(JsonToken.StartObject); ReadIntoWrappedTypeObject(); + isWrappedArray = true; break; case '[': _charPos++;