Skip to content

Commit 7c0a74e

Browse files
authored
Fix string-based creators with UNWRAP_SINGLE_VALUE_ARRAYS (#3666)
1 parent 960b91c commit 7c0a74e

File tree

4 files changed

+49
-3
lines changed

4 files changed

+49
-3
lines changed

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

+3-3
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,8 @@ protected Object _deserializeFromArray(JsonParser p, DeserializationContext ctxt
616616
final boolean unwrap = ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS);
617617

618618
if (unwrap || (act != CoercionAction.Fail)) {
619-
JsonToken t = p.nextToken();
620-
if (t == JsonToken.END_ARRAY) {
619+
JsonToken unwrappedToken = p.nextToken();
620+
if (unwrappedToken == JsonToken.END_ARRAY) {
621621
switch (act) {
622622
case AsEmpty:
623623
return getEmptyValue(ctxt);
@@ -631,7 +631,7 @@ protected Object _deserializeFromArray(JsonParser p, DeserializationContext ctxt
631631
if (unwrap) {
632632
// 23-Aug-2022, tatu: To prevent unbounded nested arrays, we better
633633
// check there is NOT another START_ARRAY lurking there..
634-
if (p.nextToken() == JsonToken.START_ARRAY) {
634+
if (unwrappedToken == JsonToken.START_ARRAY) {
635635
JavaType targetType = getValueType(ctxt);
636636
return ctxt.handleUnexpectedToken(targetType, JsonToken.START_ARRAY, p,
637637
"Cannot deserialize value of type %s from deeply-nested Array: only single wrapper allowed with `%s`",

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

+10
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,23 @@ public Object deserialize(JsonParser p, DeserializationContext ctxt) throws IOEx
151151
// 14-Jan-2022, tatu: as per [databind#3369] need to consider structured
152152
// value types (Object, Array) as well.
153153
JsonToken t = p.currentToken();
154+
boolean unwrapping = false;
155+
if (t == JsonToken.START_ARRAY && ctxt.isEnabled(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)) {
156+
t = p.nextToken();
157+
unwrapping = true;
158+
}
154159
if ((t != null) && !t.isScalarValue()) {
155160
// Could argue we should throw an exception but...
156161
value = "";
157162
p.skipChildren();
158163
} else {
159164
value = p.getValueAsString();
160165
}
166+
if (unwrapping) {
167+
if (p.nextToken() != JsonToken.END_ARRAY) {
168+
handleMissingEndArrayForSingle(p, ctxt);
169+
}
170+
}
161171
} else { // zero-args; just skip whatever value there may be
162172
p.skipChildren();
163173
try {

src/test/java/com/fasterxml/jackson/databind/deser/creators/EnumCreatorTest.java

+29
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,15 @@ private TestEnumFromInt(int id) {
6262
}
6363
}
6464

65+
protected enum TestEnumFromString
66+
{
67+
ENUM_A, ENUM_B, ENUM_C;
68+
69+
@JsonCreator public static TestEnumFromString fromId(String id) {
70+
return valueOf(id);
71+
}
72+
}
73+
6574
static enum EnumWithPropertiesModeJsonCreator {
6675
TEST1,
6776
TEST2,
@@ -344,4 +353,24 @@ public void testPropertyCreatorEnum3280() throws Exception
344353
assertEquals(Enum3280.x, r.readValue("{\"a\":[], \"b\":\"x\"}"));
345354
assertEquals(Enum3280.x, r.readValue("{\"a\":{}, \"b\":\"x\"}"));
346355
}
356+
357+
// for [databind#3655]
358+
public void testEnumsFromIntsUnwrapped() throws Exception
359+
{
360+
Object ob = newJsonMapper()
361+
.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)
362+
.readValue("[1]", TestEnumFromInt.class);
363+
assertEquals(TestEnumFromInt.class, ob.getClass());
364+
assertSame(TestEnumFromInt.ENUM_A, ob);
365+
}
366+
367+
// for [databind#3655]
368+
public void testEnumsFromStringUnwrapped() throws Exception
369+
{
370+
Object ob = newJsonMapper()
371+
.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)
372+
.readValue("[\"ENUM_A\"]", TestEnumFromString.class);
373+
assertEquals(TestEnumFromString.class, ob.getClass());
374+
assertSame(TestEnumFromString.ENUM_A, ob);
375+
}
347376
}

src/test/java/com/fasterxml/jackson/databind/deser/creators/TestCreators3.java

+7
Original file line numberDiff line numberDiff line change
@@ -205,5 +205,12 @@ public void testDeserializationFromString() throws Exception {
205205
assertEquals("DELEG:testProduct",
206206
MAPPER.readValue(q("testProduct"), Product1853.class).getName());
207207
}
208+
209+
public void testDeserializationFromWrappedString() throws Exception {
210+
assertEquals("DELEG:testProduct",
211+
newJsonMapper()
212+
.enable(DeserializationFeature.UNWRAP_SINGLE_VALUE_ARRAYS)
213+
.readValue("[\"testProduct\"]", Product1853.class).getName());
214+
}
208215
}
209216

0 commit comments

Comments
 (0)