Skip to content

Commit 0631835

Browse files
committed
Fix #3582
1 parent 8513512 commit 0631835

File tree

4 files changed

+26
-7
lines changed

4 files changed

+26
-7
lines changed

release-notes/VERSION-2.x

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ Project: jackson-databind
1313
#3565: `Arrays.asList()` value deserialization has changed from mutable to
1414
immutable in 2.13
1515
(reported by JonasWilms@github)
16+
#3582: Add check in `BeanDeserializer._deserializeFromArray()` to prevent
17+
use of deeply nested arrays
1618

1719
2.13.3 (14-May-2022)
1820

src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,8 +317,10 @@ public enum DeserializationFeature implements ConfigFeature
317317
* values to the corresponding value type. This is basically the opposite of the {@link #ACCEPT_SINGLE_VALUE_AS_ARRAY}
318318
* feature. If more than one value is found in the array, a JsonMappingException is thrown.
319319
* <p>
320+
* NOTE: only <b>single</b> wrapper Array is allowed: if multiple attempted, exception
321+
* will be thrown.
320322
*
321-
* Feature is disabled by default
323+
* Feature is disabled by default.
322324
* @since 2.4
323325
*/
324326
UNWRAP_SINGLE_VALUE_ARRAYS(false),

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import com.fasterxml.jackson.databind.cfg.CoercionAction;
99
import com.fasterxml.jackson.databind.deser.impl.*;
1010
import com.fasterxml.jackson.databind.deser.impl.ReadableObjectId.Referring;
11+
import com.fasterxml.jackson.databind.util.ClassUtil;
1112
import com.fasterxml.jackson.databind.util.IgnorePropertiesUtil;
1213
import com.fasterxml.jackson.databind.util.NameTransformer;
1314
import com.fasterxml.jackson.databind.util.TokenBuffer;
@@ -628,6 +629,15 @@ protected Object _deserializeFromArray(JsonParser p, DeserializationContext ctxt
628629
return ctxt.handleUnexpectedToken(getValueType(ctxt), JsonToken.START_ARRAY, p, null);
629630
}
630631
if (unwrap) {
632+
// 23-Aug-2022, tatu: To prevent unbounded nested arrays, we better
633+
// check there is NOT another START_ARRAY lurking there..
634+
if (p.nextToken() == JsonToken.START_ARRAY) {
635+
JavaType targetType = getValueType(ctxt);
636+
return ctxt.handleUnexpectedToken(targetType, JsonToken.START_ARRAY, p,
637+
"Cannot deserialize value of type %s from deeply-nested JSON Array: only single wrapper allowed with `%s`",
638+
ClassUtil.getTypeDescription(targetType),
639+
"DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS");
640+
}
631641
final Object value = deserialize(p, ctxt);
632642
if (p.nextToken() != JsonToken.END_ARRAY) {
633643
handleMissingEndArrayForSingle(p, ctxt);

src/test/java/com/fasterxml/jackson/databind/deser/dos/DeepArrayWrappingForDeser3582Test.java

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
package com.fasterxml.jackson.databind.deser.dos;
22

33
import com.fasterxml.jackson.databind.*;
4+
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
45

56
public class DeepArrayWrappingForDeser3582Test extends BaseMapTest
67
{
7-
// 23-Aug-2022, tatu: Before fix, fails with 5000
8-
// (but passes with 2000)
9-
// private final static int TOO_DEEP_NESTING = 4999;
10-
private final static int TOO_DEEP_NESTING = 999;
8+
// 23-Aug-2022, tatu: Before fix, failed with 5000
9+
private final static int TOO_DEEP_NESTING = 9999;
1110

1211
private final ObjectMapper MAPPER = jsonMapperBuilder()
1312
.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)
@@ -16,8 +15,14 @@ public class DeepArrayWrappingForDeser3582Test extends BaseMapTest
1615
public void testArrayWrapping() throws Exception
1716
{
1817
final String doc = _nestedDoc(TOO_DEEP_NESTING, "[ ", "] ", "{}");
19-
Point p = MAPPER.readValue(doc, Point.class);
20-
assertNotNull(p);
18+
try {
19+
MAPPER.readValue(doc, Point.class);
20+
fail("Should not pass");
21+
} catch (MismatchedInputException e) {
22+
verifyException(e, "Cannot deserialize");
23+
verifyException(e, "nested JSON Array");
24+
verifyException(e, "only single");
25+
}
2126
}
2227

2328
private String _nestedDoc(int nesting, String open, String close, String content) {

0 commit comments

Comments
 (0)