Skip to content

Commit 37413a7

Browse files
committed
Fix regression wrt char/Character coercion from String
1 parent 2c49fc6 commit 37413a7

File tree

3 files changed

+31
-20
lines changed

3 files changed

+31
-20
lines changed

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

+23-13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import com.fasterxml.jackson.databind.*;
1111
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
1212
import com.fasterxml.jackson.databind.cfg.CoercionAction;
13+
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
1314
import com.fasterxml.jackson.databind.jsontype.TypeDeserializer;
1415
import com.fasterxml.jackson.databind.type.LogicalType;
1516
import com.fasterxml.jackson.databind.util.AccessPattern;
@@ -423,24 +424,37 @@ public CharacterDeserializer(Class<Character> cls, Character nvl)
423424
public Character deserialize(JsonParser p, DeserializationContext ctxt)
424425
throws IOException
425426
{
427+
CoercionAction act;
428+
426429
switch (p.currentTokenId()) {
427430
case JsonTokenId.ID_NUMBER_INT: // ok iff Unicode value
428-
// 12-Jun-2020, tatu: inlined from `StdDeserializer`
429-
if (!ctxt.isEnabled(MapperFeature.ALLOW_COERCION_OF_SCALARS)) {
430-
ctxt.reportInputMismatch(this,
431-
"Cannot coerce Integer value to `Character` (enable `MapperFeature.ALLOW_COERCION_OF_SCALARS` to allow)");
431+
act = ctxt.findCoercionAction(logicalType(), _valueClass, CoercionInputShape.Integer);
432+
switch (act) {
433+
case Fail:
434+
_checkCoercionActionFail(ctxt, act, "Integer value ("+p.getText()+")");
435+
break;
436+
case AsNull:
437+
return getNullValue(ctxt);
438+
case AsEmpty:
439+
return (Character) getEmptyValue(ctxt);
440+
default:
432441
}
433442
int value = p.getIntValue();
434443
if (value >= 0 && value <= 0xFFFF) {
435444
return Character.valueOf((char) value);
436445
}
437446
break;
438-
case JsonTokenId.ID_STRING: // this is the usual type
439-
447+
case JsonTokenId.ID_STRING:
448+
// 23-Jun-2020, tatu: Unlike real numeric types, Character/char does not
449+
// have canonical shape in JSON, and String in particular does not need
450+
// coercion -- as long as it has length of 1.
440451
String text = p.getText();
441-
CoercionAction act = _checkFromStringCoercion(ctxt, text);
452+
if (text.length() == 1) {
453+
return Character.valueOf(text.charAt(0));
454+
}
455+
act = _checkFromStringCoercion(ctxt, text);
442456
if (act == CoercionAction.AsNull) {
443-
return (Character) getNullValue(ctxt);
457+
return getNullValue(ctxt);
444458
}
445459
if (act == CoercionAction.AsEmpty) {
446460
return (Character) getEmptyValue(ctxt);
@@ -449,10 +463,6 @@ public Character deserialize(JsonParser p, DeserializationContext ctxt)
449463
if (_checkTextualNull(ctxt, text)) {
450464
return (Character) getNullValue(ctxt);
451465
}
452-
// But does it have to be exactly one char?
453-
if (text.length() == 1) {
454-
return Character.valueOf(text.charAt(0));
455-
}
456466
break;
457467
case JsonTokenId.ID_NULL:
458468
if (_primitive) {
@@ -463,7 +473,7 @@ public Character deserialize(JsonParser p, DeserializationContext ctxt)
463473
return _deserializeFromArray(p, ctxt);
464474
default:
465475
}
466-
return (Character) ctxt.handleUnexpectedToken(_valueClass, p);
476+
return (Character) ctxt.handleUnexpectedToken(getValueType(ctxt), p);
467477
}
468478
}
469479

src/test/java/com/fasterxml/jackson/databind/convert/CoerceJDKScalarsTest.java

+2-4
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,9 @@ public void testMiscCoercionFail() throws Exception
208208
// And then we have coercions from more esoteric types too
209209

210210
_verifyCoerceFail("65", Character.class,
211-
"Cannot coerce Integer value to `Character",
212-
"enable `MapperFeature.ALLOW_COERCION_OF_SCALARS` to allow");
211+
"Cannot coerce Integer value (65) to `java.lang.Character` value");
213212
_verifyCoerceFail("65", Character.TYPE,
214-
"Cannot coerce Integer value to `Character",
215-
"enable `MapperFeature.ALLOW_COERCION_OF_SCALARS` to allow");
213+
"Cannot coerce Integer value (65) to `char` value");
216214
}
217215

218216
/*

src/test/java/com/fasterxml/jackson/databind/deser/jdk/JDKScalarsTest.java

+6-3
Original file line numberDiff line numberDiff line change
@@ -230,12 +230,15 @@ public void testShortWrapper() throws Exception
230230
public void testCharacterWrapper() throws Exception
231231
{
232232
// First: canonical value is 1-char string
233-
Character result = MAPPER.readValue("\"a\"", Character.class);
234-
assertEquals(Character.valueOf('a'), result);
233+
assertEquals(Character.valueOf('a'), MAPPER.readValue(quote("a"), Character.class));
235234

236235
// But can also pass in ascii code
237-
result = MAPPER.readValue(" "+((int) 'X'), Character.class);
236+
Character result = MAPPER.readValue(" "+((int) 'X'), Character.class);
238237
assertEquals(Character.valueOf('X'), result);
238+
239+
// 22-Jun-2020, tatu: one special case turns out to be white space;
240+
// need to avoid considering it "blank" value
241+
assertEquals(Character.valueOf(' '), MAPPER.readValue(quote(" "), Character.class));
239242

240243
final CharacterWrapperBean wrapper = MAPPER.readValue("{\"v\":null}", CharacterWrapperBean.class);
241244
assertNotNull(wrapper);

0 commit comments

Comments
 (0)