From 5bacb5be9a68fb56511283b7efbf1a7c06b30206 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Antonio=20S=C3=A1nchez?= Date: Fri, 6 Mar 2026 18:50:28 +0000 Subject: [PATCH] Fix null pointer dereference in Sparse-Dense products for Sparse vectors. libeigen/eigen!2256 --- Eigen/src/SparseCore/SparseDenseProduct.h | 38 ++++++++++++++--------- test/sparse_product.cpp | 12 +++++++ 2 files changed, 36 insertions(+), 14 deletions(-) diff --git a/Eigen/src/SparseCore/SparseDenseProduct.h b/Eigen/src/SparseCore/SparseDenseProduct.h index 98f81dd5e..75127937c 100644 --- a/Eigen/src/SparseCore/SparseDenseProduct.h +++ b/Eigen/src/SparseCore/SparseDenseProduct.h @@ -70,6 +70,7 @@ struct sparse_time_dense_product_impl 1 && mat.nonZeros() > 20000) { #pragma omp parallel for schedule(dynamic, (n + threads * 4 - 1) / (threads * 4)) num_threads(threads) for (Index i = 0; i < n; ++i) { - Index k = outer[i]; - const Index end = innerNnz ? outer[i] + innerNnz[i] : outer[i + 1]; + Index k = outer ? outer[i] : 0; + const Index end = innerNnz ? (outer ? outer[i] : 0) + innerNnz[i] + : (outer ? outer[i + 1] : mat.nonZeros()); ResScalar sum0(0), sum1(0); for (; k < end; ++k) { sum0 += vals[k] * x[inds[k]]; @@ -96,8 +98,9 @@ struct sparse_time_dense_product_impl::ReturnType rhs_j(alpha * rhs.coeff(j, c)); - const Index start = outer[j]; - const Index end = innerNnz ? outer[j] + innerNnz[j] : outer[j + 1]; + const Index start = outer ? outer[j] : 0; + const Index end = innerNnz ? start + innerNnz[j] : (outer ? outer[j + 1] : mat.nonZeros()); Index k = start; // 4-way unrolled scatter-add (no SIMD: writes are scattered) for (; k + 3 < end; k += 4) { @@ -218,8 +223,8 @@ struct sparse_time_dense_product_impl::ReturnType rhs_j(alpha * rhs.coeff(j, c)); - const Index start = outer[j]; - const Index end = innerNnz ? outer[j] + innerNnz[j] : outer[j + 1]; + const Index start = outer ? outer[j] : 0; + const Index end = innerNnz ? start + innerNnz[j] : (outer ? outer[j + 1] : mat.nonZeros()); for (Index k = start; k < end; ++k) res.coeffRef(inds[k], c) += vals[k] * rhs_j; } } @@ -280,9 +285,13 @@ struct sparse_time_dense_product_impl(); } +void test_sparse_vector_dense_product() { + SparseVector sv(3); + sv.insert(0) = 1.0; + sv.insert(2) = 2.0; + + MatrixXd dm = MatrixXd::Random(3, 2); + MatrixXd res = sv.transpose() * dm; + MatrixXd ref = MatrixXd(sv).transpose() * dm; + VERIFY_IS_APPROX(res, ref); +} + EIGEN_DECLARE_TEST(sparse_product) { for (int i = 0; i < g_repeat; i++) { + CALL_SUBTEST_1((test_sparse_vector_dense_product())); CALL_SUBTEST_1((sparse_product >())); CALL_SUBTEST_1((sparse_product >())); CALL_SUBTEST_1((bug_942()));