From 505716d4b37ab9edf22db65d212845e2f01c8460 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 12 Jun 2020 15:51:27 -0700 Subject: [PATCH 1/2] ... --- .../jackson/databind/deser/std/StdDeserializer.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java index 180da028c3..678e516f2e 100644 --- a/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java +++ b/src/main/java/com/fasterxml/jackson/databind/deser/std/StdDeserializer.java @@ -357,7 +357,14 @@ protected final boolean _parseBooleanPrimitive(JsonParser p, DeserializationCont return _parseBooleanPrimitive(ctxt, p, Boolean.TYPE); } - // @since 2.12 + /** + * @param ctxt Deserialization context for accessing configuration + * @param p Underlying parser + * @param targetType Actual type that is being deserialized, typically + * same as {@link #handledType}, and not necessarily {@code boolean} + * (may be {@code boolean[]} or {@code AtomicBoolean} for example); + * used for coercion config access + */ protected final boolean _parseBooleanPrimitive(DeserializationContext ctxt, JsonParser p, Class targetType) throws IOException @@ -372,7 +379,7 @@ protected final boolean _parseBooleanPrimitive(DeserializationContext ctxt, // may accept ints too, (0 == false, otherwise true) if (t == JsonToken.VALUE_NUMBER_INT) { - Boolean b = _coerceBooleanFromInt(ctxt, p, Boolean.TYPE); + Boolean b = _coerceBooleanFromInt(ctxt, p, targetType); // may get `null`, Boolean.TRUE or Boolean.FALSE so: return (b == Boolean.TRUE); } @@ -425,7 +432,7 @@ protected final Boolean _parseBoolean(DeserializationContext ctxt, } // may accept ints too, (0 == false, otherwise true) if (t == JsonToken.VALUE_NUMBER_INT) { - return _coerceBooleanFromInt(ctxt, p, Boolean.class); + return _coerceBooleanFromInt(ctxt, p, targetType); } // And finally, let's allow Strings to be converted too if (t == JsonToken.VALUE_STRING) { From a179e1fbb886bd4968f967ac713ba81245ba65be Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Fri, 12 Jun 2020 16:02:43 -0700 Subject: [PATCH 2/2] Minor refactoring to prepare for float->int coercion changes --- .../convert/CoerceFloatToIntTest.java | 123 +++++++++--------- 1 file changed, 64 insertions(+), 59 deletions(-) diff --git a/src/test/java/com/fasterxml/jackson/databind/convert/CoerceFloatToIntTest.java b/src/test/java/com/fasterxml/jackson/databind/convert/CoerceFloatToIntTest.java index a90c96f574..4bd362a663 100644 --- a/src/test/java/com/fasterxml/jackson/databind/convert/CoerceFloatToIntTest.java +++ b/src/test/java/com/fasterxml/jackson/databind/convert/CoerceFloatToIntTest.java @@ -1,84 +1,89 @@ package com.fasterxml.jackson.databind.convert; +import java.math.BigInteger; + import com.fasterxml.jackson.databind.*; import com.fasterxml.jackson.databind.exc.MismatchedInputException; public class CoerceFloatToIntTest extends BaseMapTest { - private final ObjectMapper MAPPER = sharedMapper(); - private final ObjectReader R = MAPPER.reader().without(DeserializationFeature.ACCEPT_FLOAT_AS_INT); + private final ObjectMapper DEFAULT_MAPPER = sharedMapper(); + private final ObjectReader READER_LEGACY_FAIL = DEFAULT_MAPPER.reader() + .without(DeserializationFeature.ACCEPT_FLOAT_AS_INT); - public void testDoubleToInt() throws Exception + /* + /******************************************************** + /* Test methods, defaults (legacy) + /******************************************************** + */ + + public void testLegacyDoubleToIntCoercion() throws Exception { // by default, should be ok - Integer I = MAPPER.readValue(" 1.25 ", Integer.class); + Integer I = DEFAULT_MAPPER.readValue(" 1.25 ", Integer.class); assertEquals(1, I.intValue()); - IntWrapper w = MAPPER.readValue("{\"i\":-2.25 }", IntWrapper.class); - assertEquals(-2, w.i); - int[] arr = MAPPER.readValue("[ 1.25 ]", int[].class); - assertEquals(1, arr[0]); - - try { - R.forType(Integer.class).readValue("1.5"); - fail("Should not pass"); - } catch (JsonMappingException e) { - verifyException(e, "Cannot coerce a floating-point"); - } - try { - R.forType(Integer.TYPE).readValue("1.5"); - fail("Should not pass"); - } catch (JsonMappingException e) { - verifyException(e, "Cannot coerce a floating-point"); - } - try { - R.forType(IntWrapper.class).readValue("{\"i\":-2.25 }"); - fail("Should not pass"); - } catch (JsonMappingException e) { - verifyException(e, "Cannot coerce a floating-point"); + { + IntWrapper w = DEFAULT_MAPPER.readValue("{\"i\":-2.25 }", IntWrapper.class); + assertEquals(-2, w.i); + int[] arr = DEFAULT_MAPPER.readValue("[ 1.25 ]", int[].class); + assertEquals(1, arr[0]); } - try { - R.forType(int[].class).readValue("[ 2.5 ]"); - fail("Should not pass"); - } catch (JsonMappingException e) { - verifyException(e, "Cannot coerce a floating-point"); + + Long L = DEFAULT_MAPPER.readValue(" 3.33 ", Long.class); + assertEquals(3L, L.longValue()); + { + LongWrapper w = DEFAULT_MAPPER.readValue("{\"l\":-2.25 }", LongWrapper.class); + assertEquals(-2L, w.l); + long[] arr = DEFAULT_MAPPER.readValue("[ 1.25 ]", long[].class); + assertEquals(1, arr[0]); } + + Short S = DEFAULT_MAPPER.readValue("42.33", Short.class); + assertEquals(42, S.intValue()); + + BigInteger biggie = DEFAULT_MAPPER.readValue("95.3", BigInteger.class); + assertEquals(95L, biggie.longValue()); } - public void testDoubleToLong() throws Exception + public void testLegacyFailDoubleToInt() throws Exception { - // by default, should be ok - Long L = MAPPER.readValue(" 3.33 ", Long.class); - assertEquals(3L, L.longValue()); - LongWrapper w = MAPPER.readValue("{\"l\":-2.25 }", LongWrapper.class); - assertEquals(-2L, w.l); - long[] arr = MAPPER.readValue("[ 1.25 ]", long[].class); - assertEquals(1, arr[0]); + _verifyCoerceFail(READER_LEGACY_FAIL, Integer.class, "1.5"); + _verifyCoerceFail(READER_LEGACY_FAIL, Integer.TYPE, "1.5"); + _verifyCoerceFail(READER_LEGACY_FAIL, IntWrapper.class, "{\"i\":-2.25 }"); + _verifyCoerceFail(READER_LEGACY_FAIL, int[].class, "[ 2.5 ]"); - try { - R.forType(Long.class).readValue("1.5"); - fail("Should not pass"); - } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce a floating-point"); - } + _verifyCoerceFail(READER_LEGACY_FAIL, Long.class, "0.5"); + _verifyCoerceFail(READER_LEGACY_FAIL, Long.TYPE, "-2.5"); + _verifyCoerceFail(READER_LEGACY_FAIL, LongWrapper.class, "{\"l\": 7.7 }"); + _verifyCoerceFail(READER_LEGACY_FAIL, long[].class, "[ -1.35 ]"); + _verifyCoerceFail(READER_LEGACY_FAIL, Short.class, "0.5"); + _verifyCoerceFail(READER_LEGACY_FAIL, Short.TYPE, "-2.5"); + _verifyCoerceFail(READER_LEGACY_FAIL, short[].class, "[ -1.35 ]"); + + _verifyCoerceFail(READER_LEGACY_FAIL, BigInteger.class, "25236.256"); + } + + private void _verifyCoerceFail(ObjectReader r, Class targetType, + String doc) throws Exception + { try { - R.forType(Long.TYPE).readValue("1.5"); - fail("Should not pass"); - } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce a floating-point"); - } - - try { - R.forType(LongWrapper.class).readValue("{\"l\": 7.7 }"); - fail("Should not pass"); - } catch (MismatchedInputException e) { - verifyException(e, "Cannot coerce a floating-point"); - } - try { - R.forType(long[].class).readValue("[ 2.5 ]"); + r.forType(targetType).readValue(doc); fail("Should not pass"); } catch (MismatchedInputException e) { verifyException(e, "Cannot coerce a floating-point"); } } + + public void testDoubleToLong() throws Exception + { + + } + + /* + /******************************************************** + /* Test methods, CoerceConfig + /******************************************************** + */ + }