mirror of https://github.com/OpenTTD/OpenTTD
(svn r26591) -Add: some instrumentation to catch most cases where the wrong number of bytes would be written into variables during loading (or read during saving)
parent
191fd09d32
commit
46792e58dd
|
@ -1464,9 +1464,50 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the variable size of the variable in the saveload configuration
|
||||||
|
* matches with the actual variable size.
|
||||||
|
* @param sld The saveload configuration to test.
|
||||||
|
*/
|
||||||
|
static bool IsVariableSizeRight(const SaveLoad *sld)
|
||||||
|
{
|
||||||
|
switch (sld->cmd) {
|
||||||
|
case SL_VAR:
|
||||||
|
switch (GetVarMemType(sld->conv)) {
|
||||||
|
case SLE_VAR_BL:
|
||||||
|
return sld->size == sizeof(bool);
|
||||||
|
case SLE_VAR_I8:
|
||||||
|
case SLE_VAR_U8:
|
||||||
|
return sld->size == sizeof(int8);
|
||||||
|
case SLE_VAR_I16:
|
||||||
|
case SLE_VAR_U16:
|
||||||
|
return sld->size == sizeof(int16);
|
||||||
|
case SLE_VAR_I32:
|
||||||
|
case SLE_VAR_U32:
|
||||||
|
return sld->size == sizeof(int32);
|
||||||
|
case SLE_VAR_I64:
|
||||||
|
case SLE_VAR_U64:
|
||||||
|
return sld->size == sizeof(int64);
|
||||||
|
default:
|
||||||
|
return sld->size == sizeof(void *);
|
||||||
|
}
|
||||||
|
case SL_REF:
|
||||||
|
/* These should all be pointer sized. */
|
||||||
|
return sld->size == sizeof(void *);
|
||||||
|
|
||||||
|
case SL_STR:
|
||||||
|
/* These should be pointer sized, or fixed array. */
|
||||||
|
return sld->size == sizeof(void *) || sld->size == sld->length;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
||||||
{
|
{
|
||||||
|
assert(IsVariableSizeRight(sld));
|
||||||
|
|
||||||
VarType conv = GB(sld->conv, 0, 8);
|
VarType conv = GB(sld->conv, 0, 8);
|
||||||
switch (sld->cmd) {
|
switch (sld->cmd) {
|
||||||
case SL_VAR:
|
case SL_VAR:
|
||||||
|
|
|
@ -212,6 +212,7 @@ struct SaveLoad {
|
||||||
* during runtime. Decision on which one to use is controlled by the function
|
* during runtime. Decision on which one to use is controlled by the function
|
||||||
* that is called to save it. address: global=true, offset: global=false */
|
* that is called to save it. address: global=true, offset: global=false */
|
||||||
void *address; ///< address of variable OR offset of variable in the struct (max offset is 65536)
|
void *address; ///< address of variable OR offset of variable in the struct (max offset is 65536)
|
||||||
|
size_t size; ///< the sizeof size.
|
||||||
};
|
};
|
||||||
|
|
||||||
/** Same as #SaveLoad but global variables are used (for better readability); */
|
/** Same as #SaveLoad but global variables are used (for better readability); */
|
||||||
|
@ -227,7 +228,7 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
* @param to Last savegame version that has the field.
|
* @param to Last savegame version that has the field.
|
||||||
* @note In general, it is better to use one of the SLE_* macros below.
|
* @note In general, it is better to use one of the SLE_* macros below.
|
||||||
*/
|
*/
|
||||||
#define SLE_GENERAL(cmd, base, variable, type, length, from, to) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable)}
|
#define SLE_GENERAL(cmd, base, variable, type, length, from, to) {false, cmd, type, length, from, to, (void*)cpp_offsetof(base, variable), cpp_sizeof(base, variable)}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a variable in some savegame versions.
|
* Storage of a variable in some savegame versions.
|
||||||
|
@ -340,11 +341,11 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
/** Translate values ingame to different values in the savegame and vv. */
|
/** Translate values ingame to different values in the savegame and vv. */
|
||||||
#define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
|
#define SLE_WRITEBYTE(base, variable, value) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, value, value)
|
||||||
|
|
||||||
#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL}
|
#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0}
|
||||||
#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL}
|
#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, 0, SL_MAX_VERSION, NULL, 0}
|
||||||
|
|
||||||
/** End marker of a struct/class save or load. */
|
/** End marker of a struct/class save or load. */
|
||||||
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL}
|
#define SLE_END() {false, SL_END, 0, 0, 0, 0, NULL, 0}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of global simple variables, references (pointers), and arrays.
|
* Storage of global simple variables, references (pointers), and arrays.
|
||||||
|
@ -355,7 +356,7 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
* @param to Last savegame version that has the field.
|
* @param to Last savegame version that has the field.
|
||||||
* @note In general, it is better to use one of the SLEG_* macros below.
|
* @note In general, it is better to use one of the SLEG_* macros below.
|
||||||
*/
|
*/
|
||||||
#define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable}
|
#define SLEG_GENERAL(cmd, variable, type, length, from, to) {true, cmd, type, length, from, to, (void*)&variable, sizeof(variable)}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Storage of a global variable in some savegame versions.
|
* Storage of a global variable in some savegame versions.
|
||||||
|
@ -448,7 +449,7 @@ typedef SaveLoad SaveLoadGlobVarList;
|
||||||
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL}
|
#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL}
|
||||||
|
|
||||||
/** End marker of global variables save or load. */
|
/** End marker of global variables save or load. */
|
||||||
#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL}
|
#define SLEG_END() {true, SL_END, 0, 0, 0, 0, NULL, 0}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the savegame is below \a major.\a minor.
|
* Checks whether the savegame is below \a major.\a minor.
|
||||||
|
|
Loading…
Reference in New Issue