From af3bde3266d23751a6b50879e0f7126c731395d5 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Mon, 8 Jun 2026 15:02:49 +0530 Subject: [PATCH 1/2] fix off-by-one rejecting trailing nan/infinity in parseNumber --- .../math4/legacy/util/CompositeFormat.java | 2 +- .../legacy/util/ComplexFormatAbstractTest.java | 16 ++++++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/util/CompositeFormat.java b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/util/CompositeFormat.java index 1390dc1a16..333496529c 100644 --- a/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/util/CompositeFormat.java +++ b/commons-math-legacy/src/main/java/org/apache/commons/math4/legacy/util/CompositeFormat.java @@ -117,7 +117,7 @@ private static Number parseNumber(final String source, final double value, final int n = sb.length(); final int startIndex = pos.getIndex(); final int endIndex = startIndex + n; - if (endIndex < source.length() && + if (endIndex <= source.length() && source.substring(startIndex, endIndex).compareTo(sb.toString()) == 0) { ret = Double.valueOf(value); pos.setIndex(endIndex); diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java index a421348d6f..c67d6b0852 100644 --- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java +++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java @@ -277,6 +277,22 @@ public void testPaseNegativeInfinity() { Assert.assertEquals(expected, actual); } + @Test + public void testParseRealNan() { + // a real-only special value runs to the last character of the string + Complex expected = Complex.ofCartesian(Double.NaN, 0); + Assert.assertEquals(expected, complexFormat.parse("(NaN)")); + Assert.assertEquals(expected, complexFormat.parse(complexFormat.format(expected))); + } + + @Test + public void testParseRealInfinity() { + Complex positive = Complex.ofCartesian(Double.POSITIVE_INFINITY, 0); + Assert.assertEquals(positive, complexFormat.parse("(Infinity)")); + Complex negative = Complex.ofCartesian(Double.NEGATIVE_INFINITY, 0); + Assert.assertEquals(negative, complexFormat.parse("(-Infinity)")); + } + @Test public void testConstructorSingleFormat() { NumberFormat nf = NumberFormat.getInstance(); From e0bee2b919a5e9f5779f7ffc8835297e65abd194 Mon Sep 17 00:00:00 2001 From: dxbjavid Date: Tue, 9 Jun 2026 16:44:11 +0530 Subject: [PATCH 2/2] add round-trip and imaginary-part special value parse tests --- .../legacy/util/ComplexFormatAbstractTest.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java index c67d6b0852..d483982dbe 100644 --- a/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java +++ b/commons-math-legacy/src/test/java/org/apache/commons/math4/legacy/util/ComplexFormatAbstractTest.java @@ -289,8 +289,21 @@ public void testParseRealNan() { public void testParseRealInfinity() { Complex positive = Complex.ofCartesian(Double.POSITIVE_INFINITY, 0); Assert.assertEquals(positive, complexFormat.parse("(Infinity)")); + Assert.assertEquals(positive, complexFormat.parse(complexFormat.format(positive))); Complex negative = Complex.ofCartesian(Double.NEGATIVE_INFINITY, 0); Assert.assertEquals(negative, complexFormat.parse("(-Infinity)")); + Assert.assertEquals(negative, complexFormat.parse(complexFormat.format(negative))); + } + + @Test + public void testParseImaginarySpecialValue() { + // the special value sits in the imaginary part, ahead of the imaginary character + Complex nan = Complex.ofCartesian(1.23, Double.NaN); + Assert.assertEquals(nan, complexFormat.parse(complexFormat.format(nan))); + Complex positive = Complex.ofCartesian(1.23, Double.POSITIVE_INFINITY); + Assert.assertEquals(positive, complexFormat.parse(complexFormat.format(positive))); + Complex negative = Complex.ofCartesian(1.23, Double.NEGATIVE_INFINITY); + Assert.assertEquals(negative, complexFormat.parse(complexFormat.format(negative))); } @Test