Fix #11644: Off by one error/buffer over-read in StrMakeValid (#11645)

* Fix #11644: Off by one error in StrMakeValid UTF-8 decode overrun detection

* Fix #11644: Off by one error in StrMakeValid buffer last character

* Fix: Unnecessary string duplication at StrMakeValid call sites
This commit is contained in:
Jonathan G Rennison 2024-01-01 18:26:31 +00:00 committed by GitHub
parent a672813bb0
commit 88324a253e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 6 additions and 4 deletions

View File

@ -486,7 +486,7 @@ static std::string ExtractString(char *buffer, size_t buffer_length)
{
size_t length = 0;
for (; length < buffer_length && buffer[length] != '\0'; length++) {}
return StrMakeValid(std::string(buffer, length));
return StrMakeValid(std::string_view(buffer, length));
}
bool TarScanner::AddFile(const std::string &filename, size_t, [[maybe_unused]] const std::string &tar_filename)

View File

@ -284,7 +284,7 @@ void IniLoadFile::LoadFromDisk(const std::string &filename, Subdirectory subdir)
if (!quoted && e == t) {
item.value.reset();
} else {
item.value = StrMakeValid(std::string(t));
item.value = StrMakeValid(std::string_view(t));
}
} else {
/* it's an orphan item */

View File

@ -141,7 +141,7 @@ static void StrMakeValid(T &dst, const char *str, const char *last, StringValida
* would also reach the "last" byte of the string and a normal '\0'
* termination will be placed after it.
*/
if (len == 0 || str + len > last || len != Utf8Decode(&c, str)) {
if (len == 0 || str + len > last + 1 || len != Utf8Decode(&c, str)) {
/* Maybe the next byte is still a valid character? */
str++;
continue;
@ -211,8 +211,10 @@ void StrMakeValidInPlace(char *str, StringValidationSettings settings)
*/
std::string StrMakeValid(std::string_view str, StringValidationSettings settings)
{
if (str.empty()) return {};
auto buf = str.data();
auto last = buf + str.size();
auto last = buf + str.size() - 1;
std::ostringstream dst;
std::ostreambuf_iterator<char> dst_iter(dst);