Skip to content

In CollectionDeserializer, JsonSetter.contentNulls is sometimes ignored #5139

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

Closed
1 task done
k163377 opened this issue May 3, 2025 · 2 comments
Closed
1 task done
Labels
2.19 Issues planned at 2.19 or later
Milestone

Comments

@k163377
Copy link
Contributor

k163377 commented May 3, 2025

Search before asking

  • I searched in the issues and found nothing similar.

Describe the bug

There seems to be a problem with the following code

if (p.hasToken(JsonToken.VALUE_NULL)) {
// 03-Feb-2017, tatu: Hmmh. I wonder... let's try skipping here, too
if (_skipNullValues) {
return result;
}
value = _nullProvider.getNullValue(ctxt);
} else if (typeDeser == null) {
value = valueDes.deserialize(p, ctxt);
} else {
value = valueDes.deserializeWithType(p, ctxt, typeDeser);
}
if (value == null) {
_tryToAddNull(p, ctxt, result);
return result;
}

Jackson may deserialize empty characters in an array on JSON to null.
In this case, JsonToken will be VALUE_STRING instead of VALUE_NULL.

On the other hand, in the code presented, Nulls.SKIP and Nulls.FAIL are only applied if it is VALUE_NULL.
(To be precise, Nulls.SKIP works. However, it seems that the decision regarding _skipNullValues is being made in two places, which I feel should be improved).

Version Information

2.19.0

Reproduction

import com.fasterxml.jackson.annotation.JsonSetter;
import com.fasterxml.jackson.annotation.Nulls;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.exc.InvalidNullException;
import org.junit.jupiter.api.Test;

import java.util.List;

import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class TestGitHubXXX {
    static class Dst {
        private List<Integer> list;

        public List<Integer> getList() {
            return list;
        }

        public void setList(List<Integer> list) {
            this.list = list;
        }
    }

    @Test
    public void nullsFailTest() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forContentNulls(Nulls.FAIL));

        assertThrows(
                InvalidNullException.class,
                () -> mapper.readValue("{\"list\":[\"\"]}", new TypeReference<Dst>(){})
        );
    }

    @Test
    public void nullsSkipTest() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configOverride(List.class).setSetterInfo(JsonSetter.Value.forContentNulls(Nulls.SKIP));

        Dst dst = mapper.readValue("{\"list\":[\"\"]}", new TypeReference<>() {});

        assertTrue(dst.getList().isEmpty());
    }
}

Expected behavior

The JsonSetter.contentNulls must function properly.

Additional context

This was discovered by a bug report to kotlin-module.
FasterXML/jackson-module-kotlin#976

@k163377 k163377 added the to-evaluate Issue that has been received but not yet evaluated label May 3, 2025
k163377 added a commit to k163377/jackson-databind that referenced this issue May 3, 2025
k163377 added a commit to k163377/jackson-databind that referenced this issue May 3, 2025
k163377 added a commit to k163377/jackson-databind that referenced this issue May 3, 2025
k163377 added a commit to k163377/jackson-databind that referenced this issue May 3, 2025
@cowtowncoder
Copy link
Member

Hmmmh. I am not quite sure, this is unfortunately... not clear cut.

The problem is actually with coercion of empty String into null. In general, Nulls.xxx should only need to be checked for input.

But I can see how it's problem for end users. Big problem tho is that now we have tons of places where check needs to be done twice: first for input nulls, and second for JsonDeserializer coerced nulls too.

At the same time, although ideally coercion would not be done in cases where nulls are prohibited, coercion handlers do not have the context to determine this.

So perhaps it is necessary to apply _nullProvider for these two different cases.

@cowtowncoder cowtowncoder added 2.19 Issues planned at 2.19 or later and removed to-evaluate Issue that has been received but not yet evaluated labels May 3, 2025
@cowtowncoder cowtowncoder added this to the 2.19.1 milestone May 3, 2025
@cowtowncoder
Copy link
Member

Fixed for inclusion 2.19.1 (and 3.0.0)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
2.19 Issues planned at 2.19 or later
Projects
None yet
Development

No branches or pull requests

2 participants