You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by mi...@apache.org on 2017/11/11 21:48:11 UTC

[05/12] logging-log4j2 git commit: LOG4J2-2102: MapMessage Json and XML encodings escape keys and values

LOG4J2-2102: MapMessage Json and XML encodings escape keys and values


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/6757d397
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/6757d397
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/6757d397

Branch: refs/heads/master
Commit: 6757d39783f62961fe9f520367799f8d6fb30bca
Parents: f0123b1
Author: Carter Kozak <c4...@gmail.com>
Authored: Mon Nov 6 13:49:36 2017 -0500
Committer: Mikael Ståldal <mi...@staldal.nu>
Committed: Sat Nov 11 22:08:09 2017 +0100

----------------------------------------------------------------------
 .../logging/log4j/message/MapMessage.java       | 20 ++++++---
 .../logging/log4j/util/StringBuilders.java      | 44 ++++++++++++++++++++
 .../logging/log4j/message/MapMessageTest.java   | 21 ++++++++++
 .../core/pattern/EncodingPatternConverter.java  | 41 ++----------------
 4 files changed, 83 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6757d397/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
index 649772d..48f7ec7 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessage.java
@@ -21,6 +21,7 @@ import java.util.Map;
 import java.util.TreeMap;
 
 import org.apache.logging.log4j.util.BiConsumer;
+import org.apache.logging.log4j.util.Chars;
 import org.apache.logging.log4j.util.EnglishEnums;
 import org.apache.logging.log4j.util.IndexedReadOnlyStringMap;
 import org.apache.logging.log4j.util.IndexedStringMap;
@@ -344,9 +345,11 @@ public class MapMessage<M extends MapMessage<M, V>, V> implements MultiformatMes
         for (int i = 0; i < data.size(); i++) {
             sb.append("  <Entry key=\"")
                     .append(data.getKeyAt(i))
-                    .append("\">")
-                    .append(data.<Object>getValueAt(i))
-                    .append("</Entry>\n");
+                    .append("\">");
+            int size = sb.length();
+            sb.append(data.<Object>getValueAt(i));
+            StringBuilders.escapeXml(sb, size);
+            sb.append("</Entry>\n");
         }
         sb.append("</Map>");
     }
@@ -400,8 +403,15 @@ public class MapMessage<M extends MapMessage<M, V>, V> implements MultiformatMes
             if (i > 0) {
                 sb.append(", ");
             }
-            StringBuilders.appendDqValue(sb, data.getKeyAt(i)).append(':');
-            StringBuilders.appendDqValue(sb, data.getValueAt(i));
+            sb.append(Chars.DQUOTE);
+            int start = sb.length();
+            sb.append(data.getKeyAt(i));
+            StringBuilders.escapeJson(sb, start);
+            sb.append(Chars.DQUOTE).append(':').append(Chars.DQUOTE);
+            start = sb.length();
+            sb.append(data.<Object>getValueAt(i));
+            StringBuilders.escapeJson(sb, start);
+            sb.append(Chars.DQUOTE);
         }
         sb.append('}');
     }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6757d397/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java
index 2d6ae9c..1ab0909 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/StringBuilders.java
@@ -158,4 +158,48 @@ public final class StringBuilders {
             stringBuilder.trimToSize();
         }
     }
+
+    public static void escapeJson(final StringBuilder toAppendTo, final int start) {
+        for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change
+            final char c = toAppendTo.charAt(i);
+            if (Character.isISOControl(c)) {
+                // all iso control characters are in U+00xx
+                toAppendTo.setCharAt(i, '\\');
+                toAppendTo.insert(i + 1, "u0000");
+                toAppendTo.setCharAt(i + 4, Chars.getUpperCaseHex((c & 0xF0) >> 4));
+                toAppendTo.setCharAt(i + 5, Chars.getUpperCaseHex(c & 0xF));
+            } else if (c == '"' || c == '\\') {
+                // only " and \ need to be escaped; other escapes are optional
+                toAppendTo.insert(i, '\\');
+            }
+        }
+    }
+
+    public static void escapeXml(final StringBuilder toAppendTo, final int start) {
+        for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change
+            final char c = toAppendTo.charAt(i);
+            switch (c) {
+                case '&':
+                    toAppendTo.setCharAt(i, '&');
+                    toAppendTo.insert(i + 1, "amp;");
+                    break;
+                case '<':
+                    toAppendTo.setCharAt(i, '&');
+                    toAppendTo.insert(i + 1, "lt;");
+                    break;
+                case '>':
+                    toAppendTo.setCharAt(i, '&');
+                    toAppendTo.insert(i + 1, "gt;");
+                    break;
+                case '"':
+                    toAppendTo.setCharAt(i, '&');
+                    toAppendTo.insert(i + 1, "quot;");
+                    break;
+                case '\'':
+                    toAppendTo.setCharAt(i, '&');
+                    toAppendTo.insert(i + 1, "apos;");
+                    break;
+            }
+        }
+    }
 }

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6757d397/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
index 9aae448..781d46d 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
@@ -64,6 +64,17 @@ public class MapMessageTest {
     }
 
     @Test
+    public void testXMLEscape() {
+        final String testMsg = "Test message <foo>";
+        final StringMapMessage msg = new StringMapMessage();
+        msg.put("message", testMsg);
+        final String result = msg.getFormattedMessage(new String[]{"XML"});
+        final String expected = "<Map>\n  <Entry key=\"message\">Test message &lt;foo&gt;</Entry>\n" +
+                "</Map>";
+        assertEquals(expected, result);
+    }
+
+    @Test
     public void testJSON() {
         final String testMsg = "Test message {}";
         final StringMapMessage msg = new StringMapMessage();
@@ -75,6 +86,16 @@ public class MapMessageTest {
     }
 
     @Test
+    public void testJSONEscape() {
+        final String testMsg = "Test message \"Hello, World!\"";
+        final StringMapMessage msg = new StringMapMessage();
+        msg.put("message", testMsg);
+        final String result = msg.getFormattedMessage(new String[]{"JSON"});
+        final String expected = "{\"message\":\"Test message \\\"Hello, World!\\\"\"}";
+        assertEquals(expected, result);
+    }
+
+    @Test
     public void testJava() {
         final String testMsg = "Test message {}";
         final StringMapMessage msg = new StringMapMessage();

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/6757d397/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EncodingPatternConverter.java
----------------------------------------------------------------------
diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EncodingPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EncodingPatternConverter.java
index 4d22ee0..2699b1f 100644
--- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EncodingPatternConverter.java
+++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/EncodingPatternConverter.java
@@ -25,6 +25,7 @@ import org.apache.logging.log4j.core.layout.PatternLayout;
 import org.apache.logging.log4j.util.Chars;
 import org.apache.logging.log4j.util.EnglishEnums;
 import org.apache.logging.log4j.util.PerformanceSensitive;
+import org.apache.logging.log4j.util.StringBuilders;
 
 /**
  * Converter that encodes the output from a pattern using a specified format. Supported formats include HTML
@@ -139,19 +140,7 @@ public final class EncodingPatternConverter extends LogEventPatternConverter {
         JSON {
             @Override
             void escape(final StringBuilder toAppendTo, final int start) {
-                for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change
-                    final char c = toAppendTo.charAt(i);
-                    if (Character.isISOControl(c)) {
-                        // all iso control characters are in U+00xx
-                        toAppendTo.setCharAt(i, '\\');
-                        toAppendTo.insert(i + 1, "u0000");
-                        toAppendTo.setCharAt(i + 4, Chars.getUpperCaseHex((c & 0xF0) >> 4));
-                        toAppendTo.setCharAt(i + 5, Chars.getUpperCaseHex(c & 0xF));
-                    } else if (c == '"' || c == '\\') {
-                        // only " and \ need to be escaped; other escapes are optional
-                        toAppendTo.insert(i, '\\');
-                    }
-                }
+                StringBuilders.escapeJson(toAppendTo, start);
             }
         },
 
@@ -182,31 +171,7 @@ public final class EncodingPatternConverter extends LogEventPatternConverter {
         XML {
             @Override
             void escape(final StringBuilder toAppendTo, final int start) {
-                for (int i = toAppendTo.length() - 1; i >= start; i--) { // backwards: length may change
-                    final char c = toAppendTo.charAt(i);
-                    switch (c) {
-                        case '&':
-                            toAppendTo.setCharAt(i, '&');
-                            toAppendTo.insert(i + 1, "amp;");
-                            break;
-                        case '<':
-                            toAppendTo.setCharAt(i, '&');
-                            toAppendTo.insert(i + 1, "lt;");
-                            break;
-                        case '>':
-                            toAppendTo.setCharAt(i, '&');
-                            toAppendTo.insert(i + 1, "gt;");
-                            break;
-                        case '"':
-                            toAppendTo.setCharAt(i, '&');
-                            toAppendTo.insert(i + 1, "quot;");
-                            break;
-                        case '\'':
-                            toAppendTo.setCharAt(i, '&');
-                            toAppendTo.insert(i + 1, "apos;");
-                            break;
-                    }
-                }
+                StringBuilders.escapeXml(toAppendTo, start);
             }
         };