Skip to content

Commit eba7b84

Browse files
committed
Fix #3056
1 parent 1eb2c07 commit eba7b84

File tree

3 files changed

+80
-14
lines changed

3 files changed

+80
-14
lines changed

release-notes/VERSION-2.x

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ Project: jackson-databind
1414
(fix contributed by Migwel@github)
1515
#3038: Two cases of incorrect error reporting about DeserializationFeature
1616
(reported by Jelle V)
17+
#3056: MismatchedInputException: Cannot deserialize instance of
18+
`com.fasterxml.jackson.databind.node.ObjectNode` out of VALUE_NULL token
19+
(reported by Stexxen@github)
1720

1821
2.12.1 (08-Jan-2021)
1922

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

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -389,18 +389,25 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
389389
JsonNode old = node.get(key);
390390
if (old != null) {
391391
if (old instanceof ObjectNode) {
392-
JsonNode newValue = updateObject(p, ctxt, (ObjectNode) old);
393-
if (newValue != old) {
394-
node.set(key, newValue);
392+
// [databind#3056]: merging only if had Object and
393+
// getting an Object
394+
if (t == JsonToken.START_OBJECT) {
395+
JsonNode newValue = updateObject(p, ctxt, (ObjectNode) old);
396+
if (newValue != old) {
397+
node.set(key, newValue);
398+
}
399+
continue;
395400
}
396-
continue;
397-
}
398-
if (old instanceof ArrayNode) {
399-
JsonNode newValue = updateArray(p, ctxt, (ArrayNode) old);
400-
if (newValue != old) {
401-
node.set(key, newValue);
401+
} else if (old instanceof ArrayNode) {
402+
// [databind#3056]: related to Object handling, ensure
403+
// Array values also match for mergeability
404+
if (t == JsonToken.START_ARRAY) {
405+
JsonNode newValue = updateArray(p, ctxt, (ArrayNode) old);
406+
if (newValue != old) {
407+
node.set(key, newValue);
408+
}
409+
continue;
402410
}
403-
continue;
404411
}
405412
}
406413
if (t == null) { // can this ever occur?
@@ -436,10 +443,15 @@ protected final JsonNode updateObject(JsonParser p, DeserializationContext ctxt,
436443
default:
437444
value = deserializeAny(p, ctxt, nodeFactory);
438445
}
446+
// 15-Feb-2021, tatu: I don't think this should have been called
447+
// on update case (was until 2.12.2) and was simply result of
448+
// copy-paste.
449+
/*
439450
if (old != null) {
440451
_handleDuplicateField(p, ctxt, nodeFactory,
441452
key, node, old, value);
442453
}
454+
*/
443455
node.set(key, value);
444456
}
445457
return node;
@@ -449,8 +461,9 @@ protected final ArrayNode deserializeArray(JsonParser p, DeserializationContext
449461
final JsonNodeFactory nodeFactory) throws IOException
450462
{
451463
ArrayNode node = nodeFactory.arrayNode();
452-
while (true) {
453-
JsonToken t = p.nextToken();
464+
JsonToken t;
465+
466+
while ((t = p.nextToken()) != null) {
454467
switch (t.id()) {
455468
case JsonTokenId.ID_START_OBJECT:
456469
node.add(deserializeObject(p, ctxt, nodeFactory));
@@ -483,6 +496,8 @@ protected final ArrayNode deserializeArray(JsonParser p, DeserializationContext
483496
break;
484497
}
485498
}
499+
// should never really get here
500+
return node;
486501
}
487502

488503
/**

src/test/java/com/fasterxml/jackson/databind/deser/merge/NodeMergeTest.java

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ public class NodeMergeTest extends BaseMapTest
1111
final static ObjectMapper MAPPER = jsonMapperBuilder()
1212
// 26-Oct-2016, tatu: Make sure we'll report merge problems by default
1313
.disable(MapperFeature.IGNORE_MERGE_FOR_UNMERGEABLE)
14+
// 15-Feb-2021, tatu: slightly related to [databind#3056],
15+
// ensure that dup detection will not trip handling here
16+
.enable(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY)
1417
.build();
1518

1619
static class ObjectNodeWrapper {
@@ -69,8 +72,8 @@ public void testObjectDeepUpdate() throws Exception
6972
base.putNull("misc");
7073
assertSame(base,
7174
MAPPER.readerForUpdating(base)
72-
.readValue(aposToQuotes(
73-
"{'props':{'value':true, 'extra':25.5, 'array' : [ 3 ]}}")));
75+
.readValue(a2q(
76+
"{'props':{'value':true, 'extra':25.5, 'array' : [ 3 ]}}")));
7477
assertEquals(2, base.size());
7578
ObjectNode resultProps = (ObjectNode) base.get("props");
7679
assertEquals(4, resultProps.size());
@@ -114,4 +117,49 @@ public void testArrayNodeMerge() throws Exception
114117
assertEquals(0, n.size());
115118
assertEquals("foo", w.list.get(5).asText());
116119
}
120+
121+
// [databind#3056]
122+
public void testUpdateObjectNodeWithNull() throws Exception
123+
{
124+
JsonNode src = MAPPER.readTree(a2q("{'test':{}}"));
125+
JsonNode update = MAPPER.readTree(a2q("{'test':null}"));
126+
127+
ObjectNode result = MAPPER.readerForUpdating(src)
128+
.readValue(update, ObjectNode.class);
129+
130+
assertEquals(a2q("{'test':null}"), result.toString());
131+
}
132+
133+
public void testUpdateObjectNodeWithNumber() throws Exception
134+
{
135+
JsonNode src = MAPPER.readTree(a2q("{'test':{}}"));
136+
JsonNode update = MAPPER.readTree(a2q("{'test':123}"));
137+
138+
ObjectNode result = MAPPER.readerForUpdating(src)
139+
.readValue(update, ObjectNode.class);
140+
141+
assertEquals(a2q("{'test':123}"), result.toString());
142+
}
143+
144+
public void testUpdateArrayWithNull() throws Exception
145+
{
146+
JsonNode src = MAPPER.readTree(a2q("{'test':[]}"));
147+
JsonNode update = MAPPER.readTree(a2q("{'test':null}"));
148+
149+
ObjectNode result = MAPPER.readerForUpdating(src)
150+
.readValue(update, ObjectNode.class);
151+
152+
assertEquals(a2q("{'test':null}"), result.toString());
153+
}
154+
155+
public void testUpdateArrayWithString() throws Exception
156+
{
157+
JsonNode src = MAPPER.readTree(a2q("{'test':[]}"));
158+
JsonNode update = MAPPER.readTree(a2q("{'test':'n/a'}"));
159+
160+
ObjectNode result = MAPPER.readerForUpdating(src)
161+
.readValue(update, ObjectNode.class);
162+
163+
assertEquals(a2q("{'test':'n/a'}"), result.toString());
164+
}
117165
}

0 commit comments

Comments
 (0)