From c2f3ab6082e2e193c2a52e0eb4a95d7a26c297d3 Mon Sep 17 00:00:00 2001 From: jmestwa-coder Date: Mon, 25 May 2026 23:17:06 +0530 Subject: [PATCH] avoid int64 overflow in sparse CSX index bounds checks --- cpp/src/arrow/ipc/reader.cc | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/cpp/src/arrow/ipc/reader.cc b/cpp/src/arrow/ipc/reader.cc index 512305d6570..479dfc83a2b 100644 --- a/cpp/src/arrow/ipc/reader.cc +++ b/cpp/src/arrow/ipc/reader.cc @@ -79,6 +79,7 @@ namespace flatbuf = org::apache::arrow::flatbuf; using internal::AddWithOverflow; using internal::checked_cast; using internal::checked_pointer_cast; +using internal::MultiplyWithOverflow; namespace ipc { @@ -2336,16 +2337,24 @@ Result> ReadSparseCSXIndex( /*allow_short_read=*/false)); std::vector indices_shape({non_zero_length}); - const auto indices_minimum_bytes = indices_shape[0] * indices_type->byte_width(); - if (indices_minimum_bytes > indices_buffer->length()) { + const auto indices_minimum_bytes = + MultiplyWithOverflow({indices_shape[0], indices_type->byte_width()}); + if (!indices_minimum_bytes.has_value() || + indices_minimum_bytes.value() > indices_buffer->length()) { return Status::Invalid("shape is inconsistent to the size of indices buffer"); } switch (sparse_index->compressedAxis()) { case flatbuf::SparseMatrixCompressedAxis::SparseMatrixCompressedAxis_Row: { - std::vector indptr_shape({shape[0] + 1}); - const int64_t indptr_minimum_bytes = indptr_shape[0] * indptr_byte_width; - if (indptr_minimum_bytes > indptr_buffer->length()) { + const auto indptr_length = AddWithOverflow({shape[0], 1}); + if (!indptr_length.has_value()) { + return Status::Invalid("shape is inconsistent to the size of indptr buffer"); + } + std::vector indptr_shape({indptr_length.value()}); + const auto indptr_minimum_bytes = + MultiplyWithOverflow({indptr_shape[0], indptr_byte_width}); + if (!indptr_minimum_bytes.has_value() || + indptr_minimum_bytes.value() > indptr_buffer->length()) { return Status::Invalid("shape is inconsistent to the size of indptr buffer"); } return std::make_shared( @@ -2353,9 +2362,15 @@ Result> ReadSparseCSXIndex( std::make_shared(indices_type, indices_data, indices_shape)); } case flatbuf::SparseMatrixCompressedAxis::SparseMatrixCompressedAxis_Column: { - std::vector indptr_shape({shape[1] + 1}); - const int64_t indptr_minimum_bytes = indptr_shape[0] * indptr_byte_width; - if (indptr_minimum_bytes > indptr_buffer->length()) { + const auto indptr_length = AddWithOverflow({shape[1], 1}); + if (!indptr_length.has_value()) { + return Status::Invalid("shape is inconsistent to the size of indptr buffer"); + } + std::vector indptr_shape({indptr_length.value()}); + const auto indptr_minimum_bytes = + MultiplyWithOverflow({indptr_shape[0], indptr_byte_width}); + if (!indptr_minimum_bytes.has_value() || + indptr_minimum_bytes.value() > indptr_buffer->length()) { return Status::Invalid("shape is inconsistent to the size of indptr buffer"); } return std::make_shared(