From adfecf6cc04fd4de5f0f53769509ffbdfc82276f Mon Sep 17 00:00:00 2001 From: Nayana Naik Date: Wed, 21 Oct 2026 16:11:09 +0530 Subject: [PATCH] validate union type_id range in ArrayFromJSONString --- cpp/src/arrow/json/from_string.cc | 8 +++++--- cpp/src/arrow/json/from_string_test.cc | 7 +++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/cpp/src/arrow/json/from_string.cc b/cpp/src/arrow/json/from_string.cc index f573ae710651..a74d1a3377e2 100644 --- a/cpp/src/arrow/json/from_string.cc +++ b/cpp/src/arrow/json/from_string.cc @@ -868,11 +868,13 @@ class UnionConverter final : public ConcreteConverter { array, "[type_id, value] pair", {[this, &id, &child_converter](sj::value& id_elem) { ARROW_ASSIGN_OR_RAISE(auto id_value, internal::GetJsonAs(id_elem)); + if (id_value < 0 || + id_value >= static_cast(type_id_to_child_num_.size()) || + type_id_to_child_num_[id_value] == -1) { + return Status::Invalid("type_id ", id_value, " not found in ", *type_); + } id = static_cast(id_value); auto child_num = type_id_to_child_num_[id]; - if (child_num == -1) { - return Status::Invalid("type_id ", id, " not found in ", *type_); - } child_converter = child_converters_[child_num]; if (mode_ == UnionMode::SPARSE) { diff --git a/cpp/src/arrow/json/from_string_test.cc b/cpp/src/arrow/json/from_string_test.cc index 817cfe52ee72..b0d57e9ed796 100644 --- a/cpp/src/arrow/json/from_string_test.cc +++ b/cpp/src/arrow/json/from_string_test.cc @@ -1448,6 +1448,10 @@ TEST(TestDenseUnionFromString, Errors) { ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a valid type_id\"]")); ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0, 99]]")); // 0 is not one of {4, 8} + // Out of range type_ids, including one that truncates to 4 as int8 + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[-1, 99]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[100, 99]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[260, 99]]")); ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[4, \"\"]]")); // "" is not a valid int8() @@ -1464,6 +1468,9 @@ TEST(TestSparseUnionFromString, Errors) { ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a valid type_id\"]")); ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0, 99]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[-1, 99]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[100, 99]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[260, 99]]")); ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[4, \"\"]]")); ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a pair\"]"));