Skip to content

Commit 0e1e878

Browse files
committed
Fix #88
1 parent 8221fe1 commit 0e1e878

File tree

5 files changed

+40
-52
lines changed

5 files changed

+40
-52
lines changed

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
Project: jackson-databind
22
Version: 2.4.0 (xx-xxx-2014)
33

4+
#88: Prevent use of type information for `JsonNode` via default typing
5+
(reported by electricmonk@github)
46
#381: Allow inlining/unwrapping of value from single-component JSON array
57
(contributed by yinzara@github)
68

src/main/java/com/fasterxml/jackson/databind/JavaType.java

+10-23
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public abstract class JavaType
1919
implements java.io.Serializable, // 2.1
2020
java.lang.reflect.Type // 2.2
2121
{
22-
private static final long serialVersionUID = 6774285981275451126L;
22+
private static final long serialVersionUID = 1;
2323

2424
/**
2525
* This is the nominal type-erased Class that would be close to the
@@ -30,7 +30,7 @@ public abstract class JavaType
3030
*/
3131
protected final Class<?> _class;
3232

33-
protected final int _hashCode;
33+
protected final int _hash;
3434

3535
/**
3636
* Optional handler (codec) that can be attached to indicate
@@ -74,7 +74,7 @@ protected JavaType(Class<?> raw, int additionalHash,
7474
Object valueHandler, Object typeHandler, boolean asStatic)
7575
{
7676
_class = raw;
77-
_hashCode = raw.getName().hashCode() + additionalHash;
77+
_hash = raw.getName().hashCode() + additionalHash;
7878
_valueHandler = valueHandler;
7979
_typeHandler = typeHandler;
8080
_asStatic = asStatic;
@@ -231,9 +231,7 @@ protected JavaType _widen(Class<?> superclass) {
231231
* true if instantiation of this Type is given (type-erased) Class.
232232
*/
233233
@Override
234-
public final boolean hasRawClass(Class<?> clz) {
235-
return _class == clz;
236-
}
234+
public final boolean hasRawClass(Class<?> clz) { return _class == clz; }
237235

238236
@Override
239237
public boolean isAbstract() {
@@ -254,16 +252,11 @@ public boolean isConcrete() {
254252
/* 19-Feb-2010, tatus: Holy mackarel; primitive types
255253
* have 'abstract' flag set...
256254
*/
257-
if (_class.isPrimitive()) {
258-
return true;
259-
}
260-
return false;
255+
return _class.isPrimitive();
261256
}
262257

263258
@Override
264-
public boolean isThrowable() {
265-
return Throwable.class.isAssignableFrom(_class);
266-
}
259+
public boolean isThrowable() { return Throwable.class.isAssignableFrom(_class); }
267260

268261
@Override
269262
public boolean isArrayType() { return false; }
@@ -311,9 +304,7 @@ public boolean isThrowable() {
311304
*
312305
* @since 2.2
313306
*/
314-
public final boolean useStaticType() {
315-
return _asStatic;
316-
}
307+
public final boolean useStaticType() { return _asStatic; }
317308

318309
/*
319310
/**********************************************************
@@ -322,10 +313,7 @@ public final boolean useStaticType() {
322313
*/
323314

324315
@Override
325-
public boolean hasGenericTypes()
326-
{
327-
return containedTypeCount() > 0;
328-
}
316+
public boolean hasGenericTypes() { return containedTypeCount() > 0; }
329317

330318
@Override
331319
public JavaType getKeyType() { return null; }
@@ -422,8 +410,7 @@ public String getErasedSignature() {
422410
/**********************************************************
423411
*/
424412

425-
protected void _assertSubclass(Class<?> subclass, Class<?> superClass)
426-
{
413+
protected void _assertSubclass(Class<?> subclass, Class<?> superClass) {
427414
if (!_class.isAssignableFrom(subclass)) {
428415
throw new IllegalArgumentException("Class "+subclass.getName()+" is not assignable to "+_class.getName());
429416
}
@@ -442,5 +429,5 @@ protected void _assertSubclass(Class<?> subclass, Class<?> superClass)
442429
public abstract boolean equals(Object o);
443430

444431
@Override
445-
public final int hashCode() { return _hashCode; }
432+
public final int hashCode() { return _hash; }
446433
}

src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java

+16-2
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,11 @@ public class ObjectMapper
7272
* to specify what kind of types (classes) default typing should
7373
* be used for. It will only be used if no explicit type information
7474
* is found, but this enumeration further limits subset of those types.
75+
*<p>
76+
* Since 2.4 there are special exceptions for JSON Tree model
77+
* types (sub-types of {@link TreeNode}: default typing is never
78+
* applied to them
79+
* (see <a href="https://github.com/FasterXML/jackson-databind/issues/88">Issue#88</a> for details)
7580
*/
7681
public enum DefaultTyping {
7782
/**
@@ -87,13 +92,17 @@ public enum DefaultTyping {
8792
* properties with declared type of {@link java.lang.Object}
8893
* or an abstract type (abstract class or interface).
8994
* Note that this does <b>not</b> include array types.
95+
*<p>
96+
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
9097
*/
9198
OBJECT_AND_NON_CONCRETE,
9299

93100
/**
94101
* Value that means that default typing will be used for
95102
* all types covered by {@link #OBJECT_AND_NON_CONCRETE}
96103
* plus all array types for them.
104+
*<p>
105+
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
97106
*/
98107
NON_CONCRETE_AND_ARRAYS,
99108

@@ -103,6 +112,8 @@ public enum DefaultTyping {
103112
* "natural" types (String, Boolean, Integer, Double), which
104113
* can be correctly inferred from JSON; as well as for
105114
* all arrays of non-final types.
115+
*<p>
116+
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
106117
*/
107118
NON_FINAL
108119
}
@@ -163,12 +174,15 @@ public boolean useForType(JavaType t)
163174
}
164175
// fall through
165176
case OBJECT_AND_NON_CONCRETE:
166-
return (t.getRawClass() == Object.class) || !t.isConcrete();
177+
return (t.getRawClass() == Object.class) || !t.isConcrete()
178+
// [Issue#88] Should not apply to JSON tree models:
179+
|| TreeNode.class.isAssignableFrom(t.getRawClass());
167180
case NON_FINAL:
168181
while (t.isArrayType()) {
169182
t = t.getContentType();
170183
}
171-
return !t.isFinal(); // includes Object.class
184+
// [Issue#88] Should not apply to JSON tree models:
185+
return !t.isFinal() && !TreeNode.class.isAssignableFrom(t.getRawClass());
172186
default:
173187
//case JAVA_LANG_OBJECT:
174188
return (t.getRawClass() == Object.class);

src/main/java/com/fasterxml/jackson/databind/deser/BeanDeserializerFactory.java

+1-1
Original file line numberDiff line numberDiff line change
@@ -366,7 +366,7 @@ protected void addObjectIdReader(DeserializationContext ctxt,
366366
}
367367
Class<?> implClass = objectIdInfo.getGeneratorType();
368368
JavaType idType;
369-
SettableBeanProperty idProp;
369+
SettableBeanProperty idProp;
370370
ObjectIdGenerator<?> gen;
371371

372372
// Just one special case: Property-based generator is trickier

src/main/java/com/fasterxml/jackson/databind/jsontype/impl/StdTypeResolverBuilder.java

+11-26
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@
1313

1414
/**
1515
* Default {@link TypeResolverBuilder} implementation.
16-
*
17-
* @author tatu
1816
*/
1917
public class StdTypeResolverBuilder
2018
implements TypeResolverBuilder<StdTypeResolverBuilder>
@@ -68,13 +66,12 @@ public StdTypeResolverBuilder init(JsonTypeInfo.Id idType, TypeIdResolver idRes)
6866
return this;
6967
}
7068

69+
@SuppressWarnings("incomplete-switch")
7170
@Override
7271
public TypeSerializer buildTypeSerializer(SerializationConfig config,
7372
JavaType baseType, Collection<NamedType> subtypes)
7473
{
75-
if (_idType == JsonTypeInfo.Id.NONE) {
76-
return null;
77-
}
74+
if (_idType == JsonTypeInfo.Id.NONE) { return null; }
7875
TypeIdResolver idRes = idResolver(config, baseType, subtypes, true, false);
7976
switch (_includeAs) {
8077
case WRAPPER_ARRAY:
@@ -91,13 +88,12 @@ public TypeSerializer buildTypeSerializer(SerializationConfig config,
9188
throw new IllegalStateException("Do not know how to construct standard type serializer for inclusion type: "+_includeAs);
9289
}
9390

91+
@SuppressWarnings("incomplete-switch")
9492
@Override
9593
public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
9694
JavaType baseType, Collection<NamedType> subtypes)
9795
{
98-
if (_idType == JsonTypeInfo.Id.NONE) {
99-
return null;
100-
}
96+
if (_idType == JsonTypeInfo.Id.NONE) { return null; }
10197

10298
TypeIdResolver idRes = idResolver(config, baseType, subtypes, false, true);
10399

@@ -139,8 +135,7 @@ public StdTypeResolverBuilder inclusion(JsonTypeInfo.As includeAs) {
139135
* (property name to use for type id when using "as-property" inclusion).
140136
*/
141137
@Override
142-
public StdTypeResolverBuilder typeProperty(String typeIdPropName)
143-
{
138+
public StdTypeResolverBuilder typeProperty(String typeIdPropName) {
144139
// ok to have null/empty; will restore to use defaults
145140
if (typeIdPropName == null || typeIdPropName.length() == 0) {
146141
typeIdPropName = _idType.getDefaultPropertyName();
@@ -150,8 +145,7 @@ public StdTypeResolverBuilder typeProperty(String typeIdPropName)
150145
}
151146

152147
@Override
153-
public StdTypeResolverBuilder defaultImpl(Class<?> defaultImpl)
154-
{
148+
public StdTypeResolverBuilder defaultImpl(Class<?> defaultImpl) {
155149
_defaultImpl = defaultImpl;
156150
return this;
157151
}
@@ -168,13 +162,9 @@ public StdTypeResolverBuilder typeIdVisibility(boolean isVisible) {
168162
/**********************************************************
169163
*/
170164

171-
public String getTypeProperty() { return _typeProperty; }
172-
173-
@Override
174-
public Class<?> getDefaultImpl() {
175-
return _defaultImpl;
176-
}
165+
@Override public Class<?> getDefaultImpl() { return _defaultImpl; }
177166

167+
public String getTypeProperty() { return _typeProperty; }
178168
public boolean isTypeIdVisible() { return _typeIdVisible; }
179169

180170
/*
@@ -189,16 +179,11 @@ public Class<?> getDefaultImpl() {
189179
* given configuration.
190180
*/
191181
protected TypeIdResolver idResolver(MapperConfig<?> config,
192-
JavaType baseType, Collection<NamedType> subtypes,
193-
boolean forSer, boolean forDeser)
182+
JavaType baseType, Collection<NamedType> subtypes, boolean forSer, boolean forDeser)
194183
{
195184
// Custom id resolver?
196-
if (_customIdResolver != null) {
197-
return _customIdResolver;
198-
}
199-
if (_idType == null) {
200-
throw new IllegalStateException("Can not build, 'init()' not yet called");
201-
}
185+
if (_customIdResolver != null) { return _customIdResolver; }
186+
if (_idType == null) throw new IllegalStateException("Can not build, 'init()' not yet called");
202187
switch (_idType) {
203188
case CLASS:
204189
return new ClassNameIdResolver(baseType, config.getTypeFactory());

0 commit comments

Comments
 (0)