From 9617dd452e529af3a12b14a98cd2edbfd93ea712 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Wed, 22 May 2024 17:52:53 +0200 Subject: Fix buffer overrun in Linda name --- src/linda.cpp | 34 ++++++++++++++++++++-------------- src/linda.h | 1 + 2 files changed, 21 insertions(+), 14 deletions(-) diff --git a/src/linda.cpp b/src/linda.cpp index 4bd4553..1040cd6 100644 --- a/src/linda.cpp +++ b/src/linda.cpp @@ -79,14 +79,14 @@ template { Linda* const _linda{ ToLinda(L_, idx_) }; if (_linda != nullptr) { + std::ignore = lua_pushstringview(L_, "Linda: "); std::string_view const _lindaName{ _linda->getName() }; - char _text[128]; - int _len; - if (!_lindaName.empty()) - _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _lindaName.data()); - else - _len = sprintf(_text, "Linda: %p", _linda); - lua_pushlstring(L_, _text, _len); + if (!_lindaName.empty()) { + std::ignore = lua_pushstringview(L_, _lindaName); + } else { + lua_pushfstring(L_, "%p", _linda); + } + lua_concat(L_, 2); return 1; } return 0; @@ -125,10 +125,18 @@ Linda::Linda(Universe* U_, LindaGroup group_, std::string_view const& name_) // ################################################################################################# Linda::~Linda() +{ + freeAllocatedName(); +} + +// ################################################################################################# + +void Linda::freeAllocatedName() { if (std::holds_alternative(nameVariant)) { std::string_view& _name = std::get(nameVariant); U->internalAllocator.free(const_cast(_name.data()), _name.size()); + _name = {}; } } @@ -189,21 +197,19 @@ void Linda::setName(std::string_view const& name_) if (name_.empty()) { return; } - size_t const _lenWithTZ{ name_.size() + 1 }; // don't forget terminating 0 - if (_lenWithTZ < kEmbeddedNameLength) { + + // if we currently hold an allocated name, free it + freeAllocatedName(); + if (name_.size() <= kEmbeddedNameLength) { // grab our internal buffer EmbeddedName& _name = nameVariant.emplace(); // copy the string in it memcpy(_name.data(), name_.data(), name_.size()); - // don't forget terminating 0 - _name[_lenWithTZ] = 0; } else { // allocate an external buffer - char* const _nameBuffer{ static_cast(U->internalAllocator.alloc(_lenWithTZ)) }; + char* const _nameBuffer{ static_cast(U->internalAllocator.alloc(name_.size())) }; // copy the string in it memcpy(_nameBuffer, name_.data(), name_.size()); - // don't forget terminating 0 - _nameBuffer[_lenWithTZ] = 0; nameVariant.emplace(_nameBuffer, name_.size()); } } diff --git a/src/linda.h b/src/linda.h index 611008e..3545544 100644 --- a/src/linda.h +++ b/src/linda.h @@ -56,6 +56,7 @@ class Linda Linda& operator=(Linda const&&) = delete; private: + void freeAllocatedName(); void setName(std::string_view const& name_); public: -- cgit v1.2.3-55-g6feb