Skip to content

Commit 77bda5c

Browse files
rootroot
authored andcommitted
Added bounds check in ColumnVector::insert_indices_from()
1 parent a3d1080 commit 77bda5c

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed

be/src/vec/columns/column_vector.cpp

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,19 +279,35 @@ void ColumnVector<T>::insert_range_from(const IColumn& src, size_t start, size_t
279279
template <PrimitiveType T>
280280
void ColumnVector<T>::insert_indices_from(const IColumn& src, const uint32_t* indices_begin,
281281
const uint32_t* indices_end) {
282+
const auto& src_concrete = static_cast<const ColumnVector<T>&>(src);
283+
size_t src_size = src_concrete.size();
284+
if (indices_begin == nullptr || indices_end == nullptr || indices_begin > indices_end) {
285+
throw Exception(ErrorCode::INTERNAL_ERROR,
286+
"Invalid index range: begin={}, end={}",
287+
static_cast<const void*>(indices_begin),
288+
static_cast<const void*>(indices_end));
289+
}
290+
282291
auto origin_size = size();
283292
auto new_size = indices_end - indices_begin;
293+
if (new_size == 0) {
294+
return;
295+
}
284296
data.resize(origin_size + new_size);
285297

286298
auto copy = [](const value_type* __restrict src, value_type* __restrict dest,
287-
const uint32_t* __restrict begin, const uint32_t* __restrict end) {
299+
const uint32_t* __restrict begin, const uint32_t* __restrict end, size_t src_size) {
288300
for (const auto* it = begin; it != end; ++it) {
301+
if (*it >= src_size) {
302+
throw Exception(ErrorCode::INTERNAL_ERROR,
303+
"Index {} exceeds source column size {}", *it, src_size);
304+
}
289305
*dest = src[*it];
290306
++dest;
291307
}
292308
};
293309
copy(reinterpret_cast<const value_type*>(src.get_raw_data().data), data.data() + origin_size,
294-
indices_begin, indices_end);
310+
indices_begin, indices_end, src_size);
295311
}
296312

297313
template <PrimitiveType T>

be/test/vec/core/column_vector_test.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
#include <string>
2525

2626
#include "gtest/gtest_pred_impl.h"
27+
#include "vec/core/types.h"
28+
#include "vec/data_types/data_type_number.h"
2729

2830
namespace doris::vectorized {
2931

@@ -38,4 +40,36 @@ TEST(VColumnVectorTest, insert_date_column) {
3840
ASSERT_EQ(column->size(), rows);
3941
}
4042

43+
TEST(VColumnVectorTest, insert_indices_from_uInt64_crash) {
44+
auto src = ColumnInt64::create();
45+
std::vector<int64_t> src_values = {10LL, 20LL, 30LL, 40LL};
46+
for (auto v : src_values) {
47+
src->insert(Field::create_field<PrimitiveType::TYPE_BIGINT>(v));
48+
}
49+
ASSERT_EQ(src->size(), 4);
50+
51+
auto dest = ColumnInt64::create();
52+
std::vector<int64_t> dest_values = {1LL, 2LL};
53+
for (auto v : dest_values) {
54+
dest->insert(Field::create_field<PrimitiveType::TYPE_BIGINT>(v));
55+
}
56+
57+
// Valid indices (should work)
58+
uint32_t valid_indices[] = {0, 2, 3};
59+
dest->insert_indices_from(*src, valid_indices, valid_indices + 3);
60+
ASSERT_EQ(dest->size(), 5); // 2 original + 3 inserted
61+
ASSERT_EQ(dest->get_int(2), 10LL); // Check inserted value
62+
63+
// Invalid indices to trigger crash
64+
uint32_t invalid_indices[] = {0, 2, 1000000000U, 2000000000U}; // Large indices to hit unmapped memory (src size = 4)
65+
try {
66+
dest->insert_indices_from(*src, invalid_indices, invalid_indices + 4);
67+
FAIL() << "Expected Exception for out-of-bounds indices";
68+
} catch (const Exception& e) {
69+
ASSERT_EQ(e.code(), ErrorCode::INTERNAL_ERROR);
70+
ASSERT_TRUE(std::string(e.to_string()).find("Index 1000000000 exceeds source column size 4") !=
71+
std::string::npos);
72+
}
73+
}
74+
4175
} // namespace doris::vectorized

0 commit comments

Comments
 (0)