You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2022/02/26 22:06:53 UTC

[logging-log4j2] branch release-2.x updated: [LOG4J-3413] Fixes resolution of non-Log4j properties

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

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


The following commit(s) were added to refs/heads/release-2.x by this push:
     new af5d3b5  [LOG4J-3413] Fixes resolution of non-Log4j properties
     new 35f9db7  Merge pull request #774 from ppkarwasz/jira3413
af5d3b5 is described below

commit af5d3b589b6840147fa68ad48bfa7d0c32475b5e
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Fri Feb 25 21:58:18 2022 +0100

    [LOG4J-3413] Fixes resolution of non-Log4j properties
    
    For properties that does not start with `log4j` or
    `org.apache.logging.log4j` the loosed token-based lookup should not be
    applied. There are a couple of exceptions to this rule: the properties
    that start with `AsyncLogger` and those related to
    `disableThreadContext`.
    
    This PR prevents properties such as `level` to be used as a substitute
    for `log4j2.level`
---
 .../apache/logging/log4j/util/PropertySource.java  | 27 +++++++++++++----
 .../logging/log4j/util/PropertiesUtilTest.java     | 28 ++++++++++++++++++
 .../log4j/util/PropertySourceTokenizerTest.java    |  4 +++
 .../src/test/resources/Jira3413Test.properties     | 34 ++++++++++++++++++++++
 4 files changed, 88 insertions(+), 5 deletions(-)

diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertySource.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertySource.java
index 58c462c..96d09f8 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertySource.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/PropertySource.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.util;
 
 import java.io.Serializable;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -100,9 +101,19 @@ public interface PropertySource {
      * @since 2.10.0
      */
     final class Util {
-        private static final String PREFIXES = "(?i:^log4j2?[-._/]?|^org\\.apache\\.logging\\.log4j\\.)?";
-        private static final Pattern PROPERTY_TOKENIZER = Pattern.compile(PREFIXES + "([A-Z]*[a-z0-9]+|[A-Z0-9]+)[-._/]?");
+        private static final Pattern PREFIX_PATTERN = Pattern.compile(
+                // just lookahead for AsyncLogger
+                "(^log4j2?[-._/]?|^org\\.apache\\.logging\\.log4j\\.)|(?=AsyncLogger(Config)?\\.)",
+                Pattern.CASE_INSENSITIVE);
+        private static final Pattern PROPERTY_TOKENIZER = Pattern.compile("([A-Z]*[a-z0-9]+|[A-Z0-9]+)[-._/]?");
         private static final Map<CharSequence, List<CharSequence>> CACHE = new ConcurrentHashMap<>();
+        static {
+            // Add legacy properties without Log4j prefix
+            CACHE.put("disableThreadContext", Arrays.asList("disable", "thread", "context"));
+            CACHE.put("disableThreadContextStack", Arrays.asList("disable", "thread", "context", "stack"));
+            CACHE.put("disableThreadContextMap", Arrays.asList("disable", "thread", "context", "map"));
+            CACHE.put("isThreadContextMapInheritable", Arrays.asList("is", "thread", "context", "map", "inheritable"));
+        }
 
         /**
          * Converts a property name string into a list of tokens. This will strip a prefix of {@code log4j},
@@ -118,9 +129,15 @@ public interface PropertySource {
                 return CACHE.get(value);
             }
             final List<CharSequence> tokens = new ArrayList<>();
-            final Matcher matcher = PROPERTY_TOKENIZER.matcher(value);
-            while (matcher.find()) {
-                tokens.add(matcher.group(1).toLowerCase());
+            int start = 0;
+            final Matcher prefixMatcher = PREFIX_PATTERN.matcher(value);
+            if (prefixMatcher.find(start)) {
+                start = prefixMatcher.end();
+                final Matcher matcher = PROPERTY_TOKENIZER.matcher(value);
+                while (matcher.find(start)) {
+                    tokens.add(matcher.group(1).toLowerCase());
+                    start = matcher.end();
+                }
             }
             CACHE.put(value, tokens);
             return tokens;
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
index 7f0d1c7..e54cd49 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertiesUtilTest.java
@@ -120,4 +120,32 @@ public class PropertiesUtilTest {
         assertNotNull(value, "System property was not published");
         assertEquals("Log4j", value);
     }
+
+    private static final String[][] data = {
+            { null, "org.apache.logging.log4j.level" },
+            { null, "Log4jAnotherProperty" },
+            { null, "log4j2.catalinaBase" },
+            { "ok", "log4j2.configurationFile" },
+            { "ok", "log4j2.defaultStatusLevel" },
+            { "ok", "log4j2.newLevel" },
+            { "ok", "log4j2.asyncLoggerTimeout" },
+            { "ok", "log4j2.asyncLoggerConfigRingBufferSize" },
+            { "ok", "log4j2.disableThreadContext" },
+            { "ok", "log4j2.disableThreadContextStack" },
+            { "ok", "log4j2.disableThreadContextMap" },
+            { "ok", "log4j2.isThreadContextMapInheritable" }
+            };
+
+    /**
+     * LOG4J2-3413: Log4j should only resolve properties that start with a 'log4j'
+     * prefix or similar.
+     */
+    @Test
+    @ResourceLock(value = Resources.SYSTEM_PROPERTIES, mode = ResourceAccessMode.READ)
+    public void testResolvesOnlyLog4jProperties() {
+        final PropertiesUtil util = new PropertiesUtil("Jira3413Test.properties");
+        for (final String[] pair : data) {
+            assertEquals(pair[0], util.getStringProperty(pair[1]));
+        }
+    }
 }
diff --git a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertySourceTokenizerTest.java b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertySourceTokenizerTest.java
index f73c402..6dbf4d0 100644
--- a/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertySourceTokenizerTest.java
+++ b/log4j-api/src/test/java/org/apache/logging/log4j/util/PropertySourceTokenizerTest.java
@@ -44,6 +44,10 @@ public class PropertySourceTokenizerTest {
             {"log4j2-dashed-propertyName", Arrays.asList("dashed", "property", "name")},
             {"Log4jProperty_with.all-the/separators", Arrays.asList("property", "with", "all", "the", "separators")},
             {"org.apache.logging.log4j.config.property", Arrays.asList("config", "property")},
+            // LOG4J2-3413
+            {"level", Collections.emptyList()},
+            {"user.home", Collections.emptyList()},
+            {"CATALINA_BASE", Collections.emptyList()}
         };
     }
 
diff --git a/log4j-api/src/test/resources/Jira3413Test.properties b/log4j-api/src/test/resources/Jira3413Test.properties
new file mode 100644
index 0000000..1d3bdff
--- /dev/null
+++ b/log4j-api/src/test/resources/Jira3413Test.properties
@@ -0,0 +1,34 @@
+#
+# 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.
+#
+
+# These should not be resolved
+level=fail
+another.property=fail
+catalina.base=fail
+
+# Some legacy properties with a characteristic prefix
+log4j.configurationFile=ok
+Log4jDefaultStatusLevel=ok
+org.apache.logging.log4j.newLevel=ok
+
+# No characteristic prefix
+AsyncLogger.Timeout=ok
+AsyncLoggerConfig.RingBufferSize=ok
+disableThreadContext=ok
+disableThreadContextStack=ok
+disableThreadContextMap=ok
+isThreadContextMapInheritable=ok
\ No newline at end of file