From e39e2eed0596f74cb0c6a6af50ab7b3b626ce452 Mon Sep 17 00:00:00 2001 From: Kristoffer Carlsson Date: Thu, 23 Jul 2026 21:37:48 +0200 Subject: [PATCH] Fix out-of-bounds access in is_hermsym for stored zeros Co-Authored-By: Claude Fable 5 --- src/sparsematrix.jl | 14 ++++++++++---- test/linalg.jl | 9 +++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/sparsematrix.jl b/src/sparsematrix.jl index 51ff5caf..3ba28bba 100644 --- a/src/sparsematrix.jl +++ b/src/sparsematrix.jl @@ -4128,9 +4128,10 @@ function is_hermsym(A::AbstractSparseMatrixCSC, check::Function) offset = tracker[row] - # If the matrix is unsymmetric, there might not exist - # a rowval[offset] - if offset > length(rowval) + # If the matrix is unsymmetric, the tracker may have moved + # past the last stored entry of column `row`, meaning the + # partner entry A[col, row] does not exist + if offset > colptr[row+1] - 1 return false end @@ -4145,8 +4146,13 @@ function is_hermsym(A::AbstractSparseMatrixCSC, check::Function) return false end offset += 1 - row2 = rowval[offset] tracker[row] += 1 + # Column `row` ran out of stored entries before + # reaching row `col`, so A[col, row] does not exist + if offset > colptr[row+1] - 1 + return false + end + row2 = rowval[offset] end # Non zero A[i,j] exists but A[j,i] does not exist diff --git a/test/linalg.jl b/test/linalg.jl index 758ed3cb..290a4ea4 100644 --- a/test/linalg.jl +++ b/test/linalg.jl @@ -520,6 +520,15 @@ end nonzeros(A)[end - 3] = 2.0 @test issymmetric(A) == false + # stored zeros must not cause out-of-bounds access when the + # partner column runs out of stored entries + A = sparse([3, 1], [2, 3], [1.0, 0.0], 3, 3) + @test issymmetric(A) == false + @test ishermitian(A) == false + A = sparse([1, 2], [2, 1], [0.0, 0.0], 2, 2) + @test issymmetric(A) == true + @test ishermitian(A) == true + # 16521 @test issymmetric(sparse([0 0; 1 0])) == false @test issymmetric(sparse([0 1; 0 0])) == false