Skip to content

Commit 9f43e29

Browse files
authored
Fix NPE when deserializing Throwable with ignored JDK fields (e.g. message) (#4326)
1 parent d624fc6 commit 9f43e29

File tree

2 files changed

+65
-2
lines changed

2 files changed

+65
-2
lines changed

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
147147
continue;
148148
}
149149
if (_anySetter != null) {
150+
// [databind#4316] Since 2.16.2 : at this point throwable should be non-null
151+
if (throwable == null) {
152+
throwable = _instantiate(ctxt, hasStringCreator, null);
153+
}
150154
_anySetter.deserializeAndSet(p, ctxt, throwable, propName);
151155
continue;
152156
}
@@ -194,7 +198,7 @@ public Object deserializeFromObject(JsonParser p, DeserializationContext ctxt) t
194198
/**
195199
* Helper method to initialize Throwable
196200
*
197-
* @since 2.17
201+
* @since 2.16.2
198202
*/
199203
private Throwable _instantiate(DeserializationContext ctxt, boolean hasStringCreator, String valueAsString)
200204
throws IOException

src/test/java/com/fasterxml/jackson/databind/exc/ExceptionWithAnySetter4316Test.java

Lines changed: 60 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,31 @@
44

55
import com.fasterxml.jackson.annotation.JsonAnyGetter;
66
import com.fasterxml.jackson.annotation.JsonAnySetter;
7+
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
8+
import com.fasterxml.jackson.annotation.JsonInclude;
9+
710
import com.fasterxml.jackson.databind.*;
811

12+
// [databind#4316] : NPE when deserializing JsonAnySetter in Throwable
913
public class ExceptionWithAnySetter4316Test extends BaseMapTest
1014
{
1115
static class Problem extends Exception {
1216
private static final long serialVersionUID = 1L;
17+
@JsonInclude(content=JsonInclude.Include.NON_NULL)
18+
@JsonAnySetter
19+
@JsonAnyGetter
20+
Map<String, Object> additionalProperties = new HashMap<>();
21+
}
1322

23+
@JsonIgnoreProperties({ "cause", "stackTrace", "response", "message", "localizedMessage", "suppressed" })
24+
static class ProblemWithIgnorals extends Exception {
1425
@JsonAnySetter
1526
@JsonAnyGetter
1627
Map<String, Object> additionalProperties = new HashMap<>();
1728
}
1829

1930
private final ObjectMapper MAPPER = newJsonMapper();
2031

21-
// [databind#4316]
2232
public void testWithAnySetter() throws Exception
2333
{
2434
Problem problem = new Problem();
@@ -28,4 +38,53 @@ public void testWithAnySetter() throws Exception
2838
assertEquals(Collections.singletonMap("key", "value"),
2939
result.additionalProperties);
3040
}
41+
42+
// Map with ignored props keys specified in @JsonIgnoreProperties
43+
public void testWithAnySetterAndIgnoralsPut() throws Exception
44+
{
45+
// Given
46+
ProblemWithIgnorals problem = new ProblemWithIgnorals();
47+
problem.additionalProperties.put("key", "value");
48+
// Below key-value pairs also ignored from here....
49+
problem.additionalProperties.put("cause", "ignored");
50+
problem.additionalProperties.put("stackTrace", "ignored");
51+
problem.additionalProperties.put("response", "ignored");
52+
problem.additionalProperties.put("message", "ignored");
53+
problem.additionalProperties.put("localizedMessage", "ignored");
54+
problem.additionalProperties.put("suppressed", "ignored");
55+
56+
// When
57+
String json = MAPPER.writeValueAsString(problem);
58+
ProblemWithIgnorals result = MAPPER.readValue(json, ProblemWithIgnorals.class);
59+
60+
// Then
61+
assertEquals(Collections.singletonMap("key", "value"),
62+
result.additionalProperties);
63+
}
64+
65+
// With ignorals
66+
public void testWithAnySetterAndIgnoralSimple() throws Exception
67+
{
68+
// Given
69+
ProblemWithIgnorals problem = new ProblemWithIgnorals();
70+
problem.additionalProperties.put("key", "value");
71+
72+
// When
73+
String json = MAPPER.writeValueAsString(problem);
74+
ProblemWithIgnorals result = MAPPER.readValue(json, ProblemWithIgnorals.class);
75+
76+
// Then
77+
assertEquals(Collections.singletonMap("key", "value"),
78+
result.additionalProperties);
79+
}
80+
81+
// With Include.NON_NULL
82+
public void testWithAnySetterButEmptyIncludedFalse() throws Exception
83+
{
84+
Problem problem = new Problem();
85+
problem.additionalProperties.put("exclude", null);
86+
String json = MAPPER.writeValueAsString(problem);
87+
Problem result = MAPPER.readValue(json, Problem.class);
88+
assertEquals(Collections.emptyMap(), result.additionalProperties);
89+
}
3190
}

0 commit comments

Comments
 (0)