Skip to content

Commit 01ed12c

Browse files
committed
More work on #2195
1 parent 03dd8cd commit 01ed12c

File tree

3 files changed

+184
-57
lines changed

3 files changed

+184
-57
lines changed

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

+92-51
Original file line numberDiff line numberDiff line change
@@ -1525,7 +1525,43 @@ public ObjectMapper setDefaultMergeable(Boolean b) {
15251525

15261526
/*
15271527
/**********************************************************
1528-
/* Type information configuration
1528+
/* Subtype registration
1529+
/**********************************************************
1530+
*/
1531+
1532+
/**
1533+
* Method for registering specified class as a subtype, so that
1534+
* typename-based resolution can link supertypes to subtypes
1535+
* (as an alternative to using annotations).
1536+
* Type for given class is determined from appropriate annotation;
1537+
* or if missing, default name (unqualified class name)
1538+
*/
1539+
public void registerSubtypes(Class<?>... classes) {
1540+
getSubtypeResolver().registerSubtypes(classes);
1541+
}
1542+
1543+
/**
1544+
* Method for registering specified class as a subtype, so that
1545+
* typename-based resolution can link supertypes to subtypes
1546+
* (as an alternative to using annotations).
1547+
* Name may be provided as part of argument, but if not will
1548+
* be based on annotations or use default name (unqualified
1549+
* class name).
1550+
*/
1551+
public void registerSubtypes(NamedType... types) {
1552+
getSubtypeResolver().registerSubtypes(types);
1553+
}
1554+
1555+
/**
1556+
* @since 2.9
1557+
*/
1558+
public void registerSubtypes(Collection<Class<?>> subtypes) {
1559+
getSubtypeResolver().registerSubtypes(subtypes);
1560+
}
1561+
1562+
/*
1563+
/**********************************************************
1564+
/* Default typing (automatic polymorphic types): current (2.10)
15291565
/**********************************************************
15301566
*/
15311567

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

15481583
/**
@@ -1551,14 +1586,14 @@ public ObjectMapper enableDefaultTyping() {
15511586
* enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
15521587
*</pre>
15531588
*<p>
1554-
* NOTE: use of Default Typing can be a potential security risk if incoming
1555-
* content comes from untrusted sources, and it is recommended that this
1556-
* is either not done, or, if enabled, use {@link #setDefaultTyping}
1557-
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
1558-
* legal types to use.
1589+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
1590+
* as allowing all subtypes can be risky for untrusted content.
1591+
*
1592+
* @since 2.10
15591593
*/
1560-
public ObjectMapper enableDefaultTyping(DefaultTyping dti) {
1561-
return enableDefaultTyping(dti, JsonTypeInfo.As.WRAPPER_ARRAY);
1594+
public ObjectMapper enableDefaultTyping(PolymorphicTypeValidator ptv,
1595+
DefaultTyping dti) {
1596+
return enableDefaultTyping(ptv, dti, JsonTypeInfo.As.WRAPPER_ARRAY);
15621597
}
15631598

15641599
/**
@@ -1570,26 +1605,24 @@ public ObjectMapper enableDefaultTyping(DefaultTyping dti) {
15701605
* and attempts of do so will throw an {@link IllegalArgumentException} to make
15711606
* this limitation explicit.
15721607
*<p>
1573-
* NOTE: use of Default Typing can be a potential security risk if incoming
1574-
* content comes from untrusted sources, and it is recommended that this
1575-
* is either not done, or, if enabled, use {@link #setDefaultTyping}
1576-
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
1577-
* legal types to use.
1608+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
1609+
* as allowing all subtypes can be risky for untrusted content.
15781610
*
15791611
* @param applicability Defines kinds of types for which additional type information
15801612
* is added; see {@link DefaultTyping} for more information.
1613+
*
1614+
* @since 2.10
15811615
*/
1582-
public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInfo.As includeAs)
1616+
public ObjectMapper enableDefaultTyping(PolymorphicTypeValidator ptv,
1617+
DefaultTyping applicability, JsonTypeInfo.As includeAs)
15831618
{
1584-
/* 18-Sep-2014, tatu: Let's add explicit check to ensure no one tries to
1585-
* use "As.EXTERNAL_PROPERTY", since that will not work (with 2.5+)
1586-
*/
1619+
// 18-Sep-2014, tatu: Let's add explicit check to ensure no one tries to
1620+
// use "As.EXTERNAL_PROPERTY", since that will not work (with 2.5+)
15871621
if (includeAs == JsonTypeInfo.As.EXTERNAL_PROPERTY) {
15881622
throw new IllegalArgumentException("Cannot use includeAs of "+includeAs);
15891623
}
15901624

1591-
TypeResolverBuilder<?> typer = _constructDefaultTypeResolverBuilder(applicability,
1592-
getPolymorphicTypeValidator());
1625+
TypeResolverBuilder<?> typer = _constructDefaultTypeResolverBuilder(applicability, ptv);
15931626
// we'll always use full class name, when using defaulting
15941627
typer = typer.init(JsonTypeInfo.Id.CLASS, null);
15951628
typer = typer.inclusion(includeAs);
@@ -1604,13 +1637,13 @@ public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInf
16041637
* to use for inclusion (default being "@class" since default type information
16051638
* always uses class name as type identifier)
16061639
*<p>
1607-
* NOTE: use of Default Typing can be a potential security risk if incoming
1608-
* content comes from untrusted sources, and it is recommended that this
1609-
* is either not done, or, if enabled, use {@link #setDefaultTyping}
1610-
* passing a custom {@link TypeResolverBuilder} implementation that white-lists
1611-
* legal types to use.
1640+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
1641+
* as allowing all subtypes can be risky for untrusted content.
1642+
*
1643+
* @since 2.10
16121644
*/
1613-
public ObjectMapper enableDefaultTypingAsProperty(DefaultTyping applicability, String propertyName)
1645+
public ObjectMapper enableDefaultTypingAsProperty(PolymorphicTypeValidator ptv,
1646+
DefaultTyping applicability, String propertyName)
16141647
{
16151648
TypeResolverBuilder<?> typer = _constructDefaultTypeResolverBuilder(applicability,
16161649
getPolymorphicTypeValidator());
@@ -1641,7 +1674,7 @@ public ObjectMapper disableDefaultTyping() {
16411674
* content comes from untrusted sources, so care should be taken to use
16421675
* a {@link TypeResolverBuilder} that can limit allowed classes to
16431676
* deserialize.
1644-
*
1677+
*
16451678
* @param typer Type information inclusion handler
16461679
*/
16471680
public ObjectMapper setDefaultTyping(TypeResolverBuilder<?> typer) {
@@ -1650,34 +1683,42 @@ public ObjectMapper setDefaultTyping(TypeResolverBuilder<?> typer) {
16501683
return this;
16511684
}
16521685

1686+
/*
1687+
/**********************************************************
1688+
/* Default typing (automatic polymorphic types): deprecated (pre-2.10)
1689+
/**********************************************************
1690+
*/
1691+
16531692
/**
1654-
* Method for registering specified class as a subtype, so that
1655-
* typename-based resolution can link supertypes to subtypes
1656-
* (as an alternative to using annotations).
1657-
* Type for given class is determined from appropriate annotation;
1658-
* or if missing, default name (unqualified class name)
1693+
* @deprecated Since 2.10 use {@link #enableDefaultTyping(PolymorphicTypeValidator)} instead
16591694
*/
1660-
public void registerSubtypes(Class<?>... classes) {
1661-
getSubtypeResolver().registerSubtypes(classes);
1695+
@Deprecated
1696+
public ObjectMapper enableDefaultTyping() {
1697+
return enableDefaultTyping(getPolymorphicTypeValidator());
16621698
}
16631699

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

16761708
/**
1677-
* @since 2.9
1709+
* @deprecated Since 2.10 use {@link #enableDefaultTyping(PolymorphicTypeValidator,DefaultTyping,JsonTypeInfo.As)} instead
16781710
*/
1679-
public void registerSubtypes(Collection<Class<?>> subtypes) {
1680-
getSubtypeResolver().registerSubtypes(subtypes);
1711+
@Deprecated
1712+
public ObjectMapper enableDefaultTyping(DefaultTyping applicability, JsonTypeInfo.As includeAs) {
1713+
return enableDefaultTyping(getPolymorphicTypeValidator(), applicability, includeAs);
1714+
}
1715+
1716+
/**
1717+
* @deprecated Since 2.10 use {@link #enableDefaultTypingAsProperty(PolymorphicTypeValidator,DefaultTyping,String)} instead
1718+
*/
1719+
@Deprecated
1720+
public ObjectMapper enableDefaultTypingAsProperty(DefaultTyping applicability, String propertyName) {
1721+
return enableDefaultTypingAsProperty(getPolymorphicTypeValidator(), applicability, propertyName);
16811722
}
16821723

16831724
/*

src/main/java/com/fasterxml/jackson/databind/cfg/MapperBuilder.java

+88
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77

88
import com.fasterxml.jackson.annotation.JsonAutoDetect;
99
import com.fasterxml.jackson.annotation.JsonInclude;
10+
import com.fasterxml.jackson.annotation.JsonTypeInfo;
1011
import com.fasterxml.jackson.annotation.PropertyAccessor;
1112
import com.fasterxml.jackson.core.*;
1213
import com.fasterxml.jackson.databind.*;
14+
import com.fasterxml.jackson.databind.ObjectMapper.DefaultTyping;
1315
import com.fasterxml.jackson.databind.deser.*;
1416
import com.fasterxml.jackson.databind.introspect.VisibilityChecker;
1517
import com.fasterxml.jackson.databind.jsontype.NamedType;
@@ -556,6 +558,92 @@ public B polymorphicTypeValidator(PolymorphicTypeValidator ptv) {
556558
return _this();
557559
}
558560

561+
/*
562+
/**********************************************************************
563+
/* Default typing
564+
/**********************************************************************
565+
*/
566+
567+
/**
568+
* Convenience method that is equivalent to calling
569+
*<pre>
570+
* enableDefaultTyping(subtypeValidator, DefaultTyping.OBJECT_AND_NON_CONCRETE);
571+
*</pre>
572+
*<p>
573+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
574+
* as allowing all subtypes can be risky for untrusted content.
575+
*/
576+
public B enableDefaultTyping(PolymorphicTypeValidator subtypeValidator) {
577+
_mapper.enableDefaultTyping(subtypeValidator);
578+
return _this();
579+
}
580+
581+
/**
582+
* Convenience method that is equivalent to calling
583+
*<pre>
584+
* enableDefaultTyping(subtypeValidator, dti, JsonTypeInfo.As.WRAPPER_ARRAY);
585+
*</pre>
586+
*<p>
587+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
588+
* as allowing all subtypes can be risky for untrusted content.
589+
*/
590+
public B enableDefaultTyping(PolymorphicTypeValidator subtypeValidator,
591+
DefaultTyping dti) {
592+
_mapper.enableDefaultTyping(subtypeValidator, dti);
593+
return _this();
594+
}
595+
596+
/**
597+
* Method for enabling automatic inclusion of type information, needed
598+
* for proper deserialization of polymorphic types (unless types
599+
* have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}).
600+
*<P>
601+
* NOTE: use of <code>JsonTypeInfo.As#EXTERNAL_PROPERTY</code> <b>NOT SUPPORTED</b>;
602+
* and attempts of do so will throw an {@link IllegalArgumentException} to make
603+
* this limitation explicit.
604+
*<p>
605+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
606+
* as allowing all subtypes can be risky for untrusted content.
607+
*
608+
* @param applicability Defines kinds of types for which additional type information
609+
* is added; see {@link DefaultTyping} for more information.
610+
*/
611+
public B enableDefaultTyping(PolymorphicTypeValidator subtypeValidator,
612+
DefaultTyping applicability, JsonTypeInfo.As includeAs)
613+
{
614+
_mapper.enableDefaultTyping(subtypeValidator, applicability, includeAs);
615+
return _this();
616+
}
617+
618+
/**
619+
* Method for enabling automatic inclusion of type information -- needed
620+
* for proper deserialization of polymorphic types (unless types
621+
* have been annotated with {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) --
622+
* using "As.PROPERTY" inclusion mechanism and specified property name
623+
* to use for inclusion (default being "@class" since default type information
624+
* always uses class name as type identifier)
625+
*<p>
626+
* NOTE: choice of {@link PolymorphicTypeValidator} to pass is critical for security
627+
* as allowing all subtypes can be risky for untrusted content.
628+
*/
629+
public B enableDefaultTypingAsProperty(PolymorphicTypeValidator subtypeValidator,
630+
DefaultTyping applicability, String propertyName)
631+
{
632+
_mapper.enableDefaultTypingAsProperty(subtypeValidator, applicability, propertyName);
633+
return _this();
634+
}
635+
636+
/**
637+
* Method for disabling automatic inclusion of type information; if so, only
638+
* explicitly annotated types (ones with
639+
* {@link com.fasterxml.jackson.annotation.JsonTypeInfo}) will have
640+
* additional embedded type information.
641+
*/
642+
public B disableDefaultTyping() {
643+
_mapper.disableDefaultTyping();
644+
return _this();
645+
}
646+
559647
/*
560648
/**********************************************************************
561649
/* Other helper methods

src/test/java/com/fasterxml/jackson/databind/jsontype/vld/ValidatePolymSubTypeTest.java

+4-6
Original file line numberDiff line numberDiff line change
@@ -113,14 +113,12 @@ public Validity validateSubType(MapperConfig<?> ctxt, JavaType baseType, JavaTyp
113113
// // // Mappers with Default Typing
114114

115115
private final ObjectMapper MAPPER_DEF_TYPING_NAME_CHECK = jsonMapperBuilder()
116-
.polymorphicTypeValidator(new SimpleNameBasedValidator())
117-
.build()
118-
.enableDefaultTyping();
116+
.enableDefaultTyping(new SimpleNameBasedValidator())
117+
.build();
119118

120119
private final ObjectMapper MAPPER_DEF_TYPING_CLASS_CHECK = jsonMapperBuilder()
121-
.polymorphicTypeValidator(new SimpleClassBasedValidator())
122-
.build()
123-
.enableDefaultTyping();
120+
.enableDefaultTyping(new SimpleClassBasedValidator())
121+
.build();
124122

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

0 commit comments

Comments
 (0)