This is an automated email from the ASF dual-hosted git repository. pkarwasz pushed a commit to branch fix/2.25.x/jtl-nan in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 08964048c4d8dc58ab248ca38d3c6deaa101f9b3 Author: Piotr P. Karwasz <[email protected]> AuthorDate: Tue Mar 10 21:38:50 2026 +0100 JsonWriter: Write non-finite floating-point values as strings This change updates `JsonWriter` to serialize non-finite `float` and `double` values (`NaN`, `Infinity`, and `-Infinity`) as JSON strings. This behavior aligns with Jackson's `JsonWriteFeature#WRITE_NAN_AS_STRINGS`. Previously, these values were written without quotes, which produces **invalid JSON** according to the JSON specification. --- .../layout/template/json/util/JsonWriterTest.java | 18 ++++++++++++++++++ .../log4j/layout/template/json/util/JsonWriter.java | 14 ++++++++++++-- src/changelog/.2.x.x/jtl-nan.xml | 11 +++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) diff --git a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java index 11607acb2d..b390449714 100644 --- a/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java +++ b/log4j-layout-template-json-test/src/test/java/org/apache/logging/log4j/layout/template/json/util/JsonWriterTest.java @@ -40,6 +40,8 @@ import org.apache.logging.log4j.util.Strings; import org.assertj.core.api.Assertions; import org.assertj.core.api.SoftAssertions; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; @SuppressWarnings({"DoubleBraceInitialization", "UnnecessaryStringBuilder"}) class JsonWriterTest { @@ -606,6 +608,14 @@ class JsonWriterTest { } } + @ParameterizedTest + @ValueSource(floats = {Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY}) + void test_writeNumber_float_non_finite(final float number) { + final String expectedJson = "\"" + number + "\""; + final String actualJson = withLockedWriterReturning(writer -> writer.use(() -> writer.writeNumber(number))); + Assertions.assertThat(actualJson).isEqualTo(expectedJson); + } + @Test void test_writeNumber_float() { for (final float number : new float[] {Float.MIN_VALUE, -1.0F, 0F, 1.0F, Float.MAX_VALUE}) { @@ -615,6 +625,14 @@ class JsonWriterTest { } } + @ParameterizedTest + @ValueSource(doubles = {Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY}) + void test_writeNumber_double_non_finite(final double number) { + final String expectedJson = "\"" + number + "\""; + final String actualJson = withLockedWriterReturning(writer -> writer.use(() -> writer.writeNumber(number))); + Assertions.assertThat(actualJson).isEqualTo(expectedJson); + } + @Test void test_writeNumber_double() { for (final double number : new double[] {Double.MIN_VALUE, -1.0D, 0D, 1.0D, Double.MAX_VALUE}) { diff --git a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java index 749eb1519e..17b1f78bf7 100644 --- a/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java +++ b/log4j-layout-template-json/src/main/java/org/apache/logging/log4j/layout/template/json/util/JsonWriter.java @@ -722,11 +722,21 @@ public final class JsonWriter implements AutoCloseable, Cloneable { } public void writeNumber(final float number) { - stringBuilder.append(number); + // Follows the same logic as Jackson's JsonWriteFeatures#WRITE_NAN_AS_STRINGS feature. + if (!Float.isFinite(number)) { + writeString(Float.toString(number)); + } else { + stringBuilder.append(number); + } } public void writeNumber(final double number) { - stringBuilder.append(number); + // Follows the same logic as Jackson's JsonWriteFeatures#WRITE_NAN_AS_STRINGS feature. + if (!Double.isFinite(number)) { + writeString(Double.toString(number)); + } else { + stringBuilder.append(number); + } } public void writeNumber(final short number) { diff --git a/src/changelog/.2.x.x/jtl-nan.xml b/src/changelog/.2.x.x/jtl-nan.xml new file mode 100644 index 0000000000..126cfc1be3 --- /dev/null +++ b/src/changelog/.2.x.x/jtl-nan.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<entry xmlns="https://logging.apache.org/xml/ns" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation=" + https://logging.apache.org/xml/ns + https://logging.apache.org/xml/ns/log4j-changelog-0.xsd" + type="fixed"> + <description format="asciidoc"> + Write non-finite floating-point numbers as strings in `JsonWriter`. + </description> +</entry>
