Skip to content

Commit b049739

Browse files
committed
Fix #941
1 parent e258ee6 commit b049739

File tree

5 files changed

+46
-11
lines changed

5 files changed

+46
-11
lines changed

release-notes/CREDITS

+5
Original file line numberDiff line numberDiff line change
@@ -317,3 +317,8 @@ Daniel Walker (dsw2127@github)
317317
* Reported, contributed fix for #913: `ObjectMapper.copy()` does not preserve
318318
`MappingJsonFactory` features
319319
(2.6.2)
320+
321+
Sadayuki Furuhashi (frsyuki@github)
322+
* Reported #941: Deserialization from "{}" to ObjectNode field causes
323+
"out of END_OBJECT token" error
324+
(2.6.3)

release-notes/VERSION

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ Project: jackson-databind
88

99
#938: Regression: `StackOverflowError` with recursive types that contain `Map.Entry`
1010
(reported by jloisel@github)
11+
#941: Deserialization from "{}" to ObjectNode field causes "out of END_OBJECT token" error
12+
(reported by Sadayuki F)
1113

1214
2.6.2 (14-Sep-2015)
1315

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

+2
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,8 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
124124
if (_vanillaProcessing) {
125125
return vanillaDeserialize(p, ctxt, p.nextToken());
126126
}
127+
// 23-Sep-2015, tatu: This is wrong at some many levels, but for now... it is
128+
// what it is, including "expected behavior".
127129
p.nextToken();
128130
if (_objectIdReader != null) {
129131
return deserializeWithObjectId(p, ctxt);

src/main/java/com/fasterxml/jackson/databind/deser/std/JsonNodeDeserializer.java

+10-10
Original file line numberDiff line numberDiff line change
@@ -92,14 +92,15 @@ final static class ObjectDeserializer
9292
public static ObjectDeserializer getInstance() { return _instance; }
9393

9494
@Override
95-
public ObjectNode deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException
95+
public ObjectNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
9696
{
97-
if (jp.getCurrentToken() == JsonToken.START_OBJECT) {
98-
jp.nextToken();
99-
return deserializeObject(jp, ctxt, ctxt.getNodeFactory());
97+
if (p.isExpectedStartObjectToken() || p.hasToken(JsonToken.FIELD_NAME)) {
98+
return deserializeObject(p, ctxt, ctxt.getNodeFactory());
10099
}
101-
if (jp.getCurrentToken() == JsonToken.FIELD_NAME) {
102-
return deserializeObject(jp, ctxt, ctxt.getNodeFactory());
100+
// 23-Sep-2015, tatu: Ugh. We may also be given END_OBJECT (similar to FIELD_NAME),
101+
// if caller has advanced to the first token of Object, but for empty Object
102+
if (p.hasToken(JsonToken.END_OBJECT)) {
103+
return ctxt.getNodeFactory().objectNode();
103104
}
104105
throw ctxt.mappingException(ObjectNode.class);
105106
}
@@ -117,11 +118,10 @@ final static class ArrayDeserializer
117118
public static ArrayDeserializer getInstance() { return _instance; }
118119

119120
@Override
120-
public ArrayNode deserialize(JsonParser jp, DeserializationContext ctxt)
121-
throws IOException, JsonProcessingException
121+
public ArrayNode deserialize(JsonParser p, DeserializationContext ctxt) throws IOException
122122
{
123-
if (jp.isExpectedStartArrayToken()) {
124-
return deserializeArray(jp, ctxt, ctxt.getNodeFactory());
123+
if (p.isExpectedStartArrayToken()) {
124+
return deserializeArray(p, ctxt, ctxt.getNodeFactory());
125125
}
126126
throw ctxt.mappingException(ArrayNode.class);
127127
}

src/test/java/com/fasterxml/jackson/databind/node/TestObjectNode.java

+27-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,19 @@ public ObNodeWrapper(ObjectNode n) {
4747
node = n;
4848
}
4949
}
50-
50+
51+
// [databind#941]
52+
static class MyValue
53+
{
54+
private final ObjectNode object;
55+
56+
@JsonCreator
57+
public MyValue(ObjectNode object) { this.object = object; }
58+
59+
@JsonValue
60+
public ObjectNode getObject() { return object; }
61+
}
62+
5163
/*
5264
/**********************************************************
5365
/* Test methods
@@ -385,4 +397,18 @@ public void testNonEmptySerialization() throws Exception
385397
w = new ObNodeWrapper(MAPPER.createObjectNode());
386398
assertEquals("{}", MAPPER.writeValueAsString(w));
387399
}
400+
401+
public void testIssue941() throws Exception
402+
{
403+
ObjectNode object = MAPPER.createObjectNode();
404+
405+
String json = MAPPER.writeValueAsString(object);
406+
System.out.println("json: "+json);
407+
408+
ObjectNode de1 = MAPPER.readValue(json, ObjectNode.class); // this works
409+
System.out.println("Deserialized to ObjectNode: "+de1);
410+
411+
MyValue de2 = MAPPER.readValue(json, MyValue.class); // but this throws exception
412+
System.out.println("Deserialized to MyValue: "+de2);
413+
}
388414
}

0 commit comments

Comments
 (0)