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

Reply via email to