Skip to content

Commit 6beea3f

Browse files
authored
Fix encoding of MSGID and SD-ID fields of StructuredDataMessage to XML (#4136)
1 parent dcb668e commit 6beea3f

3 files changed

Lines changed: 88 additions & 2 deletions

File tree

log4j-api-test/src/test/java/org/apache/logging/log4j/message/StructuredDataMessageTest.java

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,64 @@ void testMsgXml() {
7373
assertEquals(expected, result);
7474
}
7575

76+
@Test
77+
void testXmlEncodingOfIdAndType1() {
78+
final String id = "i<&d>" + XmlFixture.TEXT;
79+
final String type = "t>yp<e&" + XmlFixture.TEXT;
80+
final String actualXml =
81+
new StructuredDataMessage(id, "discarded message", type).getFormattedMessage(new String[] {"XML"});
82+
final String expectedXml = "<StructuredData>\n"
83+
+ "<type>t&gt;yp&lt;e&amp;" + XmlFixture.ENCODED_TEXT
84+
+ "</type>\n"
85+
+ "<id>i&lt;&amp;d&gt;" + XmlFixture.ENCODED_TEXT
86+
+ "</id>\n"
87+
// Following part is encoded by `MapMessage::asXml`, hence, fuzzed & tested elsewhere
88+
+ "<Map>\n"
89+
+ "</Map>\n"
90+
+ "</StructuredData>\n";
91+
assertEquals(expectedXml, actualXml);
92+
}
93+
94+
@Test
95+
void testXmlEncodingOfIdAndType2() {
96+
final String idName = "id&<-name>" + XmlFixture.TEXT;
97+
final String idEnterpriseNumber = "id&<-enterprise-number>" + XmlFixture.TEXT;
98+
final String[] idRequired = {"id&<-required>" + XmlFixture.TEXT};
99+
final String[] idOptional = {"id&<-optional>" + XmlFixture.TEXT};
100+
final String type = "t>yp<e&" + XmlFixture.TEXT;
101+
final StructuredDataId id =
102+
new StructuredDataId(idName, idEnterpriseNumber, idRequired, idOptional, Integer.MAX_VALUE);
103+
final String actualXml =
104+
new StructuredDataMessage(id, "discarded message", type).getFormattedMessage(new String[] {"XML"});
105+
final String expectedXml = "<StructuredData>\n"
106+
+ "<type>t&gt;yp&lt;e&amp;" + XmlFixture.ENCODED_TEXT
107+
+ "</type>\n"
108+
+ "<id>" + "id&amp;&lt;-name&gt;" + XmlFixture.ENCODED_TEXT
109+
+ "@id&amp;&lt;-enterprise-number&gt;" + XmlFixture.ENCODED_TEXT
110+
+ "</id>\n"
111+
// Following part is encoded by `MapMessage::asXml`, hence, fuzzed & tested elsewhere
112+
+ "<Map>\n"
113+
+ "</Map>\n"
114+
+ "</StructuredData>\n";
115+
assertEquals(expectedXml, actualXml);
116+
}
117+
118+
private enum XmlFixture {
119+
;
120+
121+
private static final String TEXT;
122+
123+
private static final String ENCODED_TEXT;
124+
125+
static {
126+
final String notBmp = new String(Character.toChars(0x10000));
127+
final String invalid = "A\uD800B\uDE00C\0\1\2\3";
128+
final String encodedInvalid = "A\uFFFDB\uFFFDC\uFFFD\uFFFD\uFFFD\uFFFD";
129+
TEXT = " '\"\t\r\n" + notBmp + invalid;
130+
ENCODED_TEXT = " &apos;&quot;\t\r\n" + notBmp + encodedInvalid;
131+
}
132+
}
133+
76134
@Test
77135
void testBuilder() {
78136
final String testMsg = "Test message {}";

log4j-api/src/main/java/org/apache/logging/log4j/message/StructuredDataMessage.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -356,10 +356,26 @@ public final void asString(final Format format, final StructuredDataId structure
356356
}
357357

358358
private void asXml(final StructuredDataId structuredDataId, final StringBuilder sb) {
359+
359360
sb.append("<StructuredData>\n");
360-
sb.append("<type>").append(type).append("</type>\n");
361-
sb.append("<id>").append(structuredDataId).append("</id>\n");
361+
362+
// Encode type
363+
sb.append("<type>");
364+
int start = sb.length();
365+
sb.append(type);
366+
StringBuilders.escapeXml(sb, start);
367+
sb.append("</type>\n");
368+
369+
// Encode ID
370+
sb.append("<id>");
371+
start = sb.length();
372+
structuredDataId.formatTo(sb);
373+
StringBuilders.escapeXml(sb, start);
374+
sb.append("</id>\n");
375+
376+
// Encode the rest
362377
super.asXml(sb);
378+
363379
sb.append("\n</StructuredData>\n");
364380
}
365381

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<entry xmlns="https://logging.apache.org/xml/ns"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="
5+
https://logging.apache.org/xml/ns
6+
https://logging.apache.org/xml/ns/log4j-changelog-0.xsd"
7+
type="fixed">
8+
<issue id="4136" link="https://github.com/apache/logging-log4j2/pull/4136"/>
9+
<description format="asciidoc">
10+
Fix encoding of `MSGID` and `SD-ID` fields of `StructuredDataMessage` to XML
11+
</description>
12+
</entry>

0 commit comments

Comments
 (0)