diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-22 17:52:53 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-05-22 17:52:53 +0200 |
| commit | 9617dd452e529af3a12b14a98cd2edbfd93ea712 (patch) | |
| tree | 51ad857e09656fb9cafed5395c3b7613e003e102 | |
| parent | 48985bf413bef59778a4e50ba8391938364bae56 (diff) | |
| download | lanes-9617dd452e529af3a12b14a98cd2edbfd93ea712.tar.gz lanes-9617dd452e529af3a12b14a98cd2edbfd93ea712.tar.bz2 lanes-9617dd452e529af3a12b14a98cd2edbfd93ea712.zip | |
Fix buffer overrun in Linda name
| -rw-r--r-- | src/linda.cpp | 34 | ||||
| -rw-r--r-- | 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 <bool OPT> | |||
| 79 | { | 79 | { |
| 80 | Linda* const _linda{ ToLinda<OPT>(L_, idx_) }; | 80 | Linda* const _linda{ ToLinda<OPT>(L_, idx_) }; |
| 81 | if (_linda != nullptr) { | 81 | if (_linda != nullptr) { |
| 82 | std::ignore = lua_pushstringview(L_, "Linda: "); | ||
| 82 | std::string_view const _lindaName{ _linda->getName() }; | 83 | std::string_view const _lindaName{ _linda->getName() }; |
| 83 | char _text[128]; | 84 | if (!_lindaName.empty()) { |
| 84 | int _len; | 85 | std::ignore = lua_pushstringview(L_, _lindaName); |
| 85 | if (!_lindaName.empty()) | 86 | } else { |
| 86 | _len = sprintf(_text, "Linda: %.*s", (int) sizeof(_text) - 8, _lindaName.data()); | 87 | lua_pushfstring(L_, "%p", _linda); |
| 87 | else | 88 | } |
| 88 | _len = sprintf(_text, "Linda: %p", _linda); | 89 | lua_concat(L_, 2); |
| 89 | lua_pushlstring(L_, _text, _len); | ||
| 90 | return 1; | 90 | return 1; |
| 91 | } | 91 | } |
| 92 | return 0; | 92 | return 0; |
| @@ -126,9 +126,17 @@ Linda::Linda(Universe* U_, LindaGroup group_, std::string_view const& name_) | |||
| 126 | 126 | ||
| 127 | Linda::~Linda() | 127 | Linda::~Linda() |
| 128 | { | 128 | { |
| 129 | freeAllocatedName(); | ||
| 130 | } | ||
| 131 | |||
| 132 | // ################################################################################################# | ||
| 133 | |||
| 134 | void Linda::freeAllocatedName() | ||
| 135 | { | ||
| 129 | if (std::holds_alternative<std::string_view>(nameVariant)) { | 136 | if (std::holds_alternative<std::string_view>(nameVariant)) { |
| 130 | std::string_view& _name = std::get<std::string_view>(nameVariant); | 137 | std::string_view& _name = std::get<std::string_view>(nameVariant); |
| 131 | U->internalAllocator.free(const_cast<char*>(_name.data()), _name.size()); | 138 | U->internalAllocator.free(const_cast<char*>(_name.data()), _name.size()); |
| 139 | _name = {}; | ||
| 132 | } | 140 | } |
| 133 | } | 141 | } |
| 134 | 142 | ||
| @@ -189,21 +197,19 @@ void Linda::setName(std::string_view const& name_) | |||
| 189 | if (name_.empty()) { | 197 | if (name_.empty()) { |
| 190 | return; | 198 | return; |
| 191 | } | 199 | } |
| 192 | size_t const _lenWithTZ{ name_.size() + 1 }; // don't forget terminating 0 | 200 | |
| 193 | if (_lenWithTZ < kEmbeddedNameLength) { | 201 | // if we currently hold an allocated name, free it |
| 202 | freeAllocatedName(); | ||
| 203 | if (name_.size() <= kEmbeddedNameLength) { | ||
| 194 | // grab our internal buffer | 204 | // grab our internal buffer |
| 195 | EmbeddedName& _name = nameVariant.emplace<EmbeddedName>(); | 205 | EmbeddedName& _name = nameVariant.emplace<EmbeddedName>(); |
| 196 | // copy the string in it | 206 | // copy the string in it |
| 197 | memcpy(_name.data(), name_.data(), name_.size()); | 207 | memcpy(_name.data(), name_.data(), name_.size()); |
| 198 | // don't forget terminating 0 | ||
| 199 | _name[_lenWithTZ] = 0; | ||
| 200 | } else { | 208 | } else { |
| 201 | // allocate an external buffer | 209 | // allocate an external buffer |
| 202 | char* const _nameBuffer{ static_cast<char*>(U->internalAllocator.alloc(_lenWithTZ)) }; | 210 | char* const _nameBuffer{ static_cast<char*>(U->internalAllocator.alloc(name_.size())) }; |
| 203 | // copy the string in it | 211 | // copy the string in it |
| 204 | memcpy(_nameBuffer, name_.data(), name_.size()); | 212 | memcpy(_nameBuffer, name_.data(), name_.size()); |
| 205 | // don't forget terminating 0 | ||
| 206 | _nameBuffer[_lenWithTZ] = 0; | ||
| 207 | nameVariant.emplace<std::string_view>(_nameBuffer, name_.size()); | 213 | nameVariant.emplace<std::string_view>(_nameBuffer, name_.size()); |
| 208 | } | 214 | } |
| 209 | } | 215 | } |
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 | |||
| 56 | Linda& operator=(Linda const&&) = delete; | 56 | Linda& operator=(Linda const&&) = delete; |
| 57 | 57 | ||
| 58 | private: | 58 | private: |
| 59 | void freeAllocatedName(); | ||
| 59 | void setName(std::string_view const& name_); | 60 | void setName(std::string_view const& name_); |
| 60 | 61 | ||
| 61 | public: | 62 | public: |
