Skip to content

Commit c13fd35

Browse files
authored
check added to prevent IonValue null deserialization to fail when bean has a missing property (#322)
1 parent 8347d96 commit c13fd35

File tree

2 files changed

+46
-5
lines changed

2 files changed

+46
-5
lines changed

ion/src/main/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializer.java

+9-5
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import java.io.IOException;
1818

1919
import com.fasterxml.jackson.core.JsonParser;
20+
import com.fasterxml.jackson.core.JsonToken;
2021
import com.fasterxml.jackson.databind.DeserializationContext;
2122
import com.fasterxml.jackson.databind.JsonMappingException;
2223
import com.fasterxml.jackson.databind.JsonDeserializer;
@@ -58,11 +59,14 @@ public IonValue deserialize(JsonParser jp, DeserializationContext ctxt) throws I
5859
@Override
5960
public IonValue getNullValue(DeserializationContext ctxt) throws JsonMappingException {
6061
try {
61-
Object embeddedObj = ctxt.getParser().getEmbeddedObject();
62-
if (embeddedObj instanceof IonValue) {
63-
IonValue iv = (IonValue) embeddedObj;
64-
if (iv.isNullValue()) {
65-
return iv;
62+
final JsonParser parser = ctxt.getParser();
63+
if (parser != null && parser.getCurrentToken() != JsonToken.END_OBJECT) {
64+
final Object embeddedObj = parser.getEmbeddedObject();
65+
if (embeddedObj instanceof IonValue) {
66+
IonValue iv = (IonValue) embeddedObj;
67+
if (iv.isNullValue()) {
68+
return iv;
69+
}
6670
}
6771
}
6872

ion/src/test/java/com/fasterxml/jackson/dataformat/ion/ionvalue/IonValueDeserializerTest.java

+37
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,16 @@
22

33
import com.amazon.ion.IonSystem;
44
import com.amazon.ion.IonValue;
5+
import com.amazon.ion.IonStruct;
56
import com.amazon.ion.system.IonSystemBuilder;
67
import com.fasterxml.jackson.annotation.JsonAnyGetter;
78
import com.fasterxml.jackson.annotation.JsonAnySetter;
9+
import com.fasterxml.jackson.annotation.JsonProperty;
810
import com.fasterxml.jackson.databind.util.AccessPattern;
11+
import com.fasterxml.jackson.dataformat.ion.IonObjectMapper;
912
import org.junit.Test;
1013

14+
import java.io.IOException;
1115
import java.util.HashMap;
1216
import java.util.Map;
1317
import java.util.Objects;
@@ -166,6 +170,39 @@ public void shouldBeAbleToSerializeAndDeserializeStringData() throws Exception {
166170
assertEquals(source, result);
167171
}
168172

173+
static class MyBean {
174+
public IonStruct required;
175+
public IonStruct optional;
176+
177+
MyBean(
178+
@JsonProperty("required") IonStruct required,
179+
@JsonProperty("optional") IonStruct optional
180+
) {
181+
this.required = required;
182+
this.optional = optional;
183+
}
184+
}
185+
186+
@Test
187+
public void testWithMissingProperty() throws IOException
188+
{
189+
IonSystem ionSystem = IonSystemBuilder.standard().build();
190+
IonObjectMapper ionObjectMapper = IonObjectMapper.builder(ionSystem)
191+
.addModule(new IonValueModule())
192+
.build();
193+
194+
String input1 = "{required:{}, optional:{}}";
195+
MyBean deserializedBean1 = ionObjectMapper.readValue(input1, MyBean.class);
196+
assertEquals(ionSystem.newEmptyStruct(), deserializedBean1.required);
197+
assertEquals(ionSystem.newEmptyStruct(), deserializedBean1.optional);
198+
199+
// This deserialization should not fail with missing property
200+
String input2 = "{required:{}}";
201+
MyBean deserializedBean2 = ionObjectMapper.readValue(input2, MyBean.class);
202+
assertEquals(ionSystem.newEmptyStruct(), deserializedBean2.required);
203+
assertEquals(null, deserializedBean2.optional);
204+
}
205+
169206
@Test
170207
public void shouldOverrideNullAccessPatternToBeDynamic() {
171208
IonValueDeserializer deserializer = new IonValueDeserializer();

0 commit comments

Comments
 (0)