From af5da0479bef9592d41122e1e79faf63c97fa18e Mon Sep 17 00:00:00 2001 From: arimu1 <19286898+arimu1@users.noreply.github.com> Date: Mon, 17 Aug 2026 14:16:54 +0700 Subject: [PATCH] Fix #892: ignore whitespace-only unnamed XML text as unknown property --- release-notes/CREDITS | 8 +++ release-notes/VERSION | 3 + .../xml/deser/XmlDeserializationContext.java | 26 ++++++++ .../WhitespaceOnlyUnknownProp892Test.java | 65 +++++++++++++++++++ 4 files changed, 102 insertions(+) create mode 100644 src/test/java/tools/jackson/dataformat/xml/deser/WhitespaceOnlyUnknownProp892Test.java diff --git a/release-notes/CREDITS b/release-notes/CREDITS index 9f623f88..1fadf301 100644 --- a/release-notes/CREDITS +++ b/release-notes/CREDITS @@ -158,6 +158,14 @@ Christian Beikov (@beikov) with `@JsonIgnore`-annotated getter (3.2.2) +Lavender Shannon (@retrodaredevil) + * Reported #892: Whitespace-only element body treated as unknown property `""` + (3.3.0) + +@arimu1 + * Fixed #892: Ignore whitespace-only unnamed XML text as unknown property + (3.3.0) + @Sahana2524 * Contributed #891: Enforce `StreamReadConstraints.maxNestingDepth` in `FromXmlParser` diff --git a/release-notes/VERSION b/release-notes/VERSION index 66f49f7c..a2e36b3a 100644 --- a/release-notes/VERSION +++ b/release-notes/VERSION @@ -7,6 +7,9 @@ Version: 3.x (for earlier see VERSION-2.x) 3.3.0 (not yet released) +#892: Whitespace-only element body treated as unknown property `""` + (reported by @retrodaredevil) + (fix by @arimu1) #873: Fix handling of `@JsonApplyView` (fix by @cowtowncoder, w/ Claude code) #878: Re-apply entity/DTD hardening after JDK deserialization of `XmlFactory` diff --git a/src/main/java/tools/jackson/dataformat/xml/deser/XmlDeserializationContext.java b/src/main/java/tools/jackson/dataformat/xml/deser/XmlDeserializationContext.java index 36415d11..5230551b 100644 --- a/src/main/java/tools/jackson/dataformat/xml/deser/XmlDeserializationContext.java +++ b/src/main/java/tools/jackson/dataformat/xml/deser/XmlDeserializationContext.java @@ -49,6 +49,25 @@ public XmlDeserializationContext(TokenStreamFactory tsf, /********************************************************************** */ + /** + * [dataformat-xml#892]: Pretty-printed XML with attribute-only beans/records + * exposes whitespace-only character data as the unnamed text property + * ({@code ""} by default). Skip that synthetic property when it is not + * mapped ({@code @JacksonXmlText}); mapped text still binds as usual. + */ + @Override + public boolean handleUnknownProperty(JsonParser p, ValueDeserializer deser, + Object instanceOrClass, String propName) + throws JacksonException + { + if (_xmlTextElementName.equals(propName) + && _isIgnorableWhitespaceXmlText(p)) { + p.skipChildren(); + return true; + } + return super.handleUnknownProperty(p, deser, instanceOrClass, propName); + } + @Override public Object readRootValue(JsonParser p, JavaType valueType, ValueDeserializer deser, Object valueToUpdate) @@ -120,6 +139,13 @@ public TokenBuffer bufferForInputBuffering(JsonParser p) { /********************************************************************** */ + private static boolean _isIgnorableWhitespaceXmlText(JsonParser p) + throws JacksonException + { + return (p.currentToken() == JsonToken.VALUE_STRING) + && XmlTokenStream._allWs(p.getString()); + } + /** * Helper method for [dataformat-xml#247]: verify that the root element name * matches the expected name when {@link XmlReadFeature#ENFORCE_ROOT_ELEMENT_NAME} diff --git a/src/test/java/tools/jackson/dataformat/xml/deser/WhitespaceOnlyUnknownProp892Test.java b/src/test/java/tools/jackson/dataformat/xml/deser/WhitespaceOnlyUnknownProp892Test.java new file mode 100644 index 00000000..5524f990 --- /dev/null +++ b/src/test/java/tools/jackson/dataformat/xml/deser/WhitespaceOnlyUnknownProp892Test.java @@ -0,0 +1,65 @@ +package tools.jackson.dataformat.xml.deser; + +import org.junit.jupiter.api.Test; + +import com.fasterxml.jackson.annotation.JsonProperty; + +import tools.jackson.databind.DeserializationFeature; +import tools.jackson.databind.exc.UnrecognizedPropertyException; +import tools.jackson.dataformat.xml.XmlMapper; +import tools.jackson.dataformat.xml.XmlTestUtil; + +import static org.junit.jupiter.api.Assertions.*; + +// [dataformat-xml#892]: whitespace-only element body on an attribute-only type +// must not be treated as unknown property "" +public class WhitespaceOnlyUnknownProp892Test extends XmlTestUtil +{ + record Response( + @JsonProperty("Item") Item item + ) { + } + + record Item(String name) { + } + + static class ItemPojo { + public String name; + } + + private final XmlMapper MAPPER = mapperBuilder() + .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) + .build(); + + private static final String ISSUE_XML = """ + + \t + \t + + """; + + @Test + public void testRecordWhitespaceOnlyBody892() throws Exception + { + Response response = MAPPER.readValue(ISSUE_XML, Response.class); + assertEquals(new Item("example"), response.item()); + } + + @Test + public void testPojoWhitespaceOnlyBody892() throws Exception + { + ItemPojo item = MAPPER.readValue("\n\t", ItemPojo.class); + assertEquals("example", item.name); + } + + @Test + public void testNonWhitespaceTextStillUnknown892() throws Exception + { + try { + MAPPER.readValue("secret", ItemPojo.class); + fail("Should not pass"); + } catch (UnrecognizedPropertyException e) { + verifyException(e, "Unrecognized property \"\""); + } + } +}