diff --git a/stdlib/SparseArrays/src/higherorderfns.jl b/stdlib/SparseArrays/src/higherorderfns.jl index 66ab8b3f60e52..2ab7e3138bcba 100644 --- a/stdlib/SparseArrays/src/higherorderfns.jl +++ b/stdlib/SparseArrays/src/higherorderfns.jl @@ -387,7 +387,7 @@ function _map_zeropres!(f::Tf, C::SparseVecOrMat, As::Vararg{SparseVecOrMat,N}) vals, ks, rows = _fusedupdate_all(rowsentinel, activerow, rows, ks, stopks, As) Cx = f(vals...) if !_iszero(Cx) - Ck > spaceC && (spaceC = expandstorage!(C, Ck + min(length(C), _sumnnzs(As...)) - (sum(ks) - N))) + Ck > spaceC && (spaceC = expandstorage!(C, min(length(C), Ck + _sumnnzs(As...) - (sum(ks) - N)))) storedinds(C)[Ck] = activerow storedvals(C)[Ck] = Cx Ck += 1 diff --git a/stdlib/SparseArrays/test/higherorderfns.jl b/stdlib/SparseArrays/test/higherorderfns.jl index 5d353f431cb38..a50cef0ce52f2 100644 --- a/stdlib/SparseArrays/test/higherorderfns.jl +++ b/stdlib/SparseArrays/test/higherorderfns.jl @@ -671,4 +671,14 @@ end @test w == bv .* op(av) end +@testset "issue #31758: out of bounds write in _map_zeropres!" begin + y = sparsevec([2,7], [1., 2.], 10) + x1 = sparsevec(fill(1.0, 10)) + x2 = sparsevec([2,7], [1., 2.], 10) + x3 = sparsevec(fill(1.0, 10)) + f(x, y, z) = x == y == z == 0 ? 0.0 : NaN + y .= f.(x1, x2, x3) + @test all(isnan, y) +end + end # module