You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by vy...@apache.org on 2026/06/29 06:00:25 UTC

(logging-log4j2) branch MapMessage-JSON-non-finite-number created (now 254393920a)

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

vy pushed a change to branch MapMessage-JSON-non-finite-number
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git


      at 254393920a Fix handling of non-finite numbers while encoding `MapMessage` to JSON

This branch includes the following new commits:

     new 254393920a Fix handling of non-finite numbers while encoding `MapMessage` to JSON

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



(logging-log4j2) 01/01: Fix handling of non-finite numbers while encoding `MapMessage` to JSON

Posted by vy...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

vy pushed a commit to branch MapMessage-JSON-non-finite-number
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git

commit 254393920a287c40d886605e234beb31ca2e1e8a
Author: Volkan Yazıcı <vo...@yazi.ci>
AuthorDate: Tue Jun 2 09:13:38 2026 +0200

    Fix handling of non-finite numbers while encoding `MapMessage` to JSON
---
 .../logging/log4j/message/MapMessageTest.java      | 26 +++++++++++++++++++
 .../log4j/message/MapMessageJsonFormatter.java     | 30 +++++++++++++++++-----
 .../fix-MapMessage-JSON-non-finite-number.xml      | 12 +++++++++
 3 files changed, 62 insertions(+), 6 deletions(-)

diff --git a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
index db29a18949..1b45f7b8a0 100644
--- a/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
+++ b/log4j-api-test/src/test/java/org/apache/logging/log4j/message/MapMessageTest.java
@@ -32,6 +32,8 @@ import java.util.Map;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.logging.log4j.util.StringBuilderFormattable;
 import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
 
 /**
  *
@@ -171,6 +173,30 @@ class MapMessageTest {
         assertEquals(expectedJson, actualJson);
     }
 
+    @ParameterizedTest
+    @ValueSource(doubles = {Double.NEGATIVE_INFINITY, Double.NaN, Double.POSITIVE_INFINITY})
+    void testJsonFormatterDoubleNonFiniteSupport(final double number) {
+        final String expectedJson = String.format("{'number':'%s','numbers':['%s']}", number, number)
+                .replace('\'', '"');
+        final String actualJson = new ObjectMapMessage()
+                .with("number", number)
+                .with("numbers", new double[] {number})
+                .getFormattedMessage(new String[] {"JSON"});
+        assertEquals(expectedJson, actualJson);
+    }
+
+    @ParameterizedTest
+    @ValueSource(floats = {Float.NEGATIVE_INFINITY, Float.NaN, Float.POSITIVE_INFINITY})
+    void testJsonFormatterFloatNonFiniteSupport(final float number) {
+        final String expectedJson = String.format("{'number':'%s','numbers':['%s']}", number, number)
+                .replace('\'', '"');
+        final String actualJson = new ObjectMapMessage()
+                .with("number", number)
+                .with("numbers", new float[] {number})
+                .getFormattedMessage(new String[] {"JSON"});
+        assertEquals(expectedJson, actualJson);
+    }
+
     @Test
     void testJsonFormatterInfiniteRecursionPrevention() {
         final List<Object> recursiveValue = Arrays.asList(1, null);
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
index c5e5127f53..a309107471 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/message/MapMessageJsonFormatter.java
@@ -233,13 +233,13 @@ enum MapMessageJsonFormatter {
     private static void formatNumber(final StringBuilder sb, final Number number) {
         if (number instanceof BigDecimal) {
             final BigDecimal decimalNumber = (BigDecimal) number;
-            sb.append(decimalNumber.toString());
+            sb.append(decimalNumber);
         } else if (number instanceof Double) {
             final double doubleNumber = (Double) number;
-            sb.append(doubleNumber);
+            formatDouble(sb, doubleNumber);
         } else if (number instanceof Float) {
             final float floatNumber = (float) number;
-            sb.append(floatNumber);
+            formatFloat(sb, floatNumber);
         } else if (number instanceof Byte
                 || number instanceof Short
                 || number instanceof Integer
@@ -252,11 +252,29 @@ enum MapMessageJsonFormatter {
             if (Double.compare((double) longNumber, doubleValue) == 0) {
                 sb.append(longNumber);
             } else {
-                sb.append(doubleValue);
+                formatDouble(sb, doubleValue);
             }
         }
     }
 
+    private static void formatDouble(StringBuilder sb, double doubleNumber) {
+        // Follows the same logic as Jackson's JsonWriteFeature#WRITE_NAN_AS_STRINGS feature.
+        if (!Double.isFinite(doubleNumber)) {
+            formatString(sb, Double.toString(doubleNumber));
+        } else {
+            sb.append(doubleNumber);
+        }
+    }
+
+    private static void formatFloat(StringBuilder sb, float floatNumber) {
+        // Follows the same logic as Jackson's JsonWriteFeature#WRITE_NAN_AS_STRINGS feature.
+        if (!Float.isFinite(floatNumber)) {
+            formatString(sb, Float.toString(floatNumber));
+        } else {
+            sb.append(floatNumber);
+        }
+    }
+
     private static void formatBoolean(final StringBuilder sb, final boolean booleanValue) {
         sb.append(booleanValue);
     }
@@ -352,7 +370,7 @@ enum MapMessageJsonFormatter {
                 sb.append(COMMA);
             }
             final float item = items[itemIndex];
-            sb.append(item);
+            formatFloat(sb, item);
         }
         sb.append(RBRACE);
     }
@@ -364,7 +382,7 @@ enum MapMessageJsonFormatter {
                 sb.append(COMMA);
             }
             final double item = items[itemIndex];
-            sb.append(item);
+            formatDouble(sb, item);
         }
         sb.append(RBRACE);
     }
diff --git a/src/changelog/.2.x.x/fix-MapMessage-JSON-non-finite-number.xml b/src/changelog/.2.x.x/fix-MapMessage-JSON-non-finite-number.xml
new file mode 100644
index 0000000000..177291e651
--- /dev/null
+++ b/src/changelog/.2.x.x/fix-MapMessage-JSON-non-finite-number.xml
@@ -0,0 +1,12 @@
+<?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">
+  <issue id="TBD" link="https://github.com/apache/logging-log4j2/pull/TBD"/>
+  <description format="asciidoc">
+    Fix handling of non-finite numbers while encoding `MapMessage` to JSON
+  </description>
+</entry>