-Handle partial trust when creating uninitialized objects

This commit is contained in:
James Newton-King
2012-07-14 11:56:38 +12:00
parent cfb2499a35
commit 55a09d2f73
6 changed files with 57 additions and 9 deletions
@@ -72,5 +72,5 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.7.15110")]
[assembly: AssemblyFileVersion("4.5.7.15114")]
#endif
@@ -6540,6 +6540,22 @@ Parameter name: value",
}
}
[JsonObject(MemberSerialization.Fields)]
public class MyTuplePartial<T1>
{
private readonly T1 m_Item1;
public MyTuplePartial(T1 item1)
{
m_Item1 = item1;
}
public T1 Item1
{
get { return m_Item1; }
}
}
[Test]
public void SerializeCustomTupleWithSerializableAttribute()
{
@@ -6550,9 +6566,9 @@ Parameter name: value",
MyTuple<int> obj = null;
Action doStuff = () =>
{
obj = JsonConvert.DeserializeObject<MyTuple<int>>(json);
};
{
obj = JsonConvert.DeserializeObject<MyTuple<int>>(json);
};
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
doStuff();
@@ -6564,6 +6580,29 @@ Parameter name: value",
#endif
}
#if DEBUG
[Test]
public void SerializeCustomTupleWithSerializableAttributeInPartialTrust()
{
try
{
JsonTypeReflector.SetFullyTrusted(false);
var tuple = new MyTuplePartial<int>(500);
var json = JsonConvert.SerializeObject(tuple);
Assert.AreEqual(@"{""m_Item1"":500}", json);
ExceptionAssert.Throws<JsonSerializationException>(
"Unable to find a constructor to use for type Newtonsoft.Json.Tests.Serialization.JsonSerializerTest+MyTuplePartial`1[System.Int32]. A class should either have a default constructor, one constructor with arguments or a constructor marked with the JsonConstructor attribute. Path 'm_Item1', line 1, position 11.",
() => JsonConvert.DeserializeObject<MyTuplePartial<int>>(json));
}
finally
{
JsonTypeReflector.SetFullyTrusted(true);
}
}
#endif
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE || NET35 || NET20)
[Test]
public void SerializeTupleWithSerializableAttribute()
@@ -90,7 +90,7 @@ using System.Security;
// by using the '*' as shown below:
[assembly: AssemblyVersion("4.5.0.0")]
#if !PocketPC
[assembly: AssemblyFileVersion("4.5.7.15110")]
[assembly: AssemblyFileVersion("4.5.7.15114")]
#endif
[assembly: CLSCompliant(true)]
@@ -375,8 +375,10 @@ namespace Newtonsoft.Json.Serialization
else if (contract.MemberSerialization == MemberSerialization.Fields)
{
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
// mimic DataContractSerializer behaviour and create uninitialized object when populating fields
contract.DefaultCreator = contract.GetUninitializedObject;
// mimic DataContractSerializer behaviour when populating fields by overriding default creator to create an uninitialized object
// note that this is only possible when the application is fully trusted so fall back to using the default constructor (if available) in partial trust
if (JsonTypeReflector.FullyTrusted)
contract.DefaultCreator = contract.GetUninitializedObject;
#endif
}
else if (contract.DefaultCreator == null || contract.DefaultCreatorNonPublic)
@@ -24,9 +24,11 @@
#endregion
using System;
using System.Globalization;
using System.Reflection;
using System.Runtime.Serialization;
using System.Security;
using Newtonsoft.Json.Utilities;
namespace Newtonsoft.Json.Serialization
{
@@ -118,9 +120,15 @@ namespace Newtonsoft.Json.Serialization
}
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
#if !(NET20 || NET35)
[SecuritySafeCritical]
#endif
internal object GetUninitializedObject()
{
// we should never get here if the environment is not fully trusted, check just in case
if (!JsonTypeReflector.FullyTrusted)
throw new JsonException("Insufficient permissions. Creating an uninitialized '{0}' type requires full trust.".FormatWith(CultureInfo.InvariantCulture, NonNullableUnderlyingType));
return FormatterServices.GetUninitializedObject(NonNullableUnderlyingType);
}
#endif
@@ -512,8 +512,7 @@ namespace Newtonsoft.Json.Serialization
}
#if !(SILVERLIGHT || NETFX_CORE || PORTABLE)
#if !NET20
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Portability", "CA1903:UseOnlyApiFromTargetedFramework", MessageId = "System.Security.SecuritySafeCriticalAttribute")]
#if !(NET20 || NET35)
[SecuritySafeCritical]
#endif
private void SerializeISerializable(JsonWriter writer, ISerializable value, JsonISerializableContract contract, JsonProperty member, JsonContainerContract collectionContract, JsonProperty containerProperty)