Skip to content

Commit

Permalink
Fix #88
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Jan 12, 2014
1 parent 8221fe1 commit 0e1e878
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 52 deletions.
2 changes: 2 additions & 0 deletions release-notes/VERSION
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
Project: jackson-databind
Version: 2.4.0 (xx-xxx-2014)

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

Expand Down
33 changes: 10 additions & 23 deletions src/main/java/com/fasterxml/jackson/databind/JavaType.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public abstract class JavaType
implements java.io.Serializable, // 2.1
java.lang.reflect.Type // 2.2
{
private static final long serialVersionUID = 6774285981275451126L;
private static final long serialVersionUID = 1;

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

protected final int _hashCode;
protected final int _hash;

/**
* Optional handler (codec) that can be attached to indicate
Expand Down Expand Up @@ -74,7 +74,7 @@ protected JavaType(Class<?> raw, int additionalHash,
Object valueHandler, Object typeHandler, boolean asStatic)
{
_class = raw;
_hashCode = raw.getName().hashCode() + additionalHash;
_hash = raw.getName().hashCode() + additionalHash;
_valueHandler = valueHandler;
_typeHandler = typeHandler;
_asStatic = asStatic;
Expand Down Expand Up @@ -231,9 +231,7 @@ protected JavaType _widen(Class<?> superclass) {
* true if instantiation of this Type is given (type-erased) Class.
*/
@Override
public final boolean hasRawClass(Class<?> clz) {
return _class == clz;
}
public final boolean hasRawClass(Class<?> clz) { return _class == clz; }

@Override
public boolean isAbstract() {
Expand All @@ -254,16 +252,11 @@ public boolean isConcrete() {
/* 19-Feb-2010, tatus: Holy mackarel; primitive types
* have 'abstract' flag set...
*/
if (_class.isPrimitive()) {
return true;
}
return false;
return _class.isPrimitive();
}

@Override
public boolean isThrowable() {
return Throwable.class.isAssignableFrom(_class);
}
public boolean isThrowable() { return Throwable.class.isAssignableFrom(_class); }

@Override
public boolean isArrayType() { return false; }
Expand Down Expand Up @@ -311,9 +304,7 @@ public boolean isThrowable() {
*
* @since 2.2
*/
public final boolean useStaticType() {
return _asStatic;
}
public final boolean useStaticType() { return _asStatic; }

/*
/**********************************************************
Expand All @@ -322,10 +313,7 @@ public final boolean useStaticType() {
*/

@Override
public boolean hasGenericTypes()
{
return containedTypeCount() > 0;
}
public boolean hasGenericTypes() { return containedTypeCount() > 0; }

@Override
public JavaType getKeyType() { return null; }
Expand Down Expand Up @@ -422,8 +410,7 @@ public String getErasedSignature() {
/**********************************************************
*/

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

@Override
public final int hashCode() { return _hashCode; }
public final int hashCode() { return _hash; }
}
18 changes: 16 additions & 2 deletions src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ public class ObjectMapper
* to specify what kind of types (classes) default typing should
* be used for. It will only be used if no explicit type information
* is found, but this enumeration further limits subset of those types.
*<p>
* Since 2.4 there are special exceptions for JSON Tree model
* types (sub-types of {@link TreeNode}: default typing is never
* applied to them
* (see <a href="https://github.com/FasterXML/jackson-databind/issues/88">Issue#88</a> for details)
*/
public enum DefaultTyping {
/**
Expand All @@ -87,13 +92,17 @@ public enum DefaultTyping {
* properties with declared type of {@link java.lang.Object}
* or an abstract type (abstract class or interface).
* Note that this does <b>not</b> include array types.
*<p>
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
*/
OBJECT_AND_NON_CONCRETE,

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

Expand All @@ -103,6 +112,8 @@ public enum DefaultTyping {
* "natural" types (String, Boolean, Integer, Double), which
* can be correctly inferred from JSON; as well as for
* all arrays of non-final types.
*<p>
* Since 2.4, this does NOT apply to {@link TreeNode} and its subtypes.
*/
NON_FINAL
}
Expand Down Expand Up @@ -163,12 +174,15 @@ public boolean useForType(JavaType t)
}
// fall through
case OBJECT_AND_NON_CONCRETE:
return (t.getRawClass() == Object.class) || !t.isConcrete();
return (t.getRawClass() == Object.class) || !t.isConcrete()
// [Issue#88] Should not apply to JSON tree models:
|| TreeNode.class.isAssignableFrom(t.getRawClass());
case NON_FINAL:
while (t.isArrayType()) {
t = t.getContentType();
}
return !t.isFinal(); // includes Object.class
// [Issue#88] Should not apply to JSON tree models:
return !t.isFinal() && !TreeNode.class.isAssignableFrom(t.getRawClass());
default:
//case JAVA_LANG_OBJECT:
return (t.getRawClass() == Object.class);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,7 +366,7 @@ protected void addObjectIdReader(DeserializationContext ctxt,
}
Class<?> implClass = objectIdInfo.getGeneratorType();
JavaType idType;
SettableBeanProperty idProp;
SettableBeanProperty idProp;
ObjectIdGenerator<?> gen;

// Just one special case: Property-based generator is trickier
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@

/**
* Default {@link TypeResolverBuilder} implementation.
*
* @author tatu
*/
public class StdTypeResolverBuilder
implements TypeResolverBuilder<StdTypeResolverBuilder>
Expand Down Expand Up @@ -68,13 +66,12 @@ public StdTypeResolverBuilder init(JsonTypeInfo.Id idType, TypeIdResolver idRes)
return this;
}

@SuppressWarnings("incomplete-switch")
@Override
public TypeSerializer buildTypeSerializer(SerializationConfig config,
JavaType baseType, Collection<NamedType> subtypes)
{
if (_idType == JsonTypeInfo.Id.NONE) {
return null;
}
if (_idType == JsonTypeInfo.Id.NONE) { return null; }
TypeIdResolver idRes = idResolver(config, baseType, subtypes, true, false);
switch (_includeAs) {
case WRAPPER_ARRAY:
Expand All @@ -91,13 +88,12 @@ public TypeSerializer buildTypeSerializer(SerializationConfig config,
throw new IllegalStateException("Do not know how to construct standard type serializer for inclusion type: "+_includeAs);
}

@SuppressWarnings("incomplete-switch")
@Override
public TypeDeserializer buildTypeDeserializer(DeserializationConfig config,
JavaType baseType, Collection<NamedType> subtypes)
{
if (_idType == JsonTypeInfo.Id.NONE) {
return null;
}
if (_idType == JsonTypeInfo.Id.NONE) { return null; }

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

Expand Down Expand Up @@ -139,8 +135,7 @@ public StdTypeResolverBuilder inclusion(JsonTypeInfo.As includeAs) {
* (property name to use for type id when using "as-property" inclusion).
*/
@Override
public StdTypeResolverBuilder typeProperty(String typeIdPropName)
{
public StdTypeResolverBuilder typeProperty(String typeIdPropName) {
// ok to have null/empty; will restore to use defaults
if (typeIdPropName == null || typeIdPropName.length() == 0) {
typeIdPropName = _idType.getDefaultPropertyName();
Expand All @@ -150,8 +145,7 @@ public StdTypeResolverBuilder typeProperty(String typeIdPropName)
}

@Override
public StdTypeResolverBuilder defaultImpl(Class<?> defaultImpl)
{
public StdTypeResolverBuilder defaultImpl(Class<?> defaultImpl) {
_defaultImpl = defaultImpl;
return this;
}
Expand All @@ -168,13 +162,9 @@ public StdTypeResolverBuilder typeIdVisibility(boolean isVisible) {
/**********************************************************
*/

public String getTypeProperty() { return _typeProperty; }

@Override
public Class<?> getDefaultImpl() {
return _defaultImpl;
}
@Override public Class<?> getDefaultImpl() { return _defaultImpl; }

public String getTypeProperty() { return _typeProperty; }
public boolean isTypeIdVisible() { return _typeIdVisible; }

/*
Expand All @@ -189,16 +179,11 @@ public Class<?> getDefaultImpl() {
* given configuration.
*/
protected TypeIdResolver idResolver(MapperConfig<?> config,
JavaType baseType, Collection<NamedType> subtypes,
boolean forSer, boolean forDeser)
JavaType baseType, Collection<NamedType> subtypes, boolean forSer, boolean forDeser)
{
// Custom id resolver?
if (_customIdResolver != null) {
return _customIdResolver;
}
if (_idType == null) {
throw new IllegalStateException("Can not build, 'init()' not yet called");
}
if (_customIdResolver != null) { return _customIdResolver; }
if (_idType == null) throw new IllegalStateException("Can not build, 'init()' not yet called");
switch (_idType) {
case CLASS:
return new ClassNameIdResolver(baseType, config.getTypeFactory());
Expand Down

0 comments on commit 0e1e878

Please sign in to comment.