From 2e9414948518559b41945166707d5f9f807973cf Mon Sep 17 00:00:00 2001 From: ndossche <7771979+ndossche@users.noreply.github.com> Date: Wed, 18 Feb 2026 18:53:57 +0100 Subject: [PATCH] fix: handle reallocation failure gracefully in DataPointer::resize() Immediate reassignment leaves the `buf.data` pointer with a nullptr, leaking the original data. Furthermore, it leaves the length field inconsistent. This patch first checks whether the pointer was a nullptr before reassigning. --- include/ncrypto.h | 2 ++ src/ncrypto.cpp | 13 +++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/include/ncrypto.h b/include/ncrypto.h index 4b3ccab..79b7298 100644 --- a/include/ncrypto.h +++ b/include/ncrypto.h @@ -690,6 +690,8 @@ class DataPointer final { bool isSecure() const { return secure_; } private: + void free(); + void* data_ = nullptr; size_t len_ = 0; bool secure_ = false; diff --git a/src/ncrypto.cpp b/src/ncrypto.cpp index 50bd9c0..f03af46 100644 --- a/src/ncrypto.cpp +++ b/src/ncrypto.cpp @@ -228,7 +228,7 @@ void DataPointer::zero() { OPENSSL_cleanse(data_, len_); } -void DataPointer::reset(void* data, size_t length) { +void DataPointer::free() { if (data_ != nullptr) { if (secure_) { OPENSSL_secure_clear_free(data_, len_); @@ -236,6 +236,10 @@ void DataPointer::reset(void* data, size_t length) { OPENSSL_clear_free(data_, len_); } } +} + +void DataPointer::reset(void* data, size_t length) { + free(); data_ = data; len_ = length; } @@ -258,7 +262,12 @@ DataPointer DataPointer::resize(size_t len) { size_t actual_len = std::min(len_, len); auto buf = release(); if (actual_len == len_) return DataPointer(buf.data, actual_len); - buf.data = OPENSSL_realloc(buf.data, actual_len); + auto new_data = OPENSSL_realloc(buf.data, actual_len); + if (new_data == nullptr) { + free(); + return {}; + } + buf.data = new_data; buf.len = actual_len; return DataPointer(buf); }