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>