diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index 81852f7cf8..68019e8dab 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.cpp @@ -1246,17 +1246,13 @@ public: */ static size_t SlCalcLen(const void *storage, VarType conv, SaveLoadType cmd = SL_VAR) { - assert(cmd == SL_VAR || cmd == SL_REF || cmd == SL_STDSTR); + assert(cmd == SL_VAR || cmd == SL_REF); const SlStorageT *list = static_cast(storage); - size_t type_size = SlGetArrayLength(list->size()); - if constexpr (std::is_same_v, SlStorageT> || std::is_same_v, SlStorageT>) { - return std::accumulate(list->begin(), list->end(), type_size, [](size_t sum, const std::string &str) { return sum + SlCalcStdStringLen(&str); }); - } else { - size_t item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32); - return list->size() * item_size + type_size; - } + int type_size = SlGetArrayLength(list->size()); + int item_size = SlCalcConvFileLen(cmd == SL_VAR ? conv : (VarType)SLE_FILE_U32); + return list->size() * item_size + type_size; } static void SlSaveLoadMember(SaveLoadType cmd, Tvar *item, VarType conv) @@ -1368,7 +1364,12 @@ static inline size_t SlCalcDequeLen(const void *deque, VarType conv) case SLE_VAR_U32: return SlStorageHelper::SlCalcLen(deque, conv); case SLE_VAR_I64: return SlStorageHelper::SlCalcLen(deque, conv); case SLE_VAR_U64: return SlStorageHelper::SlCalcLen(deque, conv); - case SLE_VAR_STR: return SlStorageHelper::SlCalcLen(deque, conv, SL_STDSTR); + + case SLE_VAR_STR: + /* Strings are a length-prefixed field type in the savegame table format, + * these may not be directly stored in another length-prefixed container type. */ + NOT_REACHED(); + default: NOT_REACHED(); } } @@ -1390,7 +1391,16 @@ static void SlDeque(void *deque, VarType conv) case SLE_VAR_U32: SlStorageHelper::SlSaveLoad(deque, conv); break; case SLE_VAR_I64: SlStorageHelper::SlSaveLoad(deque, conv); break; case SLE_VAR_U64: SlStorageHelper::SlSaveLoad(deque, conv); break; - case SLE_VAR_STR: SlStorageHelper::SlSaveLoad(deque, conv, SL_STDSTR); break; + + case SLE_VAR_STR: + /* Strings are a length-prefixed field type in the savegame table format, + * these may not be directly stored in another length-prefixed container type. + * This is permitted for load-related actions, because invalid fields of this type are present + * from SLV_COMPANY_ALLOW_LIST up to SLV_COMPANY_ALLOW_LIST_V2. */ + assert(_sl.action != SLA_SAVE); + SlStorageHelper::SlSaveLoad(deque, conv, SL_STDSTR); + break; + default: NOT_REACHED(); } } @@ -1412,7 +1422,12 @@ static inline size_t SlCalcVectorLen(const void *vector, VarType conv) case SLE_VAR_U32: return SlStorageHelper::SlCalcLen(vector, conv); case SLE_VAR_I64: return SlStorageHelper::SlCalcLen(vector, conv); case SLE_VAR_U64: return SlStorageHelper::SlCalcLen(vector, conv); - case SLE_VAR_STR: return SlStorageHelper::SlCalcLen(vector, conv, SL_STDSTR); + + case SLE_VAR_STR: + /* Strings are a length-prefixed field type in the savegame table format, + * these may not be directly stored in another length-prefixed container type. */ + NOT_REACHED(); + default: NOT_REACHED(); } } @@ -1434,7 +1449,16 @@ static void SlVector(void *vector, VarType conv) case SLE_VAR_U32: SlStorageHelper::SlSaveLoad(vector, conv); break; case SLE_VAR_I64: SlStorageHelper::SlSaveLoad(vector, conv); break; case SLE_VAR_U64: SlStorageHelper::SlSaveLoad(vector, conv); break; - case SLE_VAR_STR: SlStorageHelper::SlSaveLoad(vector, conv, SL_STDSTR); break; + + case SLE_VAR_STR: + /* Strings are a length-prefixed field type in the savegame table format, + * these may not be directly stored in another length-prefixed container type. + * This is permitted for load-related actions, because invalid fields of this type are present + * from SLV_COMPANY_ALLOW_LIST up to SLV_COMPANY_ALLOW_LIST_V2. */ + assert(_sl.action != SLA_SAVE); + SlStorageHelper::SlSaveLoad(vector, conv, SL_STDSTR); + break; + default: NOT_REACHED(); } }