Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ void testMsgXml() {
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"
Expand All @@ -73,12 +74,45 @@ void testMsgXml() {
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;
// null message: keep this test focused on id/type escaping (and covers omission of <message>)
final String actualXml =
new StructuredDataMessage(id, "discarded message", type).getFormattedMessage(new String[] {"XML"});
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"
Expand All @@ -101,7 +135,7 @@ void testXmlEncodingOfIdAndType2() {
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"});
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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -373,6 +373,15 @@ private void asXml(final StructuredDataId structuredDataId, final StringBuilder
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);

Expand Down
12 changes: 12 additions & 0 deletions src/changelog/.2.x.x/fix-StructuredDataMessage-XML-message.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?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"/>
<description format="asciidoc">
Include the free-form `message` field when encoding `StructuredDataMessage` to XML
</description>
</entry>