Skip to content

Commit

Permalink
More work on #2195
Browse files Browse the repository at this point in the history
  • Loading branch information
cowtowncoder committed Apr 30, 2019
1 parent 03dd8cd commit 01ed12c
Show file tree
Hide file tree
Showing 3 changed files with 184 additions and 57 deletions.
143 changes: 92 additions & 51 deletions src/main/java/com/fasterxml/jackson/databind/ObjectMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -1525,7 +1525,43 @@ public ObjectMapper setDefaultMergeable(Boolean b) {

/*
/**********************************************************
/* Type information configuration
/* Subtype registration
/**********************************************************
*/

/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Type for given class is determined from appropriate annotation;
* or if missing, default name (unqualified class name)
*/
public void registerSubtypes(Class<?>... classes) {
getSubtypeResolver().registerSubtypes(classes);
}

/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Name may be provided as part of argument, but if not will
* be based on annotations or use default name (unqualified
* class name).
*/
public void registerSubtypes(NamedType... types) {
getSubtypeResolver().registerSubtypes(types);
}

/**
* @since 2.9
*/
public void registerSubtypes(Collection<Class<?>> subtypes) {
getSubtypeResolver().registerSubtypes(subtypes);
}

/*
/**********************************************************
/* Default typing (automatic polymorphic types): current (2.10)
/**********************************************************
*/

Expand All @@ -1535,14 +1571,13 @@ public ObjectMapper setDefaultMergeable(Boolean b) {
* enableDefaultTyping(DefaultTyping.OBJECT_AND_NON_CONCRETE);
*</pre>
*<p>
* NOTE: use of Default Typing can be a potential security risk if incoming
* content comes from untrusted sources, and it is recommended that this
* is either not done, or, if enabled, use {@link #setDefaultTyping}
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
* legal types to use.
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*
* @since 2.10
*/
public ObjectMapper enableDefaultTyping() {
return enableDefaultTyping(DefaultTyping.OBJECT_AND_NON_CONCRETE);
public ObjectMapper enableDefaultTyping(PolymorphicTypeValidator ptv) {
return enableDefaultTyping(ptv, DefaultTyping.OBJECT_AND_NON_CONCRETE);
}

/**
Expand All @@ -1551,14 +1586,14 @@ public ObjectMapper enableDefaultTyping() {
* enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
*</pre>
*<p>
* NOTE: use of Default Typing can be a potential security risk if incoming
* content comes from untrusted sources, and it is recommended that this
* is either not done, or, if enabled, use {@link #setDefaultTyping}
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
* legal types to use.
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*
* @since 2.10
*/
public ObjectMapper enableDefaultTyping(DefaultTyping dti) {
return enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
public ObjectMapper enableDefaultTyping(PolymorphicTypeValidator ptv,
DefaultTyping dti) {
return enableDefaultTyping(ptv, dti, JsonTypeInfo.As.WRAPPER_ARRAY);
}

/**
Expand All @@ -1570,26 +1605,24 @@ public ObjectMapper enableDefaultTyping(DefaultTyping dti) {
* and attempts of do so will throw an {@link IllegalArgumentException} to make
* this limitation explicit.
*<p>
* NOTE: use of Default Typing can be a potential security risk if incoming
* content comes from untrusted sources, and it is recommended that this
* is either not done, or, if enabled, use {@link #setDefaultTyping}
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
* legal types to use.
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*
* @param applicability Defines kinds of types for which additional type information
* is added; see {@link DefaultTyping} for more information.
*
* @since 2.10
*/
public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInfo.As includeAs)
public ObjectMapper enableDefaultTyping(PolymorphicTypeValidator ptv,
DefaultTyping applicability, JsonTypeInfo.As includeAs)
{
/* 18-Sep-2014, tatu: Let's add explicit check to ensure no one tries to
* use "As.EXTERNAL_PROPERTY", since that will not work (with 2.5+)
*/
// 18-Sep-2014, tatu: Let's add explicit check to ensure no one tries to
// use "As.EXTERNAL_PROPERTY", since that will not work (with 2.5+)
if (includeAs == JsonTypeInfo.As.EXTERNAL_PROPERTY) {
throw new IllegalArgumentException("Cannot use includeAs of "+includeAs);
}

TypeResolverBuilder<?> typer = _constructDefaultTypeResolverBuilder(applicability,
getPolymorphicTypeValidator());
TypeResolverBuilder<?> typer = _constructDefaultTypeResolverBuilder(applicability, ptv);
// we'll always use full class name, when using defaulting
typer = typer.init(JsonTypeInfo.Id.CLASS, null);
typer = typer.inclusion(includeAs);
Expand All @@ -1604,13 +1637,13 @@ public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInf
* to use for inclusion (default being "@class" since default type information
* always uses class name as type identifier)
*<p>
* NOTE: use of Default Typing can be a potential security risk if incoming
* content comes from untrusted sources, and it is recommended that this
* is either not done, or, if enabled, use {@link #setDefaultTyping}
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
* legal types to use.
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*
* @since 2.10
*/
public ObjectMapper enableDefaultTypingAsProperty(DefaultTyping applicability, String propertyName)
public ObjectMapper enableDefaultTypingAsProperty(PolymorphicTypeValidator ptv,
DefaultTyping applicability, String propertyName)
{
TypeResolverBuilder<?> typer = _constructDefaultTypeResolverBuilder(applicability,
getPolymorphicTypeValidator());
Expand Down Expand Up @@ -1641,7 +1674,7 @@ public ObjectMapper disableDefaultTyping() {
* content comes from untrusted sources, so care should be taken to use
* a {@link TypeResolverBuilder} that can limit allowed classes to
* deserialize.
*
*
* @param typer Type information inclusion handler
*/
public ObjectMapper setDefaultTyping(TypeResolverBuilder<?> typer) {
Expand All @@ -1650,34 +1683,42 @@ public ObjectMapper setDefaultTyping(TypeResolverBuilder<?> typer) {
return this;
}

/*
/**********************************************************
/* Default typing (automatic polymorphic types): deprecated (pre-2.10)
/**********************************************************
*/

/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Type for given class is determined from appropriate annotation;
* or if missing, default name (unqualified class name)
* @deprecated Since 2.10 use {@link #enableDefaultTyping(PolymorphicTypeValidator)} instead
*/
public void registerSubtypes(Class<?>... classes) {
getSubtypeResolver().registerSubtypes(classes);
@Deprecated
public ObjectMapper enableDefaultTyping() {
return enableDefaultTyping(getPolymorphicTypeValidator());
}

/**
* Method for registering specified class as a subtype, so that
* typename-based resolution can link supertypes to subtypes
* (as an alternative to using annotations).
* Name may be provided as part of argument, but if not will
* be based on annotations or use default name (unqualified
* class name).
* @deprecated Since 2.10 use {@link #enableDefaultTyping(PolymorphicTypeValidator,DefaultTyping)} instead
*/
public void registerSubtypes(NamedType... types) {
getSubtypeResolver().registerSubtypes(types);
@Deprecated
public ObjectMapper enableDefaultTyping(DefaultTyping dti) {
return enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
}

/**
* @since 2.9
* @deprecated Since 2.10 use {@link #enableDefaultTyping(PolymorphicTypeValidator,DefaultTyping,JsonTypeInfo.As)} instead
*/
public void registerSubtypes(Collection<Class<?>> subtypes) {
getSubtypeResolver().registerSubtypes(subtypes);
@Deprecated
public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInfo.As includeAs) {
return enableDefaultTyping(getPolymorphicTypeValidator(), applicability, includeAs);
}

/**
* @deprecated Since 2.10 use {@link #enableDefaultTypingAsProperty(PolymorphicTypeValidator,DefaultTyping,String)} instead
*/
@Deprecated
public ObjectMapper enableDefaultTypingAsProperty(DefaultTyping applicability, String propertyName) {
return enableDefaultTypingAsProperty(getPolymorphicTypeValidator(), applicability, propertyName);
}

/*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
import com.fasterxml.jackson.databind.deser.*;
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
import com.fasterxml.jackson.databind.jsontype.NamedType;
Expand Down Expand Up @@ -556,6 +558,92 @@ public B polymorphicTypeValidator(PolymorphicTypeValidator ptv) {
return _this();
}

/*
/**********************************************************************
/* Default typing
/**********************************************************************
*/

/**
* Convenience method that is equivalent to calling
*<pre>
* enableDefaultTyping(subtypeValidator, DefaultTyping.OBJECT_AND_NON_CONCRETE);
*</pre>
*<p>
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*/
public B enableDefaultTyping(PolymorphicTypeValidator subtypeValidator) {
_mapper.enableDefaultTyping(subtypeValidator);
return _this();
}

/**
* Convenience method that is equivalent to calling
*<pre>
* enableDefaultTyping(subtypeValidator, dti, JsonTypeInfo.As.WRAPPER_ARRAY);
*</pre>
*<p>
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*/
public B enableDefaultTyping(PolymorphicTypeValidator subtypeValidator,
DefaultTyping dti) {
_mapper.enableDefaultTyping(subtypeValidator, dti);
return _this();
}

/**
* Method for enabling automatic inclusion of type information, needed
* for proper deserialization of polymorphic types (unless types
* have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}).
*<P>
* NOTE: use of <code>JsonTypeInfo.As#EXTERNAL_PROPERTY</code> <b>NOT SUPPORTED</b>;
* and attempts of do so will throw an {@link IllegalArgumentException} to make
* this limitation explicit.
*<p>
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*
* @param applicability Defines kinds of types for which additional type information
* is added; see {@link DefaultTyping} for more information.
*/
public B enableDefaultTyping(PolymorphicTypeValidator subtypeValidator,
DefaultTyping applicability, JsonTypeInfo.As includeAs)
{
_mapper.enableDefaultTyping(subtypeValidator, applicability, includeAs);
return _this();
}

/**
* Method for enabling automatic inclusion of type information -- needed
* for proper deserialization of polymorphic types (unless types
* have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) --
* using "As.PROPERTY" inclusion mechanism and specified property name
* to use for inclusion (default being "@class" since default type information
* always uses class name as type identifier)
*<p>
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
* as allowing all subtypes can be risky for untrusted content.
*/
public B enableDefaultTypingAsProperty(PolymorphicTypeValidator subtypeValidator,
DefaultTyping applicability, String propertyName)
{
_mapper.enableDefaultTypingAsProperty(subtypeValidator, applicability, propertyName);
return _this();
}

/**
* Method for disabling automatic inclusion of type information; if so, only
* explicitly annotated types (ones with
* {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) will have
* additional embedded type information.
*/
public B disableDefaultTyping() {
_mapper.disableDefaultTyping();
return _this();
}

/*
/**********************************************************************
/* Other helper methods
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,12 @@ public Validity validateSubType(MapperConfig<?> ctxt, JavaType baseType, JavaTyp
// // // Mappers with Default Typing

private final ObjectMapper MAPPER_DEF_TYPING_NAME_CHECK = jsonMapperBuilder()
.polymorphicTypeValidator(new SimpleNameBasedValidator())
.build()
.enableDefaultTyping();
.enableDefaultTyping(new SimpleNameBasedValidator())
.build();

private final ObjectMapper MAPPER_DEF_TYPING_CLASS_CHECK = jsonMapperBuilder()
.polymorphicTypeValidator(new SimpleClassBasedValidator())
.build()
.enableDefaultTyping();
.enableDefaultTyping(new SimpleClassBasedValidator())
.build();

// // // Mappers without Default Typing (explicit annotation needed)

Expand Down

0 comments on commit 01ed12c

Please sign in to comment.