Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The default String deserializer does not enforce coercion configs #3240

Closed
joca-bt opened this issue Aug 12, 2021 · 5 comments
Closed

The default String deserializer does not enforce coercion configs #3240

joca-bt opened this issue Aug 12, 2021 · 5 comments
Labels
coercion-config Issue related to 2.12 added "CoercionConfig"

Comments

@joca-bt
Copy link

joca-bt commented Aug 12, 2021

The default String deserializer does not enforce coercion configs (or feature ALLOW_COERCION_OF_SCALARS).

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.cfg.CoercionAction;
import com.fasterxml.jackson.databind.cfg.CoercionInputShape;
import com.fasterxml.jackson.databind.json.JsonMapper;

ObjectMapper objectMapper = JsonMapper.builder().build();
objectMapper.coercionConfigDefaults()
    .setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail)
    .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail)
    .setCoercion(CoercionInputShape.Float, CoercionAction.Fail)
    .setCoercion(CoercionInputShape.String, CoercionAction.Fail)
    .setCoercion(CoercionInputShape.Array, CoercionAction.Fail)
    .setCoercion(CoercionInputShape.Object, CoercionAction.Fail);

objectMapper.readValue("true", String.class); // should throw MismatchedInputException but doesn't
objectMapper.readValue("1", String.class); // should throw MismatchedInputException but doesn't
objectMapper.readValue("1.0", String.class); // should throw MismatchedInputException but doesn't
objectMapper.readValue("[]", String.class); // throws MismatchedInputException
objectMapper.readValue("{}", String.class); // throws MismatchedInputException

When the source is a scalar value, coercion configs seem to be ignored
https://github.com/FasterXML/jackson-databind/blob/2.13/src/main/java/com/fasterxml/jackson/databind/deser/std/StringDeserializer.java.

@joca-bt joca-bt added the to-evaluate Issue that has been received but not yet evaluated label Aug 12, 2021
@cowtowncoder cowtowncoder added coercion-config Issue related to 2.12 added "CoercionConfig" and removed to-evaluate Issue that has been received but not yet evaluated labels Aug 12, 2021
@cowtowncoder
Copy link
Member

cowtowncoder commented Aug 12, 2021

Correct, currently StringDeserializer does not check for coercion config settings and should be improved.

One of the cases was reported earlier, I think: #3013

@joca-bt
Copy link
Author

joca-bt commented Dec 3, 2022

I believe this was fixed in 2.14. @cowtowncoder we can close it.

@joca-bt joca-bt closed this as completed Dec 3, 2022
@cowtowncoder
Copy link
Member

Yes, I think that boolean and number cases at least were fixed via #3013 (integers) and #3613 (floating-point, boolean).

@joca-bt
Copy link
Author

joca-bt commented Dec 5, 2022

I think there is some issue when coercing strings inside JSON arrays and objects, not sure if related with the fix or the default serializer:

// A truly strict String parser.
public class StringDeserializer extends JsonDeserializer<String> {
    @Override
    public String deserialize(JsonParser parser, DeserializationContext context) throws IOException {
        if (!parser.hasToken(VALUE_STRING)) {
            throw context.wrongTokenException(parser, String.class, VALUE_STRING, null);
        }

        return parser.getText();
    }
}

// Test class.
public class Input<T> {
    private final T field;

    public Input(@JsonProperty("field") T value) {
        this.field = value;
    }
}

// Building a strict ObjectMapper.
ObjectMapper objectMapper = JsonMapper.builder()
    .enable(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)
    .defaultSetterInfo(JsonSetter.Value.construct(Nulls.FAIL, Nulls.FAIL))
    .withCoercionConfigDefaults(config -> {
        config.setCoercion(CoercionInputShape.Boolean, CoercionAction.Fail)
            .setCoercion(CoercionInputShape.Integer, CoercionAction.Fail)
            .setCoercion(CoercionInputShape.Float, CoercionAction.Fail)
            .setCoercion(CoercionInputShape.String, CoercionAction.Fail)
            .setCoercion(CoercionInputShape.Array, CoercionAction.Fail)
            .setCoercion(CoercionInputShape.Object, CoercionAction.Fail);
    })
    .build();
TypeFactory typeFactory = objectMapper.getTypeFactory();

JavaType arrayType = typeFactory.constructParametricType(List.class, String.class);
JavaType inputType = typeFactory.constructParametricType(Input.class, arrayType);
String json = "{ \"field\": [ 1 ] }";
objectMapper.readValue(json, inputType);

// Was expecting an error about field[0] being an integer instead of a string.
// Instead got the following:
-> com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot coerce Integer value (1) to element of `java.util.ArrayList<java.lang.String>` (but could if coercion was enabled using `CoercionConfig`)
 at [Source: (String)"{ "field": [ 1 ] }"; line: 1, column: 14] (through reference chain: ...$Input["field"]->java.util.ArrayList[0])
// It seems it might just be the message that is wrong? Since [0] is mentioned.

// If we register the StringDeserializer above in the ObjectMapper we will get the expected error.
-> com.fasterxml.jackson.databind.exc.MismatchedInputException: Unexpected token (VALUE_NUMBER_INT), expected VALUE_STRING
 at [Source: (String)"{ "field": [ 1 ] }"; line: 1, column: 14] (through reference chain: ...$Input["field"]->java.util.ArrayList[0])

Should I open a new ticket for this @cowtowncoder?

@cowtowncoder
Copy link
Member

@joca-bt Yes, if there is missing/misbehaving functionality please file a new issue referencing this one. We can then figure it out separately; I try not to open closed issues as that complicates release notes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
coercion-config Issue related to 2.12 added "CoercionConfig"
Projects
None yet
Development

No branches or pull requests

2 participants