Avoid nullptr reference undefined behaviour in saveload when discarding table string on load

This commit is contained in:
Jonathan G Rennison
2024-06-20 00:09:19 +01:00
parent 88b298f30e
commit 6244f5b929
3 changed files with 12 additions and 6 deletions

View File

@@ -325,7 +325,7 @@ static void SaveDispatchSchedule(DispatchSchedule &ds)
SlWriteUint32((uint32_t)names.size()); SlWriteUint32((uint32_t)names.size());
for (auto &it : names) { for (auto &it : names) {
SlWriteUint32(it.first); SlWriteUint32(it.first);
SlStdString(it.second, SLE_STR); SlStdString(&(it.second), SLE_STR);
} }
} }
} }
@@ -354,7 +354,7 @@ static void LoadDispatchSchedule(DispatchSchedule &ds)
btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap(); btree::btree_map<uint32_t, std::string> &names = ds.GetSupplementaryNameMap();
for (uint32_t i = 0; i < string_count; i++) { for (uint32_t i = 0; i < string_count; i++) {
uint32_t key = SlReadUint32(); uint32_t key = SlReadUint32();
SlStdString(names[key], SLE_STR); SlStdString(&(names[key]), SLE_STR);
} }
} }
} }

View File

@@ -1254,10 +1254,13 @@ static void SlString(void *ptr, size_t length, VarType conv)
* @param ptr the string being manipulated * @param ptr the string being manipulated
* @param conv must be SLE_FILE_STRING * @param conv must be SLE_FILE_STRING
*/ */
void SlStdString(std::string &str, VarType conv) void SlStdString(std::string *ptr, VarType conv)
{ {
switch (_sl.action) { switch (_sl.action) {
case SLA_SAVE: { case SLA_SAVE: {
dbg_assert(ptr != nullptr);
std::string &str = *ptr;
SlWriteArrayLength(str.size()); SlWriteArrayLength(str.size());
SlCopyBytes(str.data(), str.size()); SlCopyBytes(str.data(), str.size());
break; break;
@@ -1270,6 +1273,9 @@ void SlStdString(std::string &str, VarType conv)
return; return;
} }
dbg_assert(ptr != nullptr);
std::string &str = *ptr;
str.resize(len); str.resize(len);
SlCopyBytes(str.data(), len); SlCopyBytes(str.data(), len);
@@ -1992,7 +1998,7 @@ bool SlObjectMemberGeneric(void *object, const SaveLoad &sld)
} }
break; break;
} }
case SL_STDSTR: SlStdString(*static_cast<std::string *>(ptr), sld.conv); break; case SL_STDSTR: SlStdString(static_cast<std::string *>(ptr), sld.conv); break;
default: NOT_REACHED(); default: NOT_REACHED();
} }
break; break;
@@ -2216,7 +2222,7 @@ std::vector<SaveLoad> SlTableHeader(const NamedSaveLoadTable &slt)
} }
std::string key; std::string key;
SlStdString(key, SLE_STR); SlStdString(&key, SLE_STR);
auto sld_it = std::lower_bound(key_lookup.begin(), key_lookup.end(), key); auto sld_it = std::lower_bound(key_lookup.begin(), key_lookup.end(), key);
if (sld_it == key_lookup.end() || sld_it->name != key) { if (sld_it == key_lookup.end() || sld_it->name != key) {

View File

@@ -1061,7 +1061,7 @@ void SlLoadFromBuffer(const uint8_t *buffer, size_t length, F proc)
} }
void SlGlobList(const SaveLoadTable &slt); void SlGlobList(const SaveLoadTable &slt);
void SlStdString(std::string &str, VarType conv); void SlStdString(std::string *str, VarType conv);
void SlArray(void *array, size_t length, VarType conv); void SlArray(void *array, size_t length, VarType conv);
void SlObject(void *object, const SaveLoadTable &slt); void SlObject(void *object, const SaveLoadTable &slt);
bool SlObjectMember(void *object, const SaveLoad &sld); bool SlObjectMember(void *object, const SaveLoad &sld);