Skip to content

Commit 277151d

Browse files
committed
Fix #1978
1 parent ba35c17 commit 277151d

File tree

4 files changed

+105
-4
lines changed

4 files changed

+105
-4
lines changed

release-notes/CREDITS-2.x

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,3 +762,8 @@ Aniruddha Maru (maroux@github)
762762
Timur Shakurov (saladinkzn@github)
763763
* Reported #1947: `MapperFeature.AUTO_DETECT_XXX` do not work if all disabled
764764
(2.9.5)
765+
766+
roeltje25@github
767+
* Reported #1978: Using @JsonUnwrapped annotation in builderdeserializer hangs in
768+
infinite loop
769+
(2.9.5)

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ Project: jackson-databind
2525
(reported by Timur S)
2626
#1977: Serializing an Iterator with multiple sub-types fails after upgrading to 2.9.x
2727
(reported by ssivanand@github)
28+
#1978: Using @JsonUnwrapped annotation in builderdeserializer hangs in infinite loop
29+
(reported by roeltje25@github)
2830

2931
2.9.4 (24-Jan-2018)
3032

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ private final Object vanillaDeserialize(JsonParser p,
259259
throws IOException
260260
{
261261
Object bean = _valueInstantiator.createUsingDefault(ctxt);
262-
for (; p.getCurrentToken() != JsonToken.END_OBJECT; p.nextToken()) {
262+
for (; p.getCurrentToken() == JsonToken.FIELD_NAME; p.nextToken()) {
263263
String propName = p.getCurrentName();
264264
// Skip field name:
265265
p.nextToken();
@@ -304,7 +304,7 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt)
304304
return deserializeWithView(p, ctxt, bean, view);
305305
}
306306
}
307-
for (; p.getCurrentToken() != JsonToken.END_OBJECT; p.nextToken()) {
307+
for (; p.getCurrentToken() == JsonToken.FIELD_NAME; p.nextToken()) {
308308
String propName = p.getCurrentName();
309309
// Skip field name:
310310
p.nextToken();
@@ -535,8 +535,7 @@ protected Object deserializeWithUnwrapped(JsonParser p, DeserializationContext c
535535
}
536536

537537
final Class<?> activeView = _needViewProcesing ? ctxt.getActiveView() : null;
538-
539-
for (; p.getCurrentToken() != JsonToken.END_OBJECT; p.nextToken()) {
538+
for (; p.getCurrentToken() == JsonToken.FIELD_NAME; p.nextToken()) {
540539
String propName = p.getCurrentName();
541540
p.nextToken();
542541
SettableBeanProperty prop = _beanProperties.find(propName);
Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
package com.fasterxml.jackson.databind.deser.builder;
2+
3+
import com.fasterxml.jackson.annotation.JsonProperty;
4+
import com.fasterxml.jackson.annotation.JsonUnwrapped;
5+
6+
import com.fasterxml.jackson.databind.*;
7+
8+
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
9+
10+
public class BuilderInfiniteLoop1978Test extends BaseMapTest
11+
{
12+
static class Builder
13+
{
14+
private SubBean temp;
15+
private int id;
16+
17+
Builder(@JsonProperty("beanId") int beanId) {
18+
this.id = beanId;
19+
}
20+
21+
@JsonUnwrapped(prefix="sub.")
22+
public Builder withThing(SubBean thing) {
23+
this.temp = thing;
24+
return this;
25+
}
26+
27+
public Bean build()
28+
{
29+
Bean bean = new Bean(id);
30+
bean.setThing( temp );
31+
return bean;
32+
}
33+
}
34+
35+
@JsonDeserialize(builder = Builder.class)
36+
static class Bean
37+
{
38+
int id;
39+
SubBean thing;
40+
41+
public Bean(int id) {
42+
this.id = id;
43+
}
44+
45+
public SubBean getThing() {
46+
return thing;
47+
}
48+
49+
public void setThing( SubBean thing ) {
50+
this.thing = thing;
51+
}
52+
}
53+
54+
static class SubBuilder
55+
{
56+
private int element1;
57+
private String element2;
58+
59+
@JsonProperty("el1")
60+
public SubBuilder withElement1(int e1) {
61+
this.element1 = e1;
62+
return this;
63+
}
64+
65+
public SubBean build()
66+
{
67+
SubBean bean = new SubBean();
68+
bean.element1 = element1;
69+
bean.element2 = element2;
70+
return bean;
71+
}
72+
}
73+
74+
@JsonDeserialize(builder = SubBuilder.class)
75+
static class SubBean
76+
{
77+
public int element1;
78+
public String element2;
79+
}
80+
81+
/*
82+
/**********************************************************************
83+
/* Test methods
84+
/**********************************************************************
85+
*/
86+
87+
// for [databind#1978]
88+
public void testInfiniteLoop1978() throws Exception
89+
{
90+
String json = "{\"sub.el1\":34,\"sub.el2\":\"some text\"}";
91+
ObjectMapper mapper = new ObjectMapper();
92+
Bean bean = mapper.readValue( json, Bean.class );
93+
assertNotNull(bean);
94+
}
95+
}

0 commit comments

Comments
 (0)