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

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

commit 45c53f9630eafb2c04c5e6a29406f0c53d812a63
Author: Gary Gregory <[email protected]>
AuthorDate: Mon Feb 21 11:30:41 2022 -0500

    [LOG4J2-3410] Log4j 1.2 bridge throws a ClassCastException when logging
    a Map with non-String keys.
    
    Conflicts:
        
log4j-api/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
        src/changes/changes.xml
---
 .../java/org/apache/log4j/LoggerJira3410Test.java  | 82 ++++++++++++++++++++++
 .../org/apache/log4j/config/TestConfigurator.java  |  2 +-
 .../log4j/util/SortedArrayStringMapTest.java       | 22 +++++-
 .../logging/log4j/util/SortedArrayStringMap.java   |  5 +-
 src/changes/changes.xml                            |  3 +
 5 files changed, 109 insertions(+), 5 deletions(-)

diff --git 
a/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerJira3410Test.java 
b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerJira3410Test.java
new file mode 100644
index 0000000..bdb661a
--- /dev/null
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/LoggerJira3410Test.java
@@ -0,0 +1,82 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.log4j;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.log4j.bridge.AppenderAdapter;
+import org.apache.log4j.config.TestConfigurator;
+import org.apache.logging.log4j.core.Appender;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.util.SortedArrayStringMap;
+import org.junit.Test;
+
+/**
+ * Tests Jira3410.
+ */
+public class LoggerJira3410Test {
+
+    @Test
+    public void test() throws Exception {
+        try (LoggerContext loggerContext = 
TestConfigurator.configure("target/test-classes/log4j1-list.properties")) {
+            final Logger logger = LogManager.getLogger("test");
+            //
+            Map<Object, Integer> map = new HashMap<>(1);
+            map.put(Long.MAX_VALUE, 1);
+            logger.debug(map);
+            //
+            map.put(null, null);
+            logger.debug(map);
+            //
+            logger.debug(new SortedArrayStringMap((Map) map));
+            //
+            final Configuration configuration = 
loggerContext.getConfiguration();
+            final Map<String, Appender> appenders = 
configuration.getAppenders();
+            ListAppender listAppender = null;
+            for (final Map.Entry<String, Appender> entry : 
appenders.entrySet()) {
+                if (entry.getKey().equals("list")) {
+                    listAppender = (ListAppender) ((AppenderAdapter.Adapter) 
entry.getValue()).getAppender();
+                }
+            }
+            assertNotNull("No Message Appender", listAppender);
+            final List<String> messages = listAppender.getMessages();
+            assertTrue("No messages", messages != null && !messages.isEmpty());
+            final String msg0 = messages.get(0);
+            final String msg1 = messages.get(1);
+            final String msg2 = messages.get(2);
+            // TODO Should be 1, not "1".
+            // TODO Where are the {} characters?
+            assertTrue(msg0, msg0.trim().endsWith(Long.MAX_VALUE + "=\"1\""));
+            //
+            // TODO Should be 1, not "1".
+            // TODO Should be null, not "null".
+            // TODO Where are the {} characters? 
+            // TODO Where is the , characters? 
+            assertTrue(msg1, msg1.trim().endsWith("null=\"null\" " + 
Long.MAX_VALUE + "=\"1\""));
+            //
+            assertTrue(msg2, msg2.trim().endsWith("{null=null, " + 
Long.MAX_VALUE + "=1}"));
+        }
+    }
+
+}
diff --git 
a/log4j-1.2-api/src/test/java/org/apache/log4j/config/TestConfigurator.java 
b/log4j-1.2-api/src/test/java/org/apache/log4j/config/TestConfigurator.java
index c98a008..c871566 100644
--- a/log4j-1.2-api/src/test/java/org/apache/log4j/config/TestConfigurator.java
+++ b/log4j-1.2-api/src/test/java/org/apache/log4j/config/TestConfigurator.java
@@ -33,7 +33,7 @@ import org.apache.logging.log4j.core.config.Configurator;
 
 public class TestConfigurator {
 
-    static LoggerContext configure(final String configLocation) throws 
IOException {
+    public static LoggerContext configure(final String configLocation) throws 
IOException {
         final Path path = Paths.get(configLocation);
         try (final InputStream inputStream = Files.newInputStream(path)) {
             final ConfigurationSource source = new 
ConfigurationSource(inputStream, path);
diff --git 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
index 6e1d9dc..8e214fe 100644
--- 
a/log4j-api-test/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
+++ 
b/log4j-api-test/src/test/java/org/apache/logging/log4j/util/SortedArrayStringMapTest.java
@@ -16,7 +16,15 @@
  */
 package org.apache.logging.log4j.util;
 
-import org.junit.jupiter.api.Test;
+import static org.junit.jupiter.api.Assertions.assertAll;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.fail;
 
 import java.io.BufferedReader;
 import java.io.ByteArrayInputStream;
@@ -36,7 +44,7 @@ import java.util.ConcurrentModificationException;
 import java.util.HashMap;
 import java.util.Map;
 
-import static org.junit.jupiter.api.Assertions.*;
+import org.junit.jupiter.api.Test;
 
 /**
  * Tests the SortedArrayStringMap class.
@@ -60,6 +68,16 @@ public class SortedArrayStringMapTest {
     }
 
     @Test
+    public void testConstructorNonStringKeys() {
+        Map<Object, Integer> map = new HashMap<>(1);
+        map.put(Long.MAX_VALUE, 1);
+        map.put(null, null);
+        SortedArrayStringMap sMap = new SortedArrayStringMap((Map) map);
+        assertEquals(1, (int) sMap.getValue(Long.toString(Long.MAX_VALUE)));
+        assertEquals((Integer) null, sMap.getValue(null));
+    }
+
+    @Test
     public void testToString() {
         final SortedArrayStringMap original = new SortedArrayStringMap();
         original.putValue("a", "avalue");
diff --git 
a/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
 
b/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
index c7df7a7..1f8bddb 100644
--- 
a/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
+++ 
b/log4j-api/src/main/java/org/apache/logging/log4j/util/SortedArrayStringMap.java
@@ -72,7 +72,7 @@ public class SortedArrayStringMap implements IndexedStringMap 
{
     /**
      * An empty array instance to share when the table is not inflated.
      */
-    private static final String[] EMPTY = {};
+    private static final String[] EMPTY = Strings.EMPTY_ARRAY;
     private static final String FROZEN = "Frozen collection cannot be 
modified";
 
     private transient String[] keys = EMPTY;
@@ -151,7 +151,8 @@ public class SortedArrayStringMap implements 
IndexedStringMap {
     public SortedArrayStringMap(final Map<String, ?> map) {
         resize(ceilingNextPowerOfTwo(map.size()));
         for (final Map.Entry<String, ?> entry : map.entrySet()) {
-            putValue(entry.getKey(), entry.getValue());
+            // The key might not actually be a String.
+            putValue(Objects.toString(entry.getKey(), null), entry.getValue());
         }
     }
 
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index c0e3c09..6ebb56b 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -367,6 +367,9 @@
       <action dev="ggregory" type="fix" due-to="Gary Gregory, Piotr P. 
Karwasz">
         Fix log4j-jakarta-web service file #723.
       </action>
+      <action issue="LOG4J2-3410" dev="ggregory" type="fix" due-to="Barry 
Sham, Gary Gregory">
+        Log4j 1.2 bridge throws a ClassCastException when logging a Map with 
non-String keys.
+      </action>
       <!-- ADD -->
       <action issue="LOG4J2-3297" dev="rgoers" type="add">
         Limit loading of configuration via a url to https by default.

Reply via email to