Skip to content
Commits on Source (3)
......@@ -5,12 +5,12 @@
<parent>
<groupId>com.fasterxml.jackson</groupId>
<artifactId>jackson-base</artifactId>
<version>2.9.5</version>
<version>2.9.8</version>
</parent>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.5</version>
<version>2.9.8</version>
<name>jackson-databind</name>
<packaging>bundle</packaging>
<description>General data-binding functionality for Jackson: works on core streaming API</description>
......@@ -21,7 +21,7 @@
<connection>scm:git:git@github.com:FasterXML/jackson-databind.git</connection>
<developerConnection>scm:git:git@github.com:FasterXML/jackson-databind.git</developerConnection>
<url>http://github.com/FasterXML/jackson-databind</url>
<tag>jackson-databind-2.9.5</tag>
<tag>jackson-databind-2.9.8</tag>
</scm>
<properties>
......@@ -70,13 +70,13 @@
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-module-junit4</artifactId>
<version>1.7.3</version>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito</artifactId>
<version>1.7.3</version>
<version>1.7.4</version>
<scope>test</scope>
</dependency>
<!-- For testing TestNoClassDefFoundDeserializer -->
......@@ -88,6 +88,18 @@
</dependency>
</dependencies>
<!-- Alas, need to include snapshot reference since otherwise can not find
snapshot of parent... -->
<repositories>
<repository>
<id>sonatype-nexus-snapshots</id>
<name>Sonatype Nexus Snapshots</name>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
<build>
<plugins>
<!-- Important: enable enforcer plug-in: -->
......
......@@ -649,6 +649,14 @@ Kevin Gallardo (newkek@github)
Lukas Euler
* Reported #1735: Missing type checks when using polymorphic type ids
Guixiong Wu (吴桂雄)
* Reported #2032: Blacklist another serialization gadget (ibatis)
(2.8.11.2)
svarzee@github
* Reported #2109, suggested fix: Canonical string for reference type is built incorrectly
(2.8.11.3 / 2.9.7)
Connor Kuhn (ckuhn@github)
* Contributed #1341: FAIL_ON_MISSING_EXTERNAL_TYPE_ID_PROPERTY
(2.9.0)
......@@ -767,3 +775,51 @@ roeltje25@github
* Reported #1978: Using @JsonUnwrapped annotation in builderdeserializer hangs in
infinite loop
(2.9.5)
Freddy Boucher (freddyboucher@github)
* Reported #1990: MixIn `@JsonProperty` for `Object.hashCode()` is ignored
(2.9.6)
Ondrej Zizka (OndraZizk@github)
* Reported #1999: "Duplicate property" issue should mention which class it complains about
(2.9.6)
Jakub Skierbiszewski (jskierbi@github)
* Reported, contributed fix for #2001: Deserialization issue with `@JsonIgnore` and
`@JsonCreator` + `@JsonProperty` for same property name
(2.9.6)
Carter Kozak (cakofony@github)
* Reported #2016: Delegating JsonCreator disregards JsonDeserialize info
(2.9.6)
Reinhard Prechtl (dnno@github)
* Reported #2034: Serialization problem with type specialization of nested generic types
(2.9.6)
Chetan Narsude (243826@github)
* Reported #2038: JDK Serializing and using Deserialized `ObjectMapper` loses linkage
back from `JsonParser.getCodec()`
(2.9.6)
Petar Tahchiev (ptahchiev@github)
* Reported #2060: `UnwrappingBeanPropertyWriter` incorrectly assumes the found
serializer is of type `UnwrappingBeanSerializer`
(2.9.6)
Brandon Krieger (bkrieger@github)
* Reported #2064: Cannot set custom format for `SqlDateSerializer` globally
(2.9.7)
Semyon Levin (remal@github)
* Contributed #2120: `NioPathDeserializer` improvement
(2.9.7)
Pavel Nikitin (morj@github)
* Requested #2181: Don't re-use dynamic serializers for property-updating copy constructors
(2.9.8)
René Kschamer (flawi@github)
* Reported #2197: Illegal reflective access operation warning when using `java.lang.Void`
as value type
(2.9.8)
......@@ -4,6 +4,98 @@ Project: jackson-databind
=== Releases ===
------------------------------------------------------------------------
2.9.8 (15-Dec-2018)
#1662: `ByteBuffer` serialization is broken if offset is not 0
(reported by j-baker@github)
#2155: Type parameters are checked for equality while isAssignableFrom expected
(reported by frankfiedler@github)
#2167: Large ISO-8601 Dates are formatted/serialized incorrectly
#2181: Don't re-use dynamic serializers for property-updating copy constructors
(suggested by Pavel N)
#2183: Base64 JsonMappingException: Unexpected end-of-input
(reported by ViToni@github)
#2186: Block more classes from polymorphic deserialization (CVE-2018-19360,
CVE-2018-19361, CVE-2018-19362)
(reported by Guixiong Wu)
#2197: Illegal reflective access operation warning when using `java.lang.Void`
as value type
(reported by René K)
#2202: StdKeyDeserializer Class method _getToStringResolver is slow causing Thread Block
(reported by sushobhitrajan@github)
2.9.7 (19-Sep-2018)
#2060: `UnwrappingBeanPropertyWriter` incorrectly assumes the found serializer is
of type `UnwrappingBeanSerializer`
(reported by Petar T)
#2064: Cannot set custom format for `SqlDateSerializer` globally
(reported by Brandon K)
#2079: NPE when visiting StaticListSerializerBase
(reported by WorldSEnder@github)
#2082: `FactoryBasedEnumDeserializer` should be cachable
#2088: `@JsonUnwrapped` fields are skipped when using `PropertyBasedCreator` if
they appear after the last creator property
(reported, fix contributed by 6bangs@github)
#2096: `TreeTraversingParser` does not take base64 variant into account
(reported by tangiel@github)
#2097: Block more classes from polymorphic deserialization (CVE-2018-14718
- CVE-2018-14721)
#2109: Canonical string for reference type is built incorrectly
(reported by svarzee@github)
#2120: `NioPathDeserializer` improvement
(contributed by Semyon L)
#2128: Location information included twice for some `JsonMappingException`s
2.9.6 (12-Jun-2018)
#955: Add `MapperFeature.USE_BASE_TYPE_AS_DEFAULT_IMPL` to use declared base type
as `defaultImpl` for polymorphic deserialization
(contributed by mikeldpl@github)
#1328: External property polymorphic deserialization does not work with enums
#1565: Deserialization failure with Polymorphism using JsonTypeInfo `defaultImpl`,
subtype as target
#1964: Failed to specialize `Map` type during serialization where key type
incompatibility overidden via "raw" types
(reported by ptirador@github)
#1990: MixIn `@JsonProperty` for `Object.hashCode()` is ignored
(reported by Freddy B)
#1991: Context attributes are not passed/available to custom serializer if object is in POJO
(reported by dletin@github)
#1998: Removing "type" attribute with Mixin not taken in account if
using ObjectMapper.copy()
(reported by SBKila@github)
#1999: "Duplicate property" issue should mention which class it complains about
(reported by Ondrej Z)
#2001: Deserialization issue with `@JsonIgnore` and `@JsonCreator` + `@JsonProperty`
for same property name
(reported, fix contributed by Jakub S)
#2015: `@Jsonsetter with Nulls.SKIP` collides with
`DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL` when parsing enum
(reported by ndori@github)
#2016: Delegating JsonCreator disregards JsonDeserialize info
(reported by Carter K)
#2019: Abstract Type mapping in 2.9 fails when multiple modules are registered
(reported by asger82@github)
#2021: Delegating JsonCreator disregards `JsonDeserialize.using` annotation
#2023: `JsonFormat.Feature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT` not working
with `null` coercion with `@JsonSetter`
#2027: Concurrency error causes `IllegalStateException` on `BeanPropertyMap`
(reported by franboragina@github)
#2032: CVE-2018-11307: Potential information exfiltration with default typing, serialization gadget from MyBatis
(reported by Guixiong Wu)
#2034: Serialization problem with type specialization of nested generic types
(reported by Reinhard P)
#2038: JDK Serializing and using Deserialized `ObjectMapper` loses linkage
back from `JsonParser.getCodec()`
(reported by Chetan N)
#2051: Implicit constructor property names are not renamed properly with
`PropertyNamingStrategy`
#2052: CVE-2018-12022: Block polymorphic deserialization of types from Jodd-db library
(reported by Guixiong Wu)
#2058: CVE-2018-12023: Block polymorphic deserialization of types from Oracle JDBC driver
(reported by Guixiong Wu)
2.9.5 (26-Mar-2018)
#1911: Allow serialization of `BigDecimal` as String, using
......@@ -146,6 +238,7 @@ Project: jackson-databind
#1029: Add a way to define property name aliases
#1035: `@JsonAnySetter` assumes key of `String`, does not consider declared type.
(reported by Michael F)
#1060: Allow use of `@JsonIgnoreProperties` for POJO-valued arrays, `Collection`s
#1106: Add `MapperFeature.ALLOW_COERCION_OF_SCALARS` for enabling/disabling coercions
#1284: Make `StdKeySerializers` use new `JsonGenerator.writeFieldId()` for `int`/`long` keys
#1320: Add `ObjectNode.put(String, BigInteger)`
......@@ -221,6 +314,18 @@ Project: jackson-databind
`MapperFeature.ALLOW_COERCION_OF_SCALARS`
(requested by magdel@github)
2.8.11.2 (08-Jun-2018)
#1941: `TypeFactory.constructFromCanonical()` throws NPE for Unparameterized
generic canonical strings
(reported by ayushgp@github)
#2032: CVE-2018-11307: Potential information exfiltration with default typing, serialization gadget from MyBatis
(reported by Guixiong Wu)
#2052: CVE-2018-12022: Block polymorphic deserialization of types from Jodd-db library
(reported by Guixiong Wu)
#2058: CVE-2018-12023: Block polymorphic deserialization of types from Oracle JDBC driver
(reported by Guixiong Wu)
2.8.11.1 (11-Feb-2018)
#1872: `NullPointerException` in `SubTypeValidator.validateSubType` when
......@@ -507,9 +612,10 @@ Project: jackson-databind
#1225: `JsonMappingException` should override getProcessor()
(reported by Nick B)
2.6.8 (if ever released)
2.6.7.1 (11-Jul-2017)
#1383: Problem with `@JsonCreator` with 1-arg factory-method, implicit param names
#1599: Backport the extra safety checks for polymorphic deserialization
2.6.7 (05-Jun-2016)
......
......@@ -191,7 +191,8 @@ public abstract class DatabindContext
} catch (Exception e) {
throw invalidTypeIdException(baseType, subClass, String.format(
"problem: (%s) %s",
e.getClass().getName(), e.getMessage()));
e.getClass().getName(),
ClassUtil.exceptionMessage(e)));
}
if (baseType.isTypeOrSuperTypeOf(cls)) {
return getTypeFactory().constructSpecializedType(baseType, cls);
......
......@@ -710,7 +710,8 @@ public abstract class DeserializationContext
return df.parse(dateStr);
} catch (ParseException e) {
throw new IllegalArgumentException(String.format(
"Failed to parse Date value '%s': %s", dateStr, e.getMessage()));
"Failed to parse Date value '%s': %s", dateStr,
ClassUtil.exceptionMessage(e)));
}
}
......@@ -1589,15 +1590,21 @@ trailingToken, ClassUtil.nameOf(targetType)
* to indicate problem with physically constructing instance of
* specified class (missing constructor, exception from constructor)
*<p>
* Note that most of the time this method should NOT be called; instead,
* Note that most of the time this method should NOT be called directly; instead,
* {@link #handleInstantiationProblem} should be called which will call this method
* if necessary.
*/
public JsonMappingException instantiationException(Class<?> instClass, Throwable cause) {
// Most likely problem with Creator definition, right?
JavaType type = constructType(instClass);
final JavaType type = constructType(instClass);
String excMsg;
if (cause == null) {
excMsg = "N/A";
} else if ((excMsg = ClassUtil.exceptionMessage(cause)) == null) {
excMsg = ClassUtil.nameOf(cause.getClass());
}
String msg = String.format("Cannot construct instance of %s, problem: %s",
ClassUtil.nameOf(instClass), cause.getMessage());
ClassUtil.nameOf(instClass), excMsg);
InvalidDefinitionException e = InvalidDefinitionException.from(_parser, msg, type);
e.initCause(cause);
return e;
......
......@@ -7,6 +7,7 @@ import java.util.*;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.util.ClassUtil;
/**
* Checked exception used to signal fatal problems with mapping of
......@@ -335,7 +336,8 @@ public class JsonMappingException
public static JsonMappingException fromUnexpectedIOE(IOException src) {
return new JsonMappingException(null,
String.format("Unexpected IOException (of type %s): %s",
src.getClass().getName(), src.getMessage()));
src.getClass().getName(),
ClassUtil.exceptionMessage(src)));
}
/**
......@@ -375,7 +377,8 @@ public class JsonMappingException
if (src instanceof JsonMappingException) {
jme = (JsonMappingException) src;
} else {
String msg = src.getMessage();
// [databind#2128]: try to avoid duplication
String msg = ClassUtil.exceptionMessage(src);
// Let's use a more meaningful placeholder if all we have is null
if (msg == null || msg.length() == 0) {
msg = "(was "+src.getClass().getName()+")";
......@@ -486,9 +489,7 @@ public class JsonMappingException
protected String _buildMessage()
{
/* First: if we have no path info, let's just use parent's
* definition as is
*/
// First: if we have no path info, let's just use parent's definition as is
String msg = super.getMessage();
if (_path == null) {
return msg;
......
......@@ -727,7 +727,7 @@ public abstract class JsonNode
*<p>
* This method is functionally equivalent to:
*<pre>
* node.get(fieldName) != null &lt;&lt; !node.get(fieldName).isNull()
* node.get(fieldName) != null &amp;&amp; !node.get(fieldName).isNull()
*</pre>
*
* @since 2.1
......@@ -743,7 +743,7 @@ public abstract class JsonNode
*<p>
* This method is equivalent to:
*<pre>
* node.get(index) != null &lt;&lt; !node.get(index).isNull()
* node.get(index) != null &amp;&amp; !node.get(index).isNull()
*</pre>
*
* @since 2.1
......
......@@ -286,6 +286,20 @@ public enum MapperFeature implements ConfigFeature
*/
USE_STATIC_TYPING(false),
/**
* Feature that specifies whether the declared base type of a polymorphic value
* is to be used as the "default" implementation, if no explicit default class
* is specified via {@code @JsonTypeInfo.defaultImpl} annotation.
*<p>
* Note that feature only has effect on deserialization of regular polymorphic properties:
* it does NOT affect non-polymorphic cases, and is unlikely to work with Default Typing.
*<p>
* Feature is disabled by default for backwards compatibility.
*
* @since 2.9.6
*/
USE_BASE_TYPE_AS_DEFAULT_IMPL(false),
/*
/******************************************************
/* View-related features
......
......@@ -953,6 +953,18 @@ public class ObjectMapper
return this;
}
/**
* The set of {@link Module} typeIds that are registered in this
* ObjectMapper. By default the typeId for a module is it's full
* class name (see {@link Module#getTypeId()}).
*
* @since 2.9.6
*/
public Set<Object> getRegisteredModuleIds()
{
return Collections.unmodifiableSet(_registeredModuleTypes);
}
/**
* Method for locating available methods, using JDK {@link ServiceLoader}
* facility, along with module-provided SPI.
......
......@@ -1335,11 +1335,10 @@ public abstract class SerializerProvider
try {
ser = _createUntypedSerializer(fullType);
} catch (IllegalArgumentException iae) {
/* We better only expose checked exceptions, since those
* are what caller is expected to handle
*/
// We better only expose checked exceptions, since those
// are what caller is expected to handle
ser = null; // doesn't matter but compiler whines otherwise
reportMappingProblem(iae, iae.getMessage());
reportMappingProblem(iae, ClassUtil.exceptionMessage(iae));
}
if (ser != null) {
......@@ -1359,7 +1358,7 @@ public abstract class SerializerProvider
// We better only expose checked exceptions, since those
// are what caller is expected to handle
ser = null;
reportMappingProblem(iae, iae.getMessage());
reportMappingProblem(iae, ClassUtil.exceptionMessage(iae));
}
if (ser != null) {
......@@ -1380,6 +1379,10 @@ public abstract class SerializerProvider
* since there's one instance per serialization).
* Perhaps not-yet-resolved instance might be exposed too early to callers.
*/
// 13-Apr-2018, tatu: Problem does NOT occur any more with late 2.8.x and 2.9.x
// versions, likely due to concurrency fixes for `AnnotatedClass` introspection.
// This sync block could probably be removed; but to minimize any risk of
// regression sync block will only be removed from 3.0.
synchronized (_serializerCache) {
// 17-Feb-2013, tatu: Used to call deprecated method (that passed property)
return (JsonSerializer<Object>)_serializerFactory.createSerializer(this, type);
......
......@@ -147,6 +147,26 @@ public final class BaseSettings
_defaultBase64 = defaultBase64;
}
/**
* Turns out we are not necessarily 100% stateless, alas, since {@link ClassIntrospector}
* typically has a cache. So this method is needed for deep copy() of Mapper.
*
* @since 2.9.6
*/
public BaseSettings copy() {
return new BaseSettings(_classIntrospector.copy(),
_annotationIntrospector,
_propertyNamingStrategy,
_typeFactory,
_typeResolverBuilder,
_dateFormat,
_handlerInstantiator,
_locale,
_timeZone,
_defaultBase64);
}
/*
/**********************************************************
/* Factory methods
......
......@@ -79,6 +79,8 @@ public abstract class ConfigOverride
_include = src._include;
_includeAsProperty = src._includeAsProperty;
_ignorals = src._ignorals;
_setterInfo = src._setterInfo;
_visibility = src._visibility;
_isIgnoredType = src._isIgnoredType;
_mergeable = src._mergeable;
}
......
......@@ -134,13 +134,18 @@ public abstract class MapperConfigBase<CFG extends ConfigFeature,
}
/**
* Copy constructor usually called to make a copy for use by
* ObjectMapper that is copied.
*
* @since 2.8
*/
protected MapperConfigBase(MapperConfigBase<CFG,T> src,
SimpleMixInResolver mixins, RootNameLookup rootNames,
ConfigOverrides configOverrides)
{
super(src);
// 18-Apr-2018, tatu: [databind#1898] need to force copying of `ClassIntrospector`
// (to clear its cache) to avoid leakage
super(src, src._base.copy());
_mixIns = mixins;
_subtypeResolver = src._subtypeResolver;
_rootNames = rootNames;
......
......@@ -9,6 +9,7 @@ import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonCreator.Mode;
import com.fasterxml.jackson.core.JsonLocation;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.cfg.DeserializerFactoryConfig;
import com.fasterxml.jackson.databind.cfg.HandlerInstantiator;
......@@ -16,6 +17,7 @@ import com.fasterxml.jackson.databind.deser.impl.CreatorCandidate;
import com.fasterxml.jackson.databind.deser.impl.CreatorCollector;
import com.fasterxml.jackson.databind.deser.impl.JavaUtilCollectionsDeserializers;
import com.fasterxml.jackson.databind.deser.std.*;
import com.fasterxml.jackson.databind.exc.InvalidDefinitionException;
import com.fasterxml.jackson.databind.ext.OptionalHandlerFactory;
import com.fasterxml.jackson.databind.introspect.*;
import com.fasterxml.jackson.databind.jsontype.NamedType;
......@@ -214,7 +216,7 @@ public abstract class BasicDeserializerFactory
if (_factoryConfig.hasAbstractTypeResolvers()) {
for (AbstractTypeResolver resolver : _factoryConfig.abstractTypeResolvers()) {
JavaType concrete = resolver.findTypeMapping(config, type);
if (ClassUtil.rawClass(concrete) != currClass) {
if ((concrete != null) && !concrete.hasRawClass(currClass)) {
return concrete;
}
}
......@@ -273,7 +275,8 @@ public abstract class BasicDeserializerFactory
if (instantiator.getIncompleteParameter() != null) {
final AnnotatedParameter nonAnnotatedParam = instantiator.getIncompleteParameter();
final AnnotatedWithParams ctor = nonAnnotatedParam.getOwner();
throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()+" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator");
throw new IllegalArgumentException("Argument #"+nonAnnotatedParam.getIndex()
+" of constructor "+ctor+" has no property name annotation; must have name when multiple-parameter constructor annotated as Creator");
}
return instantiator;
......@@ -336,7 +339,7 @@ public abstract class BasicDeserializerFactory
if (beanDesc.getType().isConcrete()) {
_addDeserializerConstructors(ctxt, beanDesc, vchecker, intr, creators, creatorDefs);
}
return creators.constructValueInstantiator(config);
return creators.constructValueInstantiator(ctxt);
}
protected Map<AnnotatedWithParams,BeanPropertyDefinition[]> _findCreatorsFromProperties(DeserializationContext ctxt,
......@@ -725,7 +728,11 @@ nonAnnotatedParamIndex, ctor);
if (!useProps && (paramDef != null)) {
// One more thing: if implicit name matches property with a getter
// or field, we'll consider it property-based as well
paramName = candidate.findImplicitParamName(0);
// 25-May-2018, tatu: as per [databind#2051], looks like we have to get
// not implicit name, but name with possible strategy-based-rename
// paramName = candidate.findImplicitParamName(0);
paramName = candidate.paramName(0);
useProps = (paramName != null) && paramDef.couldSerialize();
}
if (useProps) {
......@@ -1554,9 +1561,8 @@ nonAnnotatedParamIndex, ctor);
AnnotationIntrospector ai = config.getAnnotationIntrospector();
TypeResolverBuilder<?> b = ai.findTypeResolver(config, ac, baseType);
/* Ok: if there is no explicit type info handler, we may want to
* use a default. If so, config object knows what to use.
*/
// Ok: if there is no explicit type info handler, we may want to
// use a default. If so, config object knows what to use.
Collection<NamedType> subtypes = null;
if (b == null) {
b = config.getDefaultTyper(baseType);
......@@ -1574,7 +1580,16 @@ nonAnnotatedParamIndex, ctor);
b = b.defaultImpl(defaultType.getRawClass());
}
}
// 05-Apt-2018, tatu: Since we get non-mapping exception due to various limitations,
// map to better type here
try {
return b.buildTypeDeserializer(config, baseType, subtypes);
} catch (IllegalArgumentException e0) {
InvalidDefinitionException e = InvalidDefinitionException.from((JsonParser) null,
ClassUtil.exceptionMessage(e0), baseType);
e.initCause(e0);
throw e;
}
}
/**
......@@ -2133,36 +2148,6 @@ nonAnnotatedParamIndex, ctor);
if (intr == null) {
return type;
}
// First, deserializers for key/value types?
/*
if (type.isMapLikeType()) {
JavaType keyType = type.getKeyType();
// 21-Mar-2011, tatu: ... and associated deserializer too (unless already assigned)
// (not 100% why or how, but this does seem to get called more than once, which
// is not good: for now, let's just avoid errors)
if (keyType != null && keyType.getValueHandler() == null) {
Object kdDef = intr.findKeyDeserializer(a);
KeyDeserializer kd = ctxt.keyDeserializerInstance(a, kdDef);
if (kd != null) {
type = (T) ((MapLikeType) type).withKeyValueHandler(kd);
keyType = type.getKeyType(); // just in case it's used below
}
}
}
JavaType contentType = type.getContentType();
if (contentType != null) {
// ... as well as deserializer for contents:
if (contentType.getValueHandler() == null) { // as with above, avoid resetting (which would trigger exception)
Object cdDef = intr.findContentDeserializer(a);
JsonDeserializer<?> cd = ctxt.deserializerInstance(a, cdDef);
if (cd != null) {
type = (T) type.withContentValueHandler(cd);
}
}
}
*/
// then: type refinement(s)?
return intr.refineDeserializationType(ctxt.getConfig(), a, type);
}
......
......@@ -767,10 +767,17 @@ public class BeanDeserializer
p.setCurrentValue(bean);
// if so, need to copy all remaining tokens into buffer
while (t == JsonToken.FIELD_NAME) {
p.nextToken(); // to skip name
// NOTE: do NOT skip name as it needs to be copied; `copyCurrentStructure` does that
tokens.copyCurrentStructure(p);
t = p.nextToken();
}
// 28-Aug-2018, tatu: Let's add sanity check here, easier to catch off-by-some
// problems if we maintain invariants
if (t != JsonToken.END_OBJECT) {
ctxt.reportWrongTokenException(this, JsonToken.END_OBJECT,
"Attempted to unwrap '%s' value",
handledType().getName());
}
tokens.writeEndObject();
if (bean.getClass() != _beanType.getRawClass()) {
// !!! 08-Jul-2011, tatu: Could probably support; but for now
......
......@@ -617,18 +617,26 @@ public abstract class BeanDeserializerBase
}
}
private JsonDeserializer<Object> _findDelegateDeserializer(DeserializationContext ctxt, JavaType delegateType,
AnnotatedWithParams delegateCreator) throws JsonMappingException {
@SuppressWarnings("unchecked")
private JsonDeserializer<Object> _findDelegateDeserializer(DeserializationContext ctxt,
JavaType delegateType, AnnotatedWithParams delegateCreator) throws JsonMappingException
{
// Need to create a temporary property to allow contextual deserializers:
BeanProperty.Std property = new BeanProperty.Std(TEMP_PROPERTY_NAME,
delegateType, null, delegateCreator,
PropertyMetadata.STD_OPTIONAL);
TypeDeserializer td = delegateType.getTypeHandler();
if (td == null) {
td = ctxt.getConfig().findTypeDeserializer(delegateType);
}
JsonDeserializer<Object> dd = findDeserializer(ctxt, delegateType, property);
// 04-May-2018, tatu: [databind#2021] check if there's custom deserializer attached
// to type (resolved from parameter)
JsonDeserializer<Object> dd = delegateType.getValueHandler();
if (dd == null) {
dd = findDeserializer(ctxt, delegateType, property);
} else {
dd = (JsonDeserializer<Object>) ctxt.handleSecondaryContextualization(dd, property, delegateType);
}
if (td != null) {
td = td.forProperty(property);
return new TypeWrappedDeserializer(td, dd);
......@@ -636,7 +644,6 @@ public abstract class BeanDeserializerBase
return dd;
}
/**
* Helper method that can be used to see if specified property is annotated
* to indicate use of a converter for property value (in case of container types,
......
......@@ -218,7 +218,8 @@ public class BeanDeserializerFactory
// 05-Apr-2017, tatu: Although it might appear cleaner to require collector
// to throw proper exception, it doesn't actually have reference to this
// instance so...
throw InvalidDefinitionException.from(ctxt.getParser(), e.getMessage(),
throw InvalidDefinitionException.from(ctxt.getParser(),
ClassUtil.exceptionMessage(e),
beanDesc, null);
}
BeanDeserializerBuilder builder = constructBeanDeserializerBuilder(ctxt, beanDesc);
......@@ -276,7 +277,8 @@ public class BeanDeserializerFactory
// 05-Apr-2017, tatu: Although it might appear cleaner to require collector
// to throw proper exception, it doesn't actually have reference to this
// instance so...
throw InvalidDefinitionException.from(ctxt.getParser(), e.getMessage(),
throw InvalidDefinitionException.from(ctxt.getParser(),
ClassUtil.exceptionMessage(e),
builderDesc, null);
}
final DeserializationConfig config = ctxt.getConfig();
......
......@@ -265,7 +265,7 @@ public final class DeserializerCache
} catch (IllegalArgumentException iae) {
// We better only expose checked exceptions, since those
// are what caller is expected to handle
throw JsonMappingException.from(ctxt, iae.getMessage(), iae);
throw JsonMappingException.from(ctxt, ClassUtil.exceptionMessage(iae), iae);
}
if (deser == null) {
return null;
......
......@@ -199,7 +199,7 @@ public class SettableAnyProperty
StringBuilder msg = new StringBuilder("Problem deserializing \"any\" property '").append(propName);
msg.append("' of class "+getClassName()+" (expected type: ").append(_type);
msg.append("; actual type: ").append(actType).append(")");
String origMsg = e.getMessage();
String origMsg = ClassUtil.exceptionMessage(e);
if (origMsg != null) {
msg.append(", problem: ").append(origMsg);
} else {
......@@ -211,7 +211,7 @@ public class SettableAnyProperty
ClassUtil.throwIfRTE(e);
// let's wrap the innermost problem
Throwable t = ClassUtil.getRootCause(e);
throw new JsonMappingException(null, t.getMessage(), t);
throw new JsonMappingException(null, ClassUtil.exceptionMessage(t), t);
}
private String getClassName() { return _setter.getDeclaringClass().getName(); }
......