diff --git a/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs b/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs index f26dbeafc..534050ae2 100644 --- a/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs +++ b/src/ServiceStack.Text/Common/DeserializeTypeRefJson.cs @@ -91,37 +91,36 @@ internal static object StringToType( var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = AssemblyUtils.FindType(explicitTypeName); - if (explicitType != null && !explicitType.IsInterface() && !explicitType.IsAbstract()) + // let's do the type safety checks first before we even attempt to create + // a type instance + if (explicitType == null || explicitType.IsInterface() || explicitType.IsAbstract()) { - instance = explicitType.CreateInstance(); + Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } - - if (instance == null) + else if (!type.IsAssignableFrom(explicitType)) { - Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); + Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr); } else { - //If __type info doesn't match, ignore it. - if (!type.InstanceOfType(instance)) - { - instance = null; - } - else + instance = explicitType.CreateInstance(); + } + + if (instance != null) + { + var derivedType = instance.GetType(); + if (derivedType != type) { - var derivedType = instance.GetType(); - if (derivedType != type) + var derivedTypeConfig = new TypeConfig(derivedType); + var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); + if (map != null) { - var derivedTypeConfig = new TypeConfig(derivedType); - var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); - if (map != null) - { - typeAccessorMap = map; - } + typeAccessorMap = map; } } } + Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); continue; } diff --git a/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs b/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs index 522727211..058434897 100644 --- a/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs +++ b/src/ServiceStack.Text/Common/DeserializeTypeRefJsv.cs @@ -45,37 +45,33 @@ internal static object StringToType( var explicitTypeName = Serializer.ParseString(propertyValueStr); var explicitType = AssemblyUtils.FindType(explicitTypeName); - if (explicitType != null && !explicitType.IsInterface() && !explicitType.IsAbstract()) + if (explicitType == null || explicitType.IsInterface() || explicitType.IsAbstract()) { - instance = explicitType.CreateInstance(); + Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); } - - if (instance == null) + else if (!type.IsAssignableFrom(explicitType)) { - Tracer.Instance.WriteWarning("Could not find type: " + propertyValueStr); + Tracer.Instance.WriteWarning("Could not assign type: " + propertyValueStr); } else { - //If __type info doesn't match, ignore it. - if (!type.InstanceOfType(instance)) - { - instance = null; - } - else + instance = explicitType.CreateInstance(); + } + + if (instance != null) + { + var derivedType = instance.GetType(); + if (derivedType != type) { - var derivedType = instance.GetType(); - if (derivedType != type) + var derivedTypeConfig = new TypeConfig(derivedType); + var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); + if (map != null) { - var derivedTypeConfig = new TypeConfig(derivedType); - var map = DeserializeTypeRef.GetTypeAccessorMap(derivedTypeConfig, Serializer); - if (map != null) - { - typeAccessorMap = map; - } + typeAccessorMap = map; } } } - + //Serializer.EatItemSeperatorOrMapEndChar(strType, ref index); if (index != strType.Length) index++; diff --git a/tests/ServiceStack.Text.Tests/JsonTests/PolymorphicInstanceTest.cs b/tests/ServiceStack.Text.Tests/JsonTests/PolymorphicInstanceTest.cs index d7b2a3ea1..ec479de50 100644 --- a/tests/ServiceStack.Text.Tests/JsonTests/PolymorphicInstanceTest.cs +++ b/tests/ServiceStack.Text.Tests/JsonTests/PolymorphicInstanceTest.cs @@ -44,5 +44,27 @@ public void Can_deserialise_polymorphic_list_exact_with_no_side_effect_for_bad_t } + [Test] + public void Should_not_even_instantiate_incorrect_type() + { + var json = @"{""__type"":""" + + typeof(TestClass).ToTypeString() + @""", ""Name"":""Fido""}"; + var dog = JsonSerializer.DeserializeFromString( + + json); + + Assert.IsFalse(TestClass.Called); + } + + public class TestClass + { + public static bool Called { get; set; } + + public TestClass() + { + Called = true; + } + } + } }