Repository navigation
Fix #6398: honor null recovery for array-shaped builders - #6406
cowtowncoder merged 6 commits into
Conversation
|
As usual, needs release notes (I'd add but I don't have push access to this pr). |
|
(comment generated by Claude Code) The same NPE is still reachable through the array path, because the null check only covers the non-array branch. Line 137 passes the result of if (!_useVanillaProcessing(ctxt)) {
return finishBuild(ctxt, _deserializeNonVanilla(p, ctxt));
}With no usable Creator on the builder, To reproduce, on this PR's head (dd89e0e): @JsonDeserialize(builder = Value.Builder.class)
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
public static class Value {
public int x;
@JsonPropertyOrder({ "x" })
@JsonFormat(shape = JsonFormat.Shape.ARRAY)
public static class Builder {
int x;
public Builder(int a, int b) { } // no default, delegating or properties-based Creator
public Builder withX(int v) { x = v; return this; }
public Value build() {
Value r = new Value();
r.x = x;
return r;
}
}
}
ObjectMapper mapper = JsonMapper.builder()
.addHandler(new DeserializationProblemHandler() {
@Override
public Object handleMissingInstantiator(DeserializationContext ctxt, Class<?> instClass,
ValueInstantiator valueInsta, JsonParser p, String msg) {
p.skipChildren();
return null;
}
})
.build();
mapper.readValue("[1,2]", Value.class);Actual result: Expected result: Could you move the null check into protected final Object finishBuild(DeserializationContext ctxt, Object builder)
throws JacksonException
{
if (builder == null) {
return null;
}
try {
return _buildMethod.getMember().invoke(builder, (Object[]) null);
} catch (Exception e) {
return wrapInstantiationProblem(ctxt, e);
}
} |
Code Review ✅ Approved🟡 Medium risk · Returning a handler-provided null before invoking an array builder’s build method changes deserialization results; callers may receive null instead of a built value. Preserves a null result from VerificationRules No rules evaluated Functional validation Not enabledFor more verification details, comment OptionsAuto-apply is off → Gitar will not commit updates to this branch. Comment with these commands to change the behavior for this request:
Was this helpful? React with 👍 / 👎 | Powered by Gitar — free for open source |
Fixes #6398.
An array-shaped builder can reach
finishBuild()with a null builder after aDeserializationProblemHandlerrecovers. This happens both when object input is handled as an unexpected token and when array input has no usable builder creator. Calling the build method on that null receiver throws.Check for null in
finishBuild()so all callers preserve the handler result. Add regressions for both recovery paths and include the 3.3.0 entries inVERSIONandCREDITS.The missing-instantiator regression reproduces the reported failure on the prior PR head. Maven
clean verifyon JDK 21 passed with 7,774 tests passed and 1 skipped.