From 303a877aa8574d8e689f82599fa81c3c6c64b40d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=99=88=E9=82=A3=E5=87=A0?= <2078634206@qq.com> Date: Wed, 30 Sep 2026 13:03:30 +0800 Subject: [PATCH] fix(utils): handle allocation failure in RingBuffer::create MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit create() is noexcept but its vector allocation can throw length_error/bad_alloc, terminating the process; reject capacities above vector::max_size() up front and convert remaining allocation errors into the empty optional the API already uses for failure; add a unit test. Signed-off-by: 陈那几 <2078634206@qq.com> --- .../tests/ll-tests/src/linglong/utils/io_test.cpp | 10 ++++++++++ libs/utils/src/linglong/utils/io/ring_buffer.h | 12 ++++++++++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/libs/linglong/tests/ll-tests/src/linglong/utils/io_test.cpp b/libs/linglong/tests/ll-tests/src/linglong/utils/io_test.cpp index 3e3216e4e..e1ae59c14 100644 --- a/libs/linglong/tests/ll-tests/src/linglong/utils/io_test.cpp +++ b/libs/linglong/tests/ll-tests/src/linglong/utils/io_test.cpp @@ -15,6 +15,8 @@ #include "linglong/utils/unique_fd.h" #include +#include +#include #include #include @@ -259,6 +261,14 @@ TEST(RingBuffer, ClearResetsState) EXPECT_EQ(buf->size(), 0); } +TEST(RingBuffer, CreateRejectsOversizedCapacity) +{ + // A power-of-two capacity beyond vector::max_size() must be reported via + // the empty optional instead of escaping the noexcept boundary. + auto oversized = std::size_t{ 1 } << (sizeof(std::size_t) * CHAR_BIT - 1); + EXPECT_FALSE(RingBuffer::create(oversized).has_value()); +} + TEST(EventLoop, CreateAndWaitTimeout) { auto loop = EventLoop::create(); diff --git a/libs/utils/src/linglong/utils/io/ring_buffer.h b/libs/utils/src/linglong/utils/io/ring_buffer.h index 95c265aae..2d2113086 100644 --- a/libs/utils/src/linglong/utils/io/ring_buffer.h +++ b/libs/utils/src/linglong/utils/io/ring_buffer.h @@ -31,8 +31,16 @@ class alignas(hardware_constructive_interference_size) RingBuffer return std::nullopt; } - std::vector data(cap); - return RingBuffer{ std::move(data), cap - 1 }; + if (cap > std::vector().max_size()) { + return std::nullopt; + } + + try { + std::vector data(cap); + return RingBuffer{ std::move(data), cap - 1 }; + } catch (...) { + return std::nullopt; + } } RingBuffer(const RingBuffer &) = delete;