This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch 2.x in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit c890ca04710a7705492786c9d81a1db670062f84 Author: PanLongfei <[email protected]> AuthorDate: Tue Mar 19 22:02:31 2024 +0800 Fix issue #2380: Log messages with insufficient parameters should not throw exception. --- .../log4j/message/ParameterFormatterTest.java | 16 +++--- .../log4j/message/ParameterizedMessageTest.java | 62 +++++----------------- .../logging/log4j/message/ParameterFormatter.java | 8 --- ...380_insufficient_args_in_ParameterFormatter.xml | 11 ++++ 4 files changed, 31 insertions(+), 66 deletions(-) diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java index e31796368b..6fe4f2d519 100644 --- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java +++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterFormatterTest.java @@ -17,7 +17,6 @@ package org.apache.logging.log4j.message; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import java.util.ArrayList; import java.util.Arrays; @@ -68,15 +67,12 @@ class ParameterFormatterTest { } } - @ParameterizedTest - @CsvSource({"1,foo {}", "2,bar {}{}"}) - void format_should_fail_on_insufficient_args(final int placeholderCount, final String pattern) { - final int argCount = placeholderCount - 1; - assertThatThrownBy(() -> ParameterFormatter.format(pattern, new Object[argCount], argCount)) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage( - "found %d argument placeholders, but provided %d for pattern `%s`", - placeholderCount, argCount, pattern); + @Test + void formatWithInsufficientArgs() { + final String pattern = "Test message {}-{} {}"; + final Object[] args = {"a", "b"}; + final String message = ParameterFormatter.format(pattern, args, args.length); + assertThat(message).isEqualTo("Test message a-b {}"); } @ParameterizedTest diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java index 39a5fe3994..149709a6a4 100644 --- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java +++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/ParameterizedMessageTest.java @@ -19,12 +19,7 @@ package org.apache.logging.log4j.message; import static org.assertj.core.api.Assertions.assertThat; import java.math.BigDecimal; -import java.util.List; -import java.util.function.Supplier; -import java.util.stream.Collectors; import java.util.stream.Stream; -import org.apache.logging.log4j.Level; -import org.apache.logging.log4j.status.StatusData; import org.apache.logging.log4j.test.ListStatusListener; import org.apache.logging.log4j.test.junit.Mutable; import org.apache.logging.log4j.test.junit.SerialUtil; @@ -185,50 +180,21 @@ class ParameterizedMessageTest { assertThat(actual.getFormattedMessage()).isEqualTo(expected.getFormattedMessage()); } - static Stream<Object[]> testCasesForInsufficientFormatArgs() { - return Stream.of(new Object[] {1, "foo {}"}, new Object[] {2, "bar {}{}"}); - } - - @ParameterizedTest - @MethodSource("testCasesForInsufficientFormatArgs") - void formatTo_should_fail_on_insufficient_args(final int placeholderCount, final String pattern) { - final int argCount = placeholderCount - 1; - verifyFormattingFailureOnInsufficientArgs(placeholderCount, pattern, argCount, () -> { - final ParameterizedMessage message = new ParameterizedMessage(pattern, new Object[argCount]); - final StringBuilder buffer = new StringBuilder(); - message.formatTo(buffer); - return buffer.toString(); - }); + @Test + void formatToWithInsufficientArgs() { + final String pattern = "Test message {}-{} {}"; + final Object[] args = {"a", "b"}; + final ParameterizedMessage message = new ParameterizedMessage(pattern, args); + final StringBuilder buffer = new StringBuilder(); + message.formatTo(buffer); + assertThat(buffer.toString()).isEqualTo("Test message a-b {}"); } - @ParameterizedTest - @MethodSource("testCasesForInsufficientFormatArgs") - void format_should_fail_on_insufficient_args(final int placeholderCount, final String pattern) { - final int argCount = placeholderCount - 1; - verifyFormattingFailureOnInsufficientArgs( - placeholderCount, pattern, argCount, () -> ParameterizedMessage.format(pattern, new Object[argCount])); - } - - private void verifyFormattingFailureOnInsufficientArgs( - final int placeholderCount, - final String pattern, - final int argCount, - final Supplier<String> formattedMessageSupplier) { - - // Verify the formatted message - final String formattedMessage = formattedMessageSupplier.get(); - assertThat(formattedMessage).isEqualTo(pattern); - - // Verify the logged failure - final List<StatusData> statusDataList = statusListener.getStatusData().collect(Collectors.toList()); - assertThat(statusDataList).hasSize(1); - final StatusData statusData = statusDataList.get(0); - assertThat(statusData.getLevel()).isEqualTo(Level.ERROR); - assertThat(statusData.getMessage().getFormattedMessage()).isEqualTo("Unable to format msg: %s", pattern); - assertThat(statusData.getThrowable()) - .isInstanceOf(IllegalArgumentException.class) - .hasMessage( - "found %d argument placeholders, but provided %d for pattern `%s`", - placeholderCount, argCount, pattern); + @Test + void formatWithInsufficientArgs() { + final String pattern = "Test message {}-{} {}"; + final Object[] args = {"a", "b"}; + final String message = ParameterizedMessage.format(pattern, args); + assertThat(message).isEqualTo("Test message a-b {}"); } } diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java index 58436f8be3..d2bae68748 100644 --- a/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java +++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/ParameterFormatter.java @@ -240,14 +240,6 @@ final class ParameterFormatter { return; } - // Fail if there are insufficient arguments - if (analysis.placeholderCount > args.length) { - final String message = String.format( - "found %d argument placeholders, but provided %d for pattern `%s`", - analysis.placeholderCount, args.length, pattern); - throw new IllegalArgumentException(message); - } - // Fast-path for patterns containing no escapes if (analysis.escapedCharFound) { formatMessageContainingEscapes(buffer, pattern, args, argCount, analysis); diff --git a/src/changelog/.2.x.x/fix_2380_insufficient_args_in_ParameterFormatter.xml b/src/changelog/.2.x.x/fix_2380_insufficient_args_in_ParameterFormatter.xml new file mode 100644 index 0000000000..558d6a1f28 --- /dev/null +++ b/src/changelog/.2.x.x/fix_2380_insufficient_args_in_ParameterFormatter.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<entry xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xmlns="http://logging.apache.org/log4j/changelog" + xsi:schemaLocation="http://logging.apache.org/log4j/changelog https://logging.apache.org/log4j/changelog-0.1.3.xsd" + type="fixed"> + <issue id="2380" link="https://github.com/apache/logging-log4j2/pull/2380"/> + <description format="asciidoc"> + Fix that parameterized message formatting throws an exception when there are insufficient number of parameters. + It previously simply didn't replace the '{}' sequence. The behavior changed in 2.21.0 and should be restored for backward compatibility. + </description> +</entry>
