From b35070f7886d79fd91025cdf063f6dac6f184db6 Mon Sep 17 00:00:00 2001 From: Syping Date: Sun, 29 Mar 2026 09:29:09 +0200 Subject: [PATCH] http_headers: improve memory management --- src/core/http_headers.cpp | 53 +++++++++++++++++++++++++++++++++++++-- src/core/http_headers.h | 4 +++ 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/core/http_headers.cpp b/src/core/http_headers.cpp index 632b518..c118d1f 100644 --- a/src/core/http_headers.cpp +++ b/src/core/http_headers.cpp @@ -23,6 +23,10 @@ http_headers::http_headers() { instance = nullptr; } +http_headers::http_headers(const http_headers &headers) { + instance = copy_from(headers.data()); +} + http_headers::http_headers(const std::string &field, const std::string &value) { instance = nullptr; add(field, value); @@ -35,18 +39,50 @@ http_headers::http_headers(const http_header &header) { http_headers::http_headers(const std::initializer_list &headers) { instance = nullptr; - add(headers); + try { + add(headers); + } + catch (const std::bad_alloc &exception) { + curl_slist_free_all(instance); + throw; + } } http_headers::http_headers(const std::vector &headers) { instance = nullptr; - add(headers); + try { + add(headers); + } + catch (const std::bad_alloc &exception) { + curl_slist_free_all(instance); + throw; + } } http_headers::~http_headers() { curl_slist_free_all(instance); } +http_headers& http_headers::operator=(const curl_slist *other) { + if (this->data() == other) + return *this; + if (curl_slist *headers = copy_from(other)) { + curl_slist_free_all(instance); + instance = headers; + } + return *this; +} + +http_headers& http_headers::operator=(const http_headers &other) { + if (this == &other) + return *this; + if (curl_slist *headers = copy_from(other.data())) { + curl_slist_free_all(instance); + instance = headers; + } + return *this; +} + void http_headers::add(const std::string &field, const std::string &value) { const std::string header = field + ": " + value; curl_slist *headers = curl_slist_append(instance, header.c_str()); @@ -85,3 +121,16 @@ void http_headers::remove(const std::vector &fields) { const curl_slist* http_headers::data() const { return instance; } + +curl_slist* http_headers::copy_from(const curl_slist *headers) { + curl_slist *instance = nullptr; + for (const curl_slist *i = headers; i; i = i->next) { + curl_slist *headers = curl_slist_append(instance, i->data); + if (!headers) { + curl_slist_free_all(instance); + throw std::bad_alloc(); + } + instance = headers; + } + return instance; +} diff --git a/src/core/http_headers.h b/src/core/http_headers.h index 4547139..7e488cd 100644 --- a/src/core/http_headers.h +++ b/src/core/http_headers.h @@ -31,11 +31,14 @@ namespace bot { class http_headers { public: http_headers(); + http_headers(const http_headers &headers); http_headers(const std::string &field, const std::string &value); http_headers(const http_header &header); http_headers(const std::initializer_list &headers); http_headers(const std::vector &headers); ~http_headers(); + http_headers& operator=(const curl_slist *headers); + http_headers& operator=(const http_headers &headers); void add(const std::string &field, const std::string &value); void add(const http_header &header); void add(const std::initializer_list &headers); @@ -45,6 +48,7 @@ namespace bot { const curl_slist* data() const; private: + static curl_slist* copy_from(const curl_slist *headers); curl_slist *instance; }; }