Skip to content

Commit cdda82f

Browse files
committed
Fix #2573 (this adds tests, actual impl in preceding commit)
1 parent fa40257 commit cdda82f

File tree

2 files changed

+104
-6
lines changed

2 files changed

+104
-6
lines changed

release-notes/VERSION-2.x

+8-6
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,19 @@ Project: jackson-databind
1818
#2503: Support `@JsonSerialize(keyUsing)` and `@JsonDeserialize(keyUsing)` on Key class
1919
#2511: Add `SerializationFeature.WRITE_SELF_REFERENCES_AS_NULL`
2020
(contributed by Joongsoo P)
21-
#2515: `ObjectMapper.registerSubtypes(NamedType...)` doesn't allow registering the same POJO
22-
for two different type ids
21+
#2515: `ObjectMapper.registerSubtypes(NamedType...)` doesn't allow registering
22+
same POJO for two different type ids
2323
(contributed by Joseph K)
24-
#2522: `DeserializationContext.handleMissingInstantiator()` throws `MismatchedInputException`
25-
for non-static inner classes
24+
#2522: `DeserializationContext.handleMissingInstantiator()` throws
25+
`MismatchedInputException` for non-static inner classes
2626
#2525: Incorrect `JsonStreamContext` for `TokenBuffer` and `TreeTraversingParser`
27-
#2527: Add `AnnotationIntrospector.findRenameByField()` to support Kotlin's "is-getter"
28-
naming convention
27+
#2527: Add `AnnotationIntrospector.findRenameByField()` to support Kotlin's
28+
"is-getter" naming convention
2929
#2555: Use `@JsonProperty(index)` for sorting properties on serialization
3030
#2565: Java 8 `Optional` not working with `@JsonUnwrapped` on unwrappable type
3131
(reported by Haowei W)
32+
#2573: Add `MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES` to allow blocking
33+
use of unsafe base type for polymorphic deserialization
3234
- Add `SerializerProvider.findContentValueSerializer()` methods
3335

3436
2.10.2 (05-Jan-2020)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package com.fasterxml.jackson.databind.jsontype.vld;
2+
3+
import java.io.*;
4+
5+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
6+
7+
import com.fasterxml.jackson.databind.*;
8+
import com.fasterxml.jackson.databind.cfg.MapperConfig;
9+
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
10+
import com.fasterxml.jackson.databind.json.JsonMapper;
11+
import com.fasterxml.jackson.databind.jsontype.DefaultBaseTypeLimitingValidator;
12+
13+
/**
14+
* Unit tests for verifying that "unsafe" base type(s) for polymorphic deserialization
15+
* are correctly handled wrt {@link MapperFeature#BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES}.
16+
*/
17+
public class AnnotatedPolymorphicValidationTest
18+
extends BaseMapTest
19+
{
20+
static class WrappedPolymorphicUntyped {
21+
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
22+
public Object value;
23+
24+
protected WrappedPolymorphicUntyped() { }
25+
}
26+
27+
static class WrappedPolymorphicUntypedSer {
28+
@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS)
29+
public java.io.Serializable value;
30+
31+
protected WrappedPolymorphicUntypedSer() { }
32+
}
33+
34+
static class NumbersAreOkValidator extends DefaultBaseTypeLimitingValidator
35+
{
36+
private static final long serialVersionUID = 1L;
37+
38+
@Override
39+
protected boolean isUnsafeBaseType(MapperConfig<?> config, JavaType baseType)
40+
{
41+
// only override handling for `Object`
42+
if (baseType.hasRawClass(Object.class)) {
43+
return false;
44+
}
45+
return super.isUnsafeBaseType(config, baseType);
46+
}
47+
48+
@Override
49+
protected boolean isSafeSubType(MapperConfig<?> config,
50+
JavaType baseType, JavaType subType) {
51+
return baseType.isTypeOrSubTypeOf(Number.class);
52+
}
53+
}
54+
55+
/*
56+
/**********************************************************
57+
/* Test methods
58+
/**********************************************************
59+
*/
60+
61+
private final ObjectMapper MAPPER = jsonMapperBuilder()
62+
.enable(MapperFeature.BLOCK_UNSAFE_POLYMORPHIC_BASE_TYPES)
63+
.build();
64+
65+
public void testPolymorphicWithUnsafeBaseType() throws IOException
66+
{
67+
final String JSON = aposToQuotes("{'value':10}");
68+
// by default, we should NOT be allowed to deserialize due to unsafe base type
69+
try {
70+
/*w =*/ MAPPER.readValue(JSON, WrappedPolymorphicUntyped.class);
71+
fail("Should not pass");
72+
} catch (InvalidDefinitionException e) {
73+
verifyException(e, "Configured");
74+
verifyException(e, "all subtypes of base type");
75+
}
76+
77+
// but may with proper validator
78+
ObjectMapper customMapper = JsonMapper.builder()
79+
.polymorphicTypeValidator(new NumbersAreOkValidator())
80+
.build();
81+
82+
WrappedPolymorphicUntyped w = customMapper.readValue(JSON, WrappedPolymorphicUntyped.class);
83+
assertEquals(Integer.valueOf(10), w.value);
84+
85+
// but yet again, it is not opening up all types (just as an example)
86+
87+
try {
88+
customMapper.readValue(JSON, WrappedPolymorphicUntypedSer.class);
89+
fail("Should not pass");
90+
} catch (InvalidDefinitionException e) {
91+
verifyException(e, "Configured");
92+
verifyException(e, "all subtypes of base type");
93+
verifyException(e, "java.io.Serializable");
94+
}
95+
}
96+
}

0 commit comments

Comments
 (0)