diff --git a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java index f0e4c8f68e..e79822cc83 100644 --- a/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java +++ b/src/main/java/com/fasterxml/jackson/databind/DeserializationFeature.java @@ -459,7 +459,24 @@ public enum DeserializationFeature implements ConfigFeature * * @since 2.1 */ - EAGER_DESERIALIZER_FETCH(true) + EAGER_DESERIALIZER_FETCH(true), + + /** + * Feature that determines whether JSON string mapping are valid + * values to be used to map to ordinal() of matching enumeration value + * for deserializing Java enum values when string itself is a number. + * If set to 'false' string are acceptable as ordinal values when + * and are used to map to + * ordinal() of matching enumeration value; if 'true', strings are + * not allowed to be ordinal mapping and + * a {@link JsonMappingException} will be thrown. + * Latter behavior makes sense if there is concern that accidental + * mapping from string values to enums ordinal might happen (and when enums + * are always serialized as JSON Strings) + *

+ * Feature is disabled by default. + */ + FAIL_ON_ORDINAL_STRING_MAPPING_FOR_ENUMS(false) ; diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumDeserializer.java index 18923cdd4f..e20e8cf33b 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/EnumDeserializer.java @@ -234,6 +234,11 @@ private final Object _deserializeAltString(JsonParser p, DeserializationContext try { int index = Integer.parseInt(name); if (index >= 0 && index < _enumsByIndex.length) { + if (ctxt.isEnabled(DeserializationFeature.FAIL_ON_ORDINAL_STRING_MAPPING_FOR_ENUMS)) { + return ctxt.handleWeirdStringValue(_enumClass(), name, + "not allowed to deserialize Enum value by ordinal out of string: disable DeserializationConfig.DeserializationFeature.FAIL_ON_ORDINAL_STRING_MAPPING_FOR_ENUMS to allow" + ); + } return _enumsByIndex[index]; } } catch (NumberFormatException e) { diff --git a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java index efdffaf7db..d367fb3a2e 100644 --- a/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/deser/jdk/EnumDeserializationTest.java @@ -306,6 +306,22 @@ public void testEnumsWithJsonValue() throws Exception e = MAPPER.readValue(quote("bar"), EnumWithJsonValue.class); assertSame(EnumWithJsonValue.B, e); + // then, enum as string ordinal + EnumWithJsonValue enumByStringOrdinal = MAPPER.readValue(quote("0"), EnumWithJsonValue.class); + assertSame(EnumWithJsonValue.A, enumByStringOrdinal); + enumByStringOrdinal = MAPPER.readValue(quote("1"), EnumWithJsonValue.class); + assertSame(EnumWithJsonValue.B, enumByStringOrdinal); + + // but can also be changed to errors: + ObjectReader r = MAPPER.readerFor(EnumWithJsonValue.class) + .with(DeserializationFeature.FAIL_ON_ORDINAL_STRING_MAPPING_FOR_ENUMS);; + try { + enumByStringOrdinal = r.readValue(quote("0")); + fail("Expected an error"); + } catch (JsonMappingException exc) { + verifyException(exc, "Can not deserialize"); + verifyException(exc, "not allowed to deserialize Enum value by ordinal out of string"); + } // then in EnumSet EnumSet set = MAPPER.readValue("[\"bar\"]", new TypeReference>() { });