diff --git a/cpp/src/arrow/array/array_binary_test.cc b/cpp/src/arrow/array/array_binary_test.cc index 70245906f84..d0cc2c77096 100644 --- a/cpp/src/arrow/array/array_binary_test.cc +++ b/cpp/src/arrow/array/array_binary_test.cc @@ -946,6 +946,29 @@ TEST_F(TestChunkedBinaryBuilder, LargeElementCount) { } } +TEST(TestBinaryBuilder, LARGE_MEMORY_TEST(AppendOverflow)) { + const std::string value(static_cast(1) << 31, 'x'); + + BinaryBuilder builder; + ASSERT_RAISES(CapacityError, builder.Append(std::string_view(value))); + ASSERT_OK(builder.Append("x")); + ASSERT_RAISES(CapacityError, builder.ExtendCurrent(std::string_view(value))); + ASSERT_OK_AND_ASSIGN(auto array, builder.Finish()); + ASSERT_OK(array->ValidateFull()); + ASSERT_EQ(1, array->length()); +} + +TEST_F(TestChunkedBinaryBuilder, LARGE_MEMORY_TEST(AppendOverflow)) { + Init(100); + const std::string value(static_cast(1) << 31, 'x'); + + ASSERT_RAISES(CapacityError, builder_->Append(std::string_view(value))); + ArrayVector chunks; + ASSERT_OK(builder_->Finish(&chunks)); + ASSERT_EQ(1, chunks.size()); + ASSERT_EQ(0, chunks[0]->length()); +} + TEST(TestChunkedStringBuilder, BasicOperation) { const int chunksize = 100; internal::ChunkedStringBuilder builder(chunksize); diff --git a/cpp/src/arrow/array/builder_binary.h b/cpp/src/arrow/array/builder_binary.h index d0e761ae968..12f7e45f342 100644 --- a/cpp/src/arrow/array/builder_binary.h +++ b/cpp/src/arrow/array/builder_binary.h @@ -84,6 +84,7 @@ class BaseBinaryBuilder } Status Append(std::string_view value) { + ARROW_RETURN_NOT_OK(ValidateOverflow(static_cast(value.size()))); return Append(value.data(), static_cast(value.size())); } @@ -100,6 +101,7 @@ class BaseBinaryBuilder } Status ExtendCurrent(std::string_view value) { + ARROW_RETURN_NOT_OK(ValidateOverflow(static_cast(value.size()))); return ExtendCurrent(reinterpret_cast(value.data()), static_cast(value.size())); } @@ -949,6 +951,12 @@ class ARROW_EXPORT ChunkedBinaryBuilder { } Status Append(std::string_view value) { + if (ARROW_PREDICT_FALSE(value.size() > + static_cast(BinaryBuilder::memory_limit()))) { + return Status::CapacityError("array cannot contain more than ", + BinaryBuilder::memory_limit(), " bytes, have ", + value.size()); + } return Append(reinterpret_cast(value.data()), static_cast(value.size())); }