From 5528094bf79a2917adeacd1606a52614bd5dcbfa Mon Sep 17 00:00:00 2001 From: eldenmoon <15605149486@163.com> Date: Thu, 26 Sep 2024 13:50:20 +0800 Subject: [PATCH] [Fix](Serde) fix potential mem leak in array serde write_one_cell_to_json placement new may lead to mem leak in Field without calling it's desctructor related PR #40573 --- .../serde/data_type_array_serde.cpp | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/be/src/vec/data_types/serde/data_type_array_serde.cpp b/be/src/vec/data_types/serde/data_type_array_serde.cpp index e8eea4affe74a0..7828ecd4c696eb 100644 --- a/be/src/vec/data_types/serde/data_type_array_serde.cpp +++ b/be/src/vec/data_types/serde/data_type_array_serde.cpp @@ -229,20 +229,24 @@ void DataTypeArraySerDe::write_one_cell_to_jsonb(const IColumn& column, JsonbWri Status DataTypeArraySerDe::write_one_cell_to_json(const IColumn& column, rapidjson::Value& result, rapidjson::Document::AllocatorType& allocator, Arena& mem_pool, int row_num) const { - // Use allocator instead of stack memory, since rapidjson hold the reference of String value - // otherwise causes stack use after free - auto& column_array = static_cast(column); - if (row_num > column_array.size()) { - return Status::InternalError("row num {} out of range {}!", row_num, column_array.size()); - } - // void* mem = allocator.Malloc(sizeof(vectorized::Field)); - void* mem = mem_pool.alloc(sizeof(vectorized::Field)); - if (!mem) { - return Status::InternalError("Malloc failed"); - } - vectorized::Field* array = new (mem) vectorized::Field(column_array[row_num]); + auto res = check_column_const_set_readability(column, row_num); + ColumnPtr ptr = res.first; + row_num = res.second; + + const auto& data_column = assert_cast(*ptr); + const auto& offsets = data_column.get_offsets(); + + size_t offset = offsets[row_num - 1]; + size_t next_offset = offsets[row_num]; - convert_field_to_rapidjson(*array, result, allocator); + const IColumn& nested_column = data_column.get_data(); + result.SetArray(); + for (size_t i = offset; i < next_offset; ++i) { + rapidjson::Value val; + RETURN_IF_ERROR( + nested_serde->write_one_cell_to_json(nested_column, val, allocator, mem_pool, i)); + result.PushBack(val, allocator); + } return Status::OK(); }