diff --git a/Build/build.ps1 b/Build/build.ps1 index db07034f..f17ab5a2 100644 --- a/Build/build.ps1 +++ b/Build/build.ps1 @@ -30,7 +30,7 @@ $nunitConsolePath = "$buildDir\Temp\NUnit.ConsoleRunner.$nunitConsoleVersion" $builds = @( - @{Framework = "netstandard2.0"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp2.0"; Enabled=$true}, + @{Framework = "netstandard2.0"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp2.1"; Enabled=$true}, @{Framework = "netstandard1.3"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp1.1"; Enabled=$true}, @{Framework = "netstandard1.0"; TestsFunction = "NetCliTests"; TestFramework = "netcoreapp1.0"; Enabled=$true}, @{Framework = "net45"; TestsFunction = "NUnitTests"; TestFramework = "net46"; NUnitFramework="net-4.0"; Enabled=$true}, diff --git a/Src/Newtonsoft.Json.Tests/Issues/Issue1517.cs b/Src/Newtonsoft.Json.Tests/Issues/Issue1517.cs deleted file mode 100644 index c801b23a..00000000 --- a/Src/Newtonsoft.Json.Tests/Issues/Issue1517.cs +++ /dev/null @@ -1,79 +0,0 @@ -#region License -// Copyright (c) 2007 James Newton-King -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the "Software"), to deal in the Software without -// restriction, including without limitation the rights to use, -// copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following -// conditions: -// -// The above copyright notice and this permission notice shall be -// included in all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -#endregion - -#if (NETSTANDARD2_0) -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using Newtonsoft.Json; -using Newtonsoft.Json.Linq; -using System.Xml; -using Newtonsoft.Json.Serialization; -#if !NET20 -using System.Xml.Linq; -#endif -#if DNXCORE50 -using Xunit; -using Test = Xunit.FactAttribute; -using Assert = Newtonsoft.Json.Tests.XUnitAssert; -#else -using NUnit.Framework; -#endif - -namespace Newtonsoft.Json.Tests.Issues -{ - [TestFixture] - public class Issue1517 : TestFixtureBase - { - [Test] - public void Test() - { - RSAParameters rsaParameters = new RSAParameters(); - rsaParameters.D = new byte[] { 1, 2 }; - rsaParameters.DP = new byte[] { 2, 4 }; - rsaParameters.DQ = new byte[] { 5, 6 }; - rsaParameters.Exponent = new byte[] { 7, 8 }; - rsaParameters.InverseQ = new byte[] { 9, 10 }; - rsaParameters.Modulus = new byte[] { 11, 12 }; - rsaParameters.P = new byte[] { 13, 14 }; - rsaParameters.Q = new byte[] { 15, 16 }; - - string json = JsonConvert.SerializeObject(rsaParameters, Formatting.Indented); - - // a subset of values is serialized because of the NotSerializedAttribute - // https://msdn.microsoft.com/en-us/library/system.security.cryptography.rsaparameters.d(v=vs.110).aspx - StringAssert.AreEqual(@"{ - ""Exponent"": ""Bwg="", - ""Modulus"": ""Cww="" -}", json); - } - } -} -#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Issues/Issue1757.cs b/Src/Newtonsoft.Json.Tests/Issues/Issue1757.cs new file mode 100644 index 00000000..83704f5a --- /dev/null +++ b/Src/Newtonsoft.Json.Tests/Issues/Issue1757.cs @@ -0,0 +1,117 @@ +#region License +// Copyright (c) 2007 James Newton-King +// +// Permission is hereby granted, free of charge, to any person +// obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without +// restriction, including without limitation the rights to use, +// copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following +// conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +// OTHER DEALINGS IN THE SOFTWARE. +#endregion + +#if (NETSTANDARD2_0) +using System; +using System.Collections; +using System.Collections.Generic; +using System.IO; +using System.Reflection; +using System.Reflection.Emit; +using System.Runtime.Serialization; +#if !(NET20 || NET35 || NET40 || PORTABLE40) +using System.Threading.Tasks; +#endif +using Newtonsoft.Json.Converters; +using Newtonsoft.Json.Linq; +using Newtonsoft.Json.Serialization; +using Newtonsoft.Json.Utilities; +#if DNXCORE50 +using Xunit; +using Test = Xunit.FactAttribute; +using Assert = Newtonsoft.Json.Tests.XUnitAssert; +using System.Text; +#else +using NUnit.Framework; +#endif + +namespace Newtonsoft.Json.Tests.Issues +{ + [TestFixture] + public class Issue1757 : TestFixtureBase + { + [Test] + public void Test_Serialize() + { + JsonConvert.SerializeObject(new TestObject()); + } + + [Test] + public void Test_SerializeEncoding() + { + JsonConvert.SerializeObject(Encoding.UTF8); + } + + [Test] + public void Test_Deserialize() + { + JsonConvert.DeserializeObject(@"{'Room':{},'RefLike':{}}"); + } + + public class TestObject + { + public Span this[int i] + { + get { return default(Span); } + set { DoNothing(value); } + } + public static Span Space + { + get { return default(Span); } + set { DoNothing(value); } + } + public Span Room + { + get { return default(Span); } + set { DoNothing(value); } + } + public MyByRefLikeType RefLike + { + get { return default(MyByRefLikeType); } + set { } + } + private static void DoNothing(Span param) + { + throw new InvalidOperationException("Should never be called."); + } + public string PrintMySpan(string str, Span mySpan = default) + { + return str; + } + + public Span GetSpan(int[] array) + { + return array.AsSpan(); + } + } + + public ref struct MyByRefLikeType + { + public MyByRefLikeType(int i) { } + public static int Index; + } + } +} +#endif \ No newline at end of file diff --git a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj index d6f88865..752d33ac 100644 --- a/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj +++ b/Src/Newtonsoft.Json.Tests/Newtonsoft.Json.Tests.csproj @@ -1,6 +1,6 @@  - net46;net451;net452;net40;net35;net20;netcoreapp2.0;netcoreapp1.1;netcoreapp1.0 + net46;net451;net452;net40;net35;net20;netcoreapp2.1;netcoreapp1.1;netcoreapp1.0 $(TestFrameworks) latest 1.0 @@ -13,7 +13,7 @@ Newtonsoft.Json.Tests false - Full + Full false @@ -153,7 +153,7 @@ NET20;$(AdditionalConstants) - + @@ -168,7 +168,7 @@ - + Json.NET Tests .NET Standard 2.0 .NETStandard,Version=v2.0 NETSTANDARD2_0;DNXCORE50;PORTABLE;HAVE_BENCHMARKS;$(AdditionalConstants) diff --git a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs index ee3be244..6f2b5f17 100644 --- a/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs +++ b/Src/Newtonsoft.Json.Tests/Serialization/SerializationErrorHandlingTests.cs @@ -390,7 +390,8 @@ namespace Newtonsoft.Json.Tests.Serialization { #if !(NET20 || NET35) "[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", - "[1] - 1 - String was not recognized as a valid DateTime." + "[1] - 1 - String was not recognized as a valid DateTime.", + "[1] - 1 - The string 'I am not a date and will error!' was not recognized as a valid DateTime. There is an unknown word starting at index '0'." #else // handle typo fix in later versions of .NET "[1] - 1 - The string was not recognized as a valid DateTime. There is an unknown word starting at index 0.", diff --git a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs index 44309c65..e3fa24e2 100644 --- a/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs +++ b/Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs @@ -198,6 +198,25 @@ namespace Newtonsoft.Json.Serialization return _contractCache.Get(type); } + private static bool FilterMembers(MemberInfo member) + { + if (member is PropertyInfo property) + { + if (ReflectionUtils.IsIndexedProperty(property)) + { + return false; + } + + return !ReflectionUtils.IsByRefLikeType(property.PropertyType); + } + else if (member is FieldInfo field) + { + return !ReflectionUtils.IsByRefLikeType(field.FieldType); + } + + return true; + } + /// /// Gets the serializable members for the type. /// @@ -215,7 +234,7 @@ namespace Newtonsoft.Json.Serialization MemberSerialization memberSerialization = JsonTypeReflector.GetObjectMemberSerialization(objectType, ignoreSerializableAttribute); IEnumerable allMembers = ReflectionUtils.GetFieldsAndProperties(objectType, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static) - .Where(m => !ReflectionUtils.IsIndexedProperty(m)); + .Where(FilterMembers); List serializableMembers = new List(); @@ -227,7 +246,7 @@ namespace Newtonsoft.Json.Serialization #pragma warning disable 618 List defaultMembers = ReflectionUtils.GetFieldsAndProperties(objectType, DefaultMembersSearchFlags) - .Where(m => !ReflectionUtils.IsIndexedProperty(m)).ToList(); + .Where(FilterMembers).ToList(); #pragma warning restore 618 foreach (MemberInfo member in allMembers) diff --git a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs index 056d55e5..5f8741a5 100644 --- a/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs +++ b/Src/Newtonsoft.Json/Utilities/ReflectionUtils.cs @@ -457,25 +457,24 @@ namespace Newtonsoft.Json.Utilities } } - /// - /// Determines whether the member is an indexed property. - /// - /// The member. - /// - /// true if the member is an indexed property; otherwise, false. - /// - public static bool IsIndexedProperty(MemberInfo member) + public static bool IsByRefLikeType(Type type) { - ValidationUtils.ArgumentNotNull(member, nameof(member)); - - if (member is PropertyInfo propertyInfo) - { - return IsIndexedProperty(propertyInfo); - } - else + if (!type.IsValueType()) { return false; } + + // IsByRefLike flag on type is not available in netstandard2.0 + Attribute[] attributes = GetAttributes(type, null, false); + for (int i = 0; i < attributes.Length; i++) + { + if (string.Equals(attributes[i].GetType().FullName, "System.Runtime.CompilerServices.IsByRefLikeAttribute", StringComparison.Ordinal)) + { + return true; + } + } + + return false; } ///