Detail::bootstrap() could index past the end of the resample, as reported in #3214.
If all jackknife estimates are equal, sum_squares is 0 and the acceleration is 0 / 0 = NaN. That makes a1/a2 NaN, std::lround(NaN) returns LONG_MIN, and since hi was only clamped from above it becomes a huge size_t. On Linux with a 64-bit long the index times sizeof(double) wraps around to resample[0], so the upper bound silently comes out below the point estimate; with a 32-bit long (MinGW, as in the issue) it is a real out-of-bounds read and crashes. The same thing happens when every resampled estimate is below the point estimate and the acceleration is non-zero, because bias is then infinite and a(b) turns into inf/inf.
Changes:
- zero jackknife variance now means zero acceleration instead of NaN
- both indices are clamped to [0, n - 1]; if the adjusted quantile is still NaN, lo falls back to 0 and hi to n - 1
Added a test case to InternalBenchmark.tests.cpp that calls bootstrap() with both inputs. Before the change it fails with upper_bound 22.0 == 24 and 0.5 == 2 (the wrapped-around resample[0]); with it, it passes. Approval baselines are updated for the new test case, and the full ctest run passes on Linux (GCC 14).
Codecov Report
:white_check_mark: All modified and coverable lines are covered by tests. :white_check_mark: Project coverage is 91.42%. Comparing base (
0809213) to head (bb06231).Additional details and impacted files
:rocket: New features to boost your workflow: