This is an automated email from the ASF dual-hosted git repository.

ramanathan1504 pushed a commit to branch 2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


The following commit(s) were added to refs/heads/2.x by this push:
     new 38889a881f Include free-form message when encoding 
StructuredDataMessage to XML (#4180)
38889a881f is described below

commit 38889a881f341a2d9a6d6835eb76435673ffc421
Author: Kamil Krzywanski <[email protected]>
AuthorDate: Sat Jul 18 09:44:49 2026 +0200

    Include free-form message when encoding StructuredDataMessage to XML (#4180)
    
    * Include free-form message when encoding StructuredDataMessage to XML
    
    StructuredDataMessage.asXml omitted the constructor message field. Encode
    it as a distinct <message> element so it is not conflated with a map entry
    keyed "message". Fixes #4141.
    
    * apply spotless formatting
    
    * update pull id in changelog
    
    ---------
    
    Co-authored-by: Ramanathan <[email protected]>
---
 .../log4j/message/StructuredDataMessageTest.java   | 40 +++++++++++++++++++---
 .../log4j/message/StructuredDataMessage.java       |  9 +++++
 .../fix-StructuredDataMessage-XML-message.xml      | 13 +++++++
 3 files changed, 58 insertions(+), 4 deletions(-)

diff --git 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
index 3d3f403bef..b8bf55bc1e 100644
--- 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
+++ 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java
@@ -64,6 +64,7 @@ class StructuredDataMessageTest {
         final String expected = "<StructuredData>\n"
                 + "<type>Alert</type>\n"
                 + "<id>MsgId@12345</id>\n"
+                + "<message>Test message {}</message>\n"
                 + "<Map>\n"
                 + "  <Entry key=\"memo\">This is a very long test memo to 
prevent regression of LOG4J2-114</Entry>\n"
                 + "  <Entry key=\"message\">Test message {}</Entry>\n"
@@ -73,12 +74,44 @@ class StructuredDataMessageTest {
         assertEquals(expected, result);
     }
 
+    @Test
+    void testMsgXmlIncludesConstructorMessage() {
+        // #4141: constructor message must appear (and be escaped) even when 
not put into the map
+        final StructuredDataMessage msg = new StructuredDataMessage("an id", 
"a <msg> & more", "a type");
+        final String result = msg.getFormattedMessage(new String[] {"XML"});
+        final String expected = "<StructuredData>\n"
+                + "<type>a type</type>\n"
+                + "<id>an id</id>\n"
+                + "<message>a &lt;msg&gt; &amp; more</message>\n"
+                + "<Map>\n"
+                + "</Map>\n"
+                + "</StructuredData>\n";
+        assertEquals(expected, result);
+    }
+
+    @Test
+    void testMsgXmlDistinguishesConstructorMessageFromMapEntry() {
+        // #4141: free-form message and a map entry keyed "message" are 
independent
+        final StructuredDataMessage msg = new StructuredDataMessage("an id", 
"a message", "a type");
+        msg.put("message", "foo");
+        final String result = msg.getFormattedMessage(new String[] {"XML"});
+        final String expected = "<StructuredData>\n"
+                + "<type>a type</type>\n"
+                + "<id>an id</id>\n"
+                + "<message>a message</message>\n"
+                + "<Map>\n"
+                + "  <Entry key=\"message\">foo</Entry>\n"
+                + "</Map>\n"
+                + "</StructuredData>\n";
+        assertEquals(expected, result);
+    }
+
     @Test
     void testXmlEncodingOfIdAndType1() {
         final String id = "i<&d>" + XmlFixture.TEXT;
         final String type = "t>yp<e&" + XmlFixture.TEXT;
-        final String actualXml =
-                new StructuredDataMessage(id, "discarded message", 
type).getFormattedMessage(new String[] {"XML"});
+        // null message: keep this test focused on id/type escaping (and 
covers omission of <message>)
+        final String actualXml = new StructuredDataMessage(id, null, 
type).getFormattedMessage(new String[] {"XML"});
         final String expectedXml = "<StructuredData>\n"
                 + "<type>t&gt;yp&lt;e&amp;" + XmlFixture.ENCODED_TEXT
                 + "</type>\n"
@@ -100,8 +133,7 @@ class StructuredDataMessageTest {
         final String type = "t>yp<e&" + XmlFixture.TEXT;
         final StructuredDataId id =
                 new StructuredDataId(idName, idEnterpriseNumber, idRequired, 
idOptional, Integer.MAX_VALUE);
-        final String actualXml =
-                new StructuredDataMessage(id, "discarded message", 
type).getFormattedMessage(new String[] {"XML"});
+        final String actualXml = new StructuredDataMessage(id, null, 
type).getFormattedMessage(new String[] {"XML"});
         final String expectedXml = "<StructuredData>\n"
                 + "<type>t&gt;yp&lt;e&amp;" + XmlFixture.ENCODED_TEXT
                 + "</type>\n"
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
index 69fa3fb8cb..748c975c5a 100644
--- 
a/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java
@@ -373,6 +373,15 @@ public class StructuredDataMessage extends 
MapMessage<StructuredDataMessage, Str
         StringBuilders.escapeXml(sb, start);
         sb.append("</id>\n");
 
+        // Encode message as its own element (distinct from a map entry keyed 
"message")
+        if (message != null) {
+            sb.append("<message>");
+            start = sb.length();
+            sb.append(message);
+            StringBuilders.escapeXml(sb, start);
+            sb.append("</message>\n");
+        }
+
         // Encode the rest
         super.asXml(sb);
 
diff --git a/src/changelog/.2.x.x/fix-StructuredDataMessage-XML-message.xml 
b/src/changelog/.2.x.x/fix-StructuredDataMessage-XML-message.xml
new file mode 100644
index 0000000000..6060f15076
--- /dev/null
+++ b/src/changelog/.2.x.x/fix-StructuredDataMessage-XML-message.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<entry xmlns="https://logging.apache.org/xml/ns";
+       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+       xsi:schemaLocation="
+           https://logging.apache.org/xml/ns
+           https://logging.apache.org/xml/ns/log4j-changelog-0.xsd";
+       type="fixed">
+  <issue id="4141" 
link="https://github.com/apache/logging-log4j2/issues/4141"/>
+  <issue id="4180" link="https://github.com/apache/logging-log4j2/pull/4180"/>
+  <description format="asciidoc">
+    Include the free-form `message` field when encoding 
`StructuredDataMessage` to XML
+  </description>
+</entry>

Reply via email to