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

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


The following commit(s) were added to refs/heads/master by this push:
     new 8d8096403f LOG4J2-3614 Harden InstantFormatter against delegate 
failures.
8d8096403f is described below

commit 8d8096403f912645c6ae83c95b45fc3760719a4a
Author: Volkan Yazıcı <[email protected]>
AuthorDate: Mon Oct 10 11:13:12 2022 +0200

    LOG4J2-3614 Harden InstantFormatter against delegate failures.
---
 .../log4j/core/time/InstantFormatterTest.java      | 44 ++++++++++++++++++++++
 .../logging/log4j/core/time/InstantFormatter.java  | 18 +++++++--
 src/changes/changes.xml                            |  3 ++
 3 files changed, 61 insertions(+), 4 deletions(-)

diff --git 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/time/InstantFormatterTest.java
 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/time/InstantFormatterTest.java
index 0f4b73de9e..9da1852f83 100644
--- 
a/log4j-core-test/src/test/java/org/apache/logging/log4j/core/time/InstantFormatterTest.java
+++ 
b/log4j-core-test/src/test/java/org/apache/logging/log4j/core/time/InstantFormatterTest.java
@@ -16,11 +16,14 @@
  */
 package org.apache.logging.log4j.core.time;
 
+import org.apache.logging.log4j.core.time.internal.format.FastDateFormat;
+import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
 import org.assertj.core.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.CsvSource;
 
+import java.util.Locale;
 import java.util.TimeZone;
 
 class InstantFormatterTest {
@@ -59,4 +62,45 @@ class InstantFormatterTest {
                 .isEqualTo("1970-01-01T00:00:00.123456789Z");
     }
 
+    /**
+     * @see <a 
href="https://issues.apache.org/jira/browse/LOG4J2-3614";>LOG4J2-3614</a>
+     */
+    @Test
+    void FastDateFormat_failures_should_be_handled() {
+
+        // Define a pattern causing `FastDateFormat` to fail.
+        final String pattern = "ss.nnnnnnnnn";
+        final TimeZone timeZone = TimeZone.getTimeZone("UTC");
+        final Locale locale = Locale.US;
+
+        // Assert that the pattern is not supported by `FixedDateFormat`.
+        final FixedDateFormat fixedDateFormat = 
FixedDateFormat.createIfSupported(pattern, timeZone.getID());
+        Assertions.assertThat(fixedDateFormat).isNull();
+
+        // Assert that the pattern indeed causes a `FastDateFormat` failure.
+        Assertions
+                .assertThatThrownBy(() -> FastDateFormat.getInstance(pattern, 
timeZone, locale))
+                .isInstanceOf(IllegalArgumentException.class)
+                .hasMessage("Illegal pattern component: nnnnnnnnn");
+
+        // Assert that `InstantFormatter` falls back to `DateTimeFormatter`.
+        final InstantFormatter formatter = InstantFormatter
+                .newBuilder()
+                .setPattern(pattern)
+                .setTimeZone(timeZone)
+                .build();
+        Assertions
+                .assertThat(formatter.getInternalImplementationClass())
+                .asString()
+                .endsWith(".DateTimeFormatter");
+
+        // Assert that formatting works.
+        MutableInstant instant = new MutableInstant();
+        instant.initFromEpochSecond(0, 123_456_789);
+        Assertions
+                .assertThat(formatter.format(instant))
+                .isEqualTo("00.123456789");
+
+    }
+
 }
diff --git 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/time/InstantFormatter.java
 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/time/InstantFormatter.java
index cefc742352..f467240902 100644
--- 
a/log4j-core/src/main/java/org/apache/logging/log4j/core/time/InstantFormatter.java
+++ 
b/log4j-core/src/main/java/org/apache/logging/log4j/core/time/InstantFormatter.java
@@ -18,6 +18,7 @@ package org.apache.logging.log4j.core.time;
 
 import org.apache.logging.log4j.core.time.internal.format.FastDateFormat;
 import org.apache.logging.log4j.core.time.internal.format.FixedDateFormat;
+import org.apache.logging.log4j.status.StatusLogger;
 import org.apache.logging.log4j.util.Strings;
 
 import java.time.format.DateTimeFormatter;
@@ -36,6 +37,8 @@ import java.util.TimeZone;
  */
 public final class InstantFormatter {
 
+    private static final StatusLogger LOGGER = StatusLogger.getLogger();
+
     /**
      * The list of formatter factories in decreasing efficiency order.
      */
@@ -50,10 +53,17 @@ public final class InstantFormatter {
     private InstantFormatter(final Builder builder) {
         this.formatter = Arrays
                 .stream(FORMATTER_FACTORIES)
-                .map(formatterFactory -> formatterFactory.createIfSupported(
-                        builder.getPattern(),
-                        builder.getLocale(),
-                        builder.getTimeZone()))
+                .map(formatterFactory -> {
+                    try {
+                        return formatterFactory.createIfSupported(
+                                builder.getPattern(),
+                                builder.getLocale(),
+                                builder.getTimeZone());
+                    } catch (final Exception error) {
+                        LOGGER.warn("skipping the failed formatter factory 
\"{}\"", formatterFactory, error);
+                        return null;
+                    }
+                })
                 .filter(Objects::nonNull)
                 .findFirst()
                 .orElseThrow(() -> new AssertionError("could not find a 
matching formatter"));
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 14a854af28..f1f25d1cfe 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -202,6 +202,9 @@
       </action>
     </release>
     <release version="2.19.0" date="2022-MM-DD" description="GA Release 
2.19.0">
+      <action issue="LOG4J2-3614" dev="vy" type="fix" due-to="strainu">
+        Harden InstantFormatter against delegate failures.
+      </action>
       <action issue="LOG4J2-3572" dev="rgeors" type="update">
         Add getExplicitLevel method to LoggerConfig.
       </action>

Reply via email to