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 e4988f41417..37c4a2b7bbe 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 @@ -98,6 +98,19 @@ void format_should_warn_on_insufficient_args( placeholderCount, argCount, pattern); } + @Test + void format_should_not_warn_on_insufficient_args() { + final String expectedMessage = "pan a"; + final String pattern = "pan {}"; + final String[] args = new String[] {"a", null}; + final int argCount = args.length; + + String actualMessage = ParameterFormatter.format(pattern, args, argCount); + assertThat(actualMessage).isEqualTo(expectedMessage); + final List statusDataList = statusListener.getStatusData().collect(Collectors.toList()); + assertThat(statusDataList).isEmpty(); + } + @ParameterizedTest @MethodSource("messageFormattingTestCases") void format_should_work( 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 551f02c7f7b..df2d44d83ee 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 @@ -247,7 +247,7 @@ static void formatMessage( // #2380: check if the count of placeholder is not equal to the count of arguments if (analysis.placeholderCount != argCount) { final int noThrowableArgCount = - argCount < 1 ? 0 : argCount - ((args[argCount - 1] instanceof Throwable) ? 1 : 0); + argCount < 1 ? 0 : argCount - (isLastArgumentThrowable(args, argCount) ? 1 : 0); if (analysis.placeholderCount != noThrowableArgCount) { STATUS_LOGGER.warn( "found {} argument placeholders, but provided {} for pattern `{}`", @@ -268,6 +268,12 @@ static void formatMessage( } } + private static boolean isLastArgumentThrowable(final Object[] args, final int argCount) { + final Object lastArgument = args[argCount - 1]; + // #3975: tolerate null in the last argument since it could have been Throwable parameter + return (lastArgument == null) || (lastArgument instanceof Throwable); + } + private static void formatMessageContainingNoEscapes( final StringBuilder buffer, final String pattern, diff --git a/src/changelog/.2.x.x/3975_prevent_warning_for_last_null_argument.xml b/src/changelog/.2.x.x/3975_prevent_warning_for_last_null_argument.xml new file mode 100644 index 00000000000..9c96386facd --- /dev/null +++ b/src/changelog/.2.x.x/3975_prevent_warning_for_last_null_argument.xml @@ -0,0 +1,14 @@ + + + + + + Prevent ParameterFormatter issuing a warning in case there is an extra null argument. + Needed to support cases with Throwable parameter that may be null. + +