Skip to content

Commit 555cbeb

Browse files
committed
* Fix #2088
* Minor improvement to error handling wrt exception propagating via Creator (esp. for NPEs and other no-message exception types)
1 parent dd7258a commit 555cbeb

File tree

4 files changed

+58
-4
lines changed

4 files changed

+58
-4
lines changed

release-notes/VERSION-2.x

+3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ Project: jackson-databind
2222
#2079: NPE when visiting StaticListSerializerBase
2323
(reported by WorldSEnder@github)
2424
#2082: `FactoryBasedEnumDeserializer` should be cachable
25+
#2088: `@JsonUnwrapped` fields are skipped when using `PropertyBasedCreator` if
26+
they appear after the last creator property
27+
(reported, fix contributed by 6bangs@github)
2528
#2096: `TreeTraversingParser` does not take base64 variant into account
2629
(reported by tangiel@github)
2730
#2097: Block more classes from polymorphic deserialization (CVE-2018-14718

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

+9-3
Original file line numberDiff line numberDiff line change
@@ -1589,15 +1589,21 @@ public JsonMappingException weirdNativeValueException(Object value, Class<?> ins
15891589
* to indicate problem with physically constructing instance of
15901590
* specified class (missing constructor, exception from constructor)
15911591
*<p>
1592-
* Note that most of the time this method should NOT be called; instead,
1592+
* Note that most of the time this method should NOT be called directly; instead,
15931593
* {@link #handleInstantiationProblem} should be called which will call this method
15941594
* if necessary.
15951595
*/
15961596
public JsonMappingException instantiationException(Class<?> instClass, Throwable cause) {
15971597
// Most likely problem with Creator definition, right?
1598-
JavaType type = constructType(instClass);
1598+
final JavaType type = constructType(instClass);
1599+
String excMsg;
1600+
if (cause == null) {
1601+
excMsg = "N/A";
1602+
} else if ((excMsg = cause.getMessage()) == null) {
1603+
excMsg = ClassUtil.nameOf(cause.getClass());
1604+
}
15991605
String msg = String.format("Cannot construct instance of %s, problem: %s",
1600-
ClassUtil.nameOf(instClass), cause.getMessage());
1606+
ClassUtil.nameOf(instClass), excMsg);
16011607
InvalidDefinitionException e = InvalidDefinitionException.from(_parser, msg, type);
16021608
e.initCause(cause);
16031609
return e;

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

+8-1
Original file line numberDiff line numberDiff line change
@@ -767,10 +767,17 @@ protected Object deserializeUsingPropertyBasedWithUnwrapped(JsonParser p, Deseri
767767
p.setCurrentValue(bean);
768768
// if so, need to copy all remaining tokens into buffer
769769
while (t == JsonToken.FIELD_NAME) {
770-
p.nextToken(); // to skip name
770+
// NOTE: do NOT skip name as it needs to be copied; `copyCurrentStructure` does that
771771
tokens.copyCurrentStructure(p);
772772
t = p.nextToken();
773773
}
774+
// 28-Aug-2018, tatu: Let's add sanity check here, easier to catch off-by-some
775+
// problems if we maintain invariants
776+
if (t != JsonToken.END_OBJECT) {
777+
ctxt.reportWrongTokenException(this, JsonToken.END_OBJECT,
778+
"Attempted to unwrap '%s' value",
779+
handledType().getName());
780+
}
774781
tokens.writeEndObject();
775782
if (bean.getClass() != _beanType.getRawClass()) {
776783
// !!! 08-Jul-2011, tatu: Could probably support; but for now

src/test/java/com/fasterxml/jackson/databind/struct/TestUnwrapped.java

+38
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,34 @@ static class Address {
111111
public String country;
112112
}
113113

114+
// [databind#2088]
115+
static class Issue2088Bean {
116+
int x;
117+
int y;
118+
119+
@JsonUnwrapped
120+
Issue2088UnwrappedBean w;
121+
122+
public Issue2088Bean(@JsonProperty("x") int x, @JsonProperty("y") int y) {
123+
this.x = x;
124+
this.y = y;
125+
}
126+
127+
public void setW(Issue2088UnwrappedBean w) {
128+
this.w = w;
129+
}
130+
}
131+
132+
static class Issue2088UnwrappedBean {
133+
int a;
134+
int b;
135+
136+
public Issue2088UnwrappedBean(@JsonProperty("a") int a, @JsonProperty("b") int b) {
137+
this.a = a;
138+
this.b = b;
139+
}
140+
}
141+
114142
/*
115143
/**********************************************************
116144
/* Tests, serialization
@@ -216,4 +244,14 @@ public void testCaseInsensitiveUnwrap() throws Exception
216244
Person p = mapper.readValue("{ }", Person.class);
217245
assertNotNull(p);
218246
}
247+
248+
// [databind#2088]: accidental skipping of values
249+
public void testIssue2088UnwrappedFieldsAfterLastCreatorProp() throws Exception
250+
{
251+
Issue2088Bean bean = MAPPER.readValue("{\"x\":1,\"a\":2,\"y\":3,\"b\":4}", Issue2088Bean.class);
252+
assertEquals(1, bean.x);
253+
assertEquals(2, bean.w.a);
254+
assertEquals(3, bean.y);
255+
assertEquals(4, bean.w.b);
256+
}
219257
}

0 commit comments

Comments
 (0)