This is an automated email from the ASF dual-hosted git repository.
junrushao pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm-ffi.git
The following commit(s) were added to refs/heads/main by this push:
new ec56178 fix: add negative index bounds check in ArrayObj (#376)
ec56178 is described below
commit ec56178e587a5ca585fecac60823b8e55fa267d7
Author: Guan-Ming (Wesley) Chiu <[email protected]>
AuthorDate: Sat Jan 3 07:39:03 2026 +0800
fix: add negative index bounds check in ArrayObj (#376)
## Why
`ArrayObj::operator[]` and `ArrayObj::SetItem` were missing negative
index validation, causing undefined behavior when accessing arrays with
negative indices.
## How
- Add `i < 0` check to `ArrayObj::operator[]` and `ArrayObj::SetItem`
bounds validation
- Add test case
---
include/tvm/ffi/container/array.h | 4 ++--
tests/cpp/test_array.cc | 31 +++++++++++++++++++++++++++++++
2 files changed, 33 insertions(+), 2 deletions(-)
diff --git a/include/tvm/ffi/container/array.h
b/include/tvm/ffi/container/array.h
index 60fa6fe..32c1a22 100644
--- a/include/tvm/ffi/container/array.h
+++ b/include/tvm/ffi/container/array.h
@@ -70,7 +70,7 @@ class ArrayObj : public Object, public
details::InplaceArrayBase<ArrayObj, TVMFF
* \return the i-th element.
*/
const Any& operator[](int64_t i) const {
- if (i >= size_) {
+ if (i < 0 || i >= size_) {
TVM_FFI_THROW(IndexError) << "Index " << i << " out of bounds " << size_;
}
return static_cast<Any*>(data_)[i];
@@ -91,7 +91,7 @@ class ArrayObj : public Object, public
details::InplaceArrayBase<ArrayObj, TVMFF
* \param item The value to be set
*/
void SetItem(int64_t i, Any item) {
- if (i >= size_) {
+ if (i < 0 || i >= size_) {
TVM_FFI_THROW(IndexError) << "Index " << i << " out of bounds " << size_;
}
static_cast<Any*>(data_)[i] = std::move(item);
diff --git a/tests/cpp/test_array.cc b/tests/cpp/test_array.cc
index a86cc29..b7d1fa3 100644
--- a/tests/cpp/test_array.cc
+++ b/tests/cpp/test_array.cc
@@ -312,4 +312,35 @@ TEST(Array, Contains) {
EXPECT_FALSE(f(str_arr, String("foo")).cast<bool>());
}
+TEST(Array, NegativeIndexThrows) {
+ Array<int> arr = {1, 2, 3};
+ // Directly test ArrayObj methods, which are the ones modified in this PR.
+ // The Array<T> wrapper methods already had negative index checks.
+ ArrayObj* arr_obj = arr.GetArrayObj();
+
+ // Test ArrayObj::at (which calls operator[])
+ EXPECT_THROW(
+ {
+ try {
+ [[maybe_unused]] const auto& val = arr_obj->at(-1);
+ } catch (const Error& error) {
+ EXPECT_EQ(error.kind(), "IndexError");
+ throw;
+ }
+ },
+ ::tvm::ffi::Error);
+
+ // Test ArrayObj::SetItem
+ EXPECT_THROW(
+ {
+ try {
+ arr_obj->SetItem(-1, Any(42));
+ } catch (const Error& error) {
+ EXPECT_EQ(error.kind(), "IndexError");
+ throw;
+ }
+ },
+ ::tvm::ffi::Error);
+}
+
} // namespace