From fd8715e1f777f624722375d590ffd43d01aee4df Mon Sep 17 00:00:00 2001 From: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com> Date: Mon, 22 Jun 2026 09:07:55 +0900 Subject: [PATCH 1/3] Fix #6043: honor FAIL_ON_UNKNOWN_PROPERTIES for creator-based POJOs-as-Array BeanAsArrayDeserializer._deserializeUsingPropertyBased silently skipped JSON Array elements past the property count, ignoring FAIL_ON_UNKNOWN_PROPERTIES for creator-based types such as records. Mirror the check already present on the non-creator deserialization paths. --- .../deser/bean/BeanAsArrayDeserializer.java | 8 +++++ .../databind/struct/POJOAsArrayTest.java | 29 +++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java b/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java index 9efaa25412..d7ac97e2b4 100644 --- a/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java +++ b/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java @@ -390,6 +390,14 @@ protected final Object _deserializeUsingPropertyBased(final JsonParser p, final for (; p.nextToken() != JsonToken.END_ARRAY; ++i) { SettableBeanProperty prop = (i < propCount) ? props[i] : null; if (prop == null) { // we get null if there are extra elements; maybe otherwise too? + // [databind#6043]: extra JSON Array elements past property count must + // honor FAIL_ON_UNKNOWN_PROPERTIES, same as the non-creator path above + if (!_ignoreAllUnknown && ctxt.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) { + ctxt.reportWrongTokenException(this, JsonToken.END_ARRAY, + "Unexpected JSON values; expected at most %d properties (in JSON Array)", + propCount); + // never gets here + } p.skipChildren(); continue; } diff --git a/src/test/java/tools/jackson/databind/struct/POJOAsArrayTest.java b/src/test/java/tools/jackson/databind/struct/POJOAsArrayTest.java index b47153ef46..3e1f816618 100644 --- a/src/test/java/tools/jackson/databind/struct/POJOAsArrayTest.java +++ b/src/test/java/tools/jackson/databind/struct/POJOAsArrayTest.java @@ -256,6 +256,10 @@ public CreatorAsArray(@JsonProperty("x") int x, @JsonProperty("y") int y) public int getY() { return y; } } + // [databind#6043] + @JsonFormat(shape = JsonFormat.Shape.ARRAY) + record XYZParams(int x, int y, int z) { } + @JsonFormat(shape=JsonFormat.Shape.ARRAY) @JsonPropertyOrder({"a","b","x","y"}) static class CreatorAsArrayShuffled @@ -968,4 +972,29 @@ public void testBuilderUnknownExtraProp() throws Exception assertEquals(v._x, 2); assertEquals(v._y, 3); } + + // [databind#6043]: creator-based (e.g. record) POJOs-as-Array must also honor + // FAIL_ON_UNKNOWN_PROPERTIES when the JSON Array has more elements than properties + @Test + public void testCreatorUnknownExtraProp() throws Exception + { + String json = "[1, 2, 3, 4]"; + try { + MAPPER.readerFor(XYZParams.class) + .with(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .readValue(json); + fail("should not pass with extra element"); + } catch (MismatchedInputException e) { + verifyException(e, "Unexpected JSON values"); + } + + // but actually fine if skip-unknown set + XYZParams v = MAPPER.readerFor(XYZParams.class) + .without(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .readValue(json); + assertNotNull(v); + assertEquals(1, v.x()); + assertEquals(2, v.y()); + assertEquals(3, v.z()); + } } From b7bfd2ded57a80391281966d18f75f1ed8948677 Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Sun, 21 Jun 2026 18:06:50 -0700 Subject: [PATCH 2/3] Add tighter check to avoid potential false failures --- .../databind/deser/bean/BeanAsArrayDeserializer.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java b/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java index d7ac97e2b4..ed480cf6f2 100644 --- a/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java +++ b/src/main/java/tools/jackson/databind/deser/bean/BeanAsArrayDeserializer.java @@ -391,8 +391,12 @@ protected final Object _deserializeUsingPropertyBased(final JsonParser p, final SettableBeanProperty prop = (i < propCount) ? props[i] : null; if (prop == null) { // we get null if there are extra elements; maybe otherwise too? // [databind#6043]: extra JSON Array elements past property count must - // honor FAIL_ON_UNKNOWN_PROPERTIES, same as the non-creator path above - if (!_ignoreAllUnknown && ctxt.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) { + // honor FAIL_ON_UNKNOWN_PROPERTIES, same as the non-creator path above. + // Only genuinely-extra elements (past property count) count as "unknown": + // in-bounds null slots (e.g. from renamed/unwrapped properties) are skipped, + // matching the non-creator path's position-based check. + if (i >= propCount + && !_ignoreAllUnknown && ctxt.isEnabled(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)) { ctxt.reportWrongTokenException(this, JsonToken.END_ARRAY, "Unexpected JSON values; expected at most %d properties (in JSON Array)", propCount); From bf2357060f419f840b60235a104b3b42cb97a94c Mon Sep 17 00:00:00 2001 From: Tatu Saloranta Date: Tue, 23 Jun 2026 20:57:43 -0700 Subject: [PATCH 3/3] Add release notes --- release-notes/CREDITS | 10 ++++++++++ release-notes/VERSION | 4 ++++ 2 files changed, 14 insertions(+) diff --git a/release-notes/CREDITS b/release-notes/CREDITS index b397de6ed6..c160b39502 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -579,3 +579,13 @@ Yusuke Nojima (@ynojima) * Reported #6031: Getter annotated with `@JsonIgnore` prevents `@JsonAlias` from working on `@JsonCreator` parameter (regression in 3.2.0) [3.2.1] + +Théo Szanto (@indyteo) + * Reported #6043: `FAIL_ON_UNKNOWN_PROPERTIES` has no effect with `JsonFormat.Shape.ARRAY` + when using creator-based instantiation (such as `record`) + [3.2.1] + +@seonwooj0810 + * Fixed #6043: `FAIL_ON_UNKNOWN_PROPERTIES` has no effect with `JsonFormat.Shape.ARRAY` + when using creator-based instantiation (such as `record`) + [3.2.1] diff --git a/release-notes/VERSION b/release-notes/VERSION index 299527c9bc..ddeb2cef0c 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -21,6 +21,10 @@ No changes since 3.2 on `@JsonCreator` parameter (regression in 3.2.0) (reported by @ynojima) (fix by @cowtowncoder, w/ Claude code) +#6043: `FAIL_ON_UNKNOWN_PROPERTIES` has no effect with `JsonFormat.Shape.ARRAY` when + using creator-based instantiation (such as `record`) + (reported by Théo S) + (fix by @seonwooj0810) 3.2.0 (08-Jun-2026)