From 9e29489e5a7a28c7205bbf0f3528e4cdab8785dc Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Wed, 10 Jun 2015 17:10:16 +1200 Subject: [PATCH] -Added support for reading GUID strings as bytes in JsonTextReader -Changed reading GUIDs as bytes to only support 00000000-0000-0000-0000-000000000000 format --- Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs | 15 +++++++++++++++ Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs | 16 ++++++++++++++++ Src/Newtonsoft.Json/JsonReader.cs | 3 ++- Src/Newtonsoft.Json/JsonTextReader.cs | 5 +++++ Src/Newtonsoft.Json/Utilities/ConvertUtils.cs | 8 +++----- 5 files changed, 41 insertions(+), 6 deletions(-) diff --git a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs index fde37b72..3e3259f4 100644 --- a/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs +++ b/Src/Newtonsoft.Json.Tests/JsonTextReaderTest.cs @@ -92,6 +92,21 @@ namespace Newtonsoft.Json.Tests Assert.AreEqual(JsonToken.EndObject, jsonTextReader.TokenType); } + [Test] + public void ReadAsBytes_Base64AndGuid() + { + JsonTextReader jsonTextReader = new JsonTextReader(new StringReader("'AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA'")); + byte[] data = jsonTextReader.ReadAsBytes(); + byte[] expected = Convert.FromBase64String("AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA"); + + CollectionAssert.AreEqual(expected, data); + + jsonTextReader = new JsonTextReader(new StringReader("'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAABAAAA'")); + data = jsonTextReader.ReadAsBytes(); + expected = Guid.Parse("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAABAAAA").ToByteArray(); + + CollectionAssert.AreEqual(expected, data); + } [Test] public void ReadSingleQuoteInsideDoubleQuoteString() diff --git a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs index 3e2b5e67..b473ff4d 100644 --- a/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs +++ b/Src/Newtonsoft.Json.Tests/Linq/LinqToJsonTest.cs @@ -54,6 +54,22 @@ namespace Newtonsoft.Json.Tests.Linq [TestFixture] public class LinqToJsonTest : TestFixtureBase { + [Test] + public void ToObject_Base64AndGuid() + { + JObject o = JObject.Parse("{'responseArray':'AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA'}"); + byte[] data = o["responseArray"].ToObject(); + byte[] expected = Convert.FromBase64String("AAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA"); + + CollectionAssert.AreEqual(expected, data); + + o = JObject.Parse("{'responseArray':'AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAABAAAA'}"); + data = o["responseArray"].ToObject(); + expected = Guid.Parse("AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAABAAAA").ToByteArray(); + + CollectionAssert.AreEqual(expected, data); + } + [Test] public void IncompleteContainers() { diff --git a/Src/Newtonsoft.Json/JsonReader.cs b/Src/Newtonsoft.Json/JsonReader.cs index 71ace1e4..f77ff23e 100644 --- a/Src/Newtonsoft.Json/JsonReader.cs +++ b/Src/Newtonsoft.Json/JsonReader.cs @@ -500,7 +500,8 @@ namespace Newtonsoft.Json return data; } - // attempt to convert possible base 64 string to bytes + // attempt to convert possible base 64 or GUID string to bytes + // GUID has to have format 00000000-0000-0000-0000-000000000000 if (t == JsonToken.String) { string s = (string)Value; diff --git a/Src/Newtonsoft.Json/JsonTextReader.cs b/Src/Newtonsoft.Json/JsonTextReader.cs index 18e9d57b..302acfad 100644 --- a/Src/Newtonsoft.Json/JsonTextReader.cs +++ b/Src/Newtonsoft.Json/JsonTextReader.cs @@ -117,11 +117,16 @@ namespace Newtonsoft.Json if (_readType == ReadType.ReadAsBytes) { + Guid g; byte[] data; if (_stringReference.Length == 0) { data = new byte[0]; } + else if (_stringReference.Length == 36 && ConvertUtils.TryConvertGuid(_stringReference.ToString(), out g)) + { + data = g.ToByteArray(); + } else { data = Convert.FromBase64CharArray(_stringReference.Chars, _stringReference.StartIndex, _stringReference.Length); diff --git a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs index dc5d4706..0ab4fe83 100644 --- a/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ConvertUtils.cs @@ -776,14 +776,12 @@ namespace Newtonsoft.Json.Utilities public static bool TryConvertGuid(string s, out Guid g) { + // GUID has to have format 00000000-0000-0000-0000-000000000000 #if NET20 || NET35 if (s == null) throw new ArgumentNullException("s"); - Regex format = new Regex( - "^[A-Fa-f0-9]{32}$|" + - "^({|\\()?[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}(}|\\))?$|" + - "^({)?[0xA-Fa-f0-9]{3,10}(, {0,1}[0xA-Fa-f0-9]{3,6}){2}, {0,1}({)([0xA-Fa-f0-9]{3,4}, {0,1}){7}[0xA-Fa-f0-9]{3,4}(}})$"); + Regex format = new Regex("^[A-Fa-f0-9]{8}-([A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}$"); Match match = format.Match(s); if (match.Success) { @@ -794,7 +792,7 @@ namespace Newtonsoft.Json.Utilities g = Guid.Empty; return false; #else - return Guid.TryParse(s, out g); + return Guid.TryParseExact(s, "D", out g); #endif } }