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

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-statistics.git


The following commit(s) were added to refs/heads/master by this push:
     new 976c3cc1 STATISTICS-95: Validate mean is finite and variance is 
positive finite
976c3cc1 is described below

commit 976c3cc1ee318199bc1d6687a86943c1e7f079c0
Author: Alex Herbert <[email protected]>
AuthorDate: Thu Aug 27 09:17:14 2026 +0100

    STATISTICS-95: Validate mean is finite and variance is positive finite
---
 .../statistics/interval/NormalConfidenceInterval.java  | 10 +++++++++-
 .../interval/NormalConfidenceIntervalTest.java         | 18 ++++++++++++++++++
 src/changes/changes.xml                                |  3 +++
 3 files changed, 30 insertions(+), 1 deletion(-)

diff --git 
a/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
 
b/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
index 79f4f0bb..ee5b12f9 100644
--- 
a/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
+++ 
b/commons-statistics-interval/src/main/java/org/apache/commons/statistics/interval/NormalConfidenceInterval.java
@@ -72,13 +72,21 @@ public enum NormalConfidenceInterval {
      * @param alpha Desired error rate that the true value falls
      * <em>outside</em> the returned interval.
      * @return Confidence interval containing the target with error rate 
{@code alpha}
-     * @throws IllegalArgumentException if {@code n <= 1}, or if {@code alpha} 
is not in
+     * @throws IllegalArgumentException if {@code n <= 1}; if {@code mean} is 
not finite;
+     * if {@code variance} is not positive and finite; or if {@code alpha} is 
not in
      * the open interval {@code (0, 1)}.
      */
     public Interval fromErrorRate(double mean, double variance, long n, double 
alpha) {
         if (n <= 1) {
             throw new IllegalArgumentException("Sample size is not above one: 
" + n);
         }
+        if (!Double.isFinite(mean)) {
+            throw new IllegalArgumentException("Mean is not finite: " + mean);
+        }
+        if (!(variance >= 0 && variance < Double.POSITIVE_INFINITY)) {
+            // negative, infinite or nan
+            throw new IllegalArgumentException("Variance is not positive and 
finite: " + variance);
+        }
         ArgumentUtils.checkErrorRate(alpha);
         return create(mean, variance, n, alpha);
     }
diff --git 
a/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
 
b/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
index eece3f9a..539d8315 100644
--- 
a/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
+++ 
b/commons-statistics-interval/src/test/java/org/apache/commons/statistics/interval/NormalConfidenceIntervalTest.java
@@ -49,6 +49,21 @@ class NormalConfidenceIntervalTest {
         Assertions.assertThrows(IllegalArgumentException.class, () -> 
method.fromErrorRate(mean, variance, n, -0.01));
         Assertions.assertThrows(IllegalArgumentException.class, () -> 
method.fromErrorRate(mean, variance, n, 1.01));
         Assertions.assertThrows(IllegalArgumentException.class, () -> 
method.fromErrorRate(mean, variance, n, Double.NaN));
+        // mean must be finite
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> method.fromErrorRate(Double.NaN, variance, n, alpha));
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> method.fromErrorRate(Double.POSITIVE_INFINITY, variance, n, 
alpha));
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> method.fromErrorRate(Double.NEGATIVE_INFINITY, variance, n, 
alpha));
+        // variance must be positive and finite
+        Assertions.assertDoesNotThrow(() -> method.fromErrorRate(mean, 0.0, n, 
alpha));
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> method.fromErrorRate(mean, Double.NaN, n, alpha));
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> method.fromErrorRate(mean, Double.POSITIVE_INFINITY, n, 
alpha));
+        Assertions.assertThrows(IllegalArgumentException.class,
+            () -> method.fromErrorRate(mean, -1.0, n, alpha));
     }
 
     @ParameterizedTest
@@ -87,6 +102,9 @@ class NormalConfidenceIntervalTest {
         add(builder, method, 2.9535381946732131, 5.2628380291790835, 50, 0.1, 
3.887312567406342, 7.6002576083181186,
             1e-14);
 
+        // Edge cases of zero variance: the interval should be [0, 0]
+        add(builder, method, 1.23, 0.0, 100, 0.05, 0.0, 0.0, 0.0);
+
         // Approximate formula for asymptotic distributions at large n uses z 
critical value
         // from a normal distribution, here z_{0.025} = 1.96
         final double z = 1.96;
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index bf52d353..c393e874 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -53,6 +53,9 @@ If the output is not quite correct, check for invisible 
trailing spaces!
   </properties>
   <body>
     <release version="1.4" date="TBD" description="Adds new features (requires 
Java 8).">
+      <action dev="aherbert" type="fix" due-to="Security scan, Aex Herbert" 
issue="STATISTICS-95">
+        "NormalConfidenceInterval": Validate mean is finite and variance is 
positive finite.
+      </action>
     </release>
 
     <release version="1.3" date="2026-05-01" description="Adds new features 
(requires Java 8).">

Reply via email to