From 47d02a31da050898265dc4a8e0e8f34a0284fccf Mon Sep 17 00:00:00 2001 From: Giel van Schijndel Date: Thu, 24 Jul 2008 18:18:07 +0000 Subject: [PATCH] * Change strresGetString to return its string as const (to prevent potential double-free problems) * Instead use strdup() where a non-const reference to these strings is used * NOTE: This may introduce memory leaks, but I'd rather have memory leaks than double-frees, of which I'm frankly surprised that they don't occur ''much'' more often * Change FindDroidTemplate to take its parameter as const * Don't multi-purpose the parameters of FindDroidTemplate as local variables * Store string variables in getName as const * scrvGetString: * Directly return the string it retrieved and use NULL to indicate failure * Return the string as `const' git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@5658 4a71c877-e1ca-e34f-864e-861f7616d084 --- lib/framework/strres.c | 2 +- lib/framework/strres.h | 2 +- src/game.c | 13 +++++++------ src/message.c | 4 ++-- src/scriptobj.c | 16 +++++++++++++++- src/scriptvals.c | 12 +++++------- src/scriptvals.h | 2 +- src/scriptvals_parser.y | 16 +++++++++++++--- src/stats.c | 4 ++-- 9 files changed, 47 insertions(+), 24 deletions(-) diff --git a/lib/framework/strres.c b/lib/framework/strres.c index cecc77de0..dcb54d5cb 100644 --- a/lib/framework/strres.c +++ b/lib/framework/strres.c @@ -334,7 +334,7 @@ BOOL strresStoreString(STR_RES *psRes, char *pID, const char *pString) /* Get the string from an ID number */ -char *strresGetString(STR_RES *psRes, UDWORD id) +const char* strresGetString(const STR_RES * psRes, UDWORD id) { STR_BLOCK *psBlock; diff --git a/lib/framework/strres.h b/lib/framework/strres.h index 5674df736..32d0962b0 100644 --- a/lib/framework/strres.h +++ b/lib/framework/strres.h @@ -42,7 +42,7 @@ extern BOOL strresGetIDNum(struct STR_RES *psRes, const char *pIDStr, UDWORD *pI extern const char* strresGetIDString(struct STR_RES *psRes, const char *pIDStr); /* Get the string from an ID number */ -extern char *strresGetString(struct STR_RES *psRes, UDWORD id); +extern const char* strresGetString(const struct STR_RES *psRes, UDWORD id); /* Load a string resource file */ extern BOOL strresLoad(struct STR_RES* psRes, const char* fileName); diff --git a/src/game.c b/src/game.c index 27fa1f814..16e8af74b 100644 --- a/src/game.c +++ b/src/game.c @@ -2146,7 +2146,7 @@ static bool writeMapFile(const char* fileName); static BOOL loadSaveDroidInitV2(char *pFileData, UDWORD filesize,UDWORD quantity); static BOOL loadSaveDroidInit(char *pFileData, UDWORD filesize); -static DROID_TEMPLATE *FindDroidTemplate(char *name,UDWORD player); +static DROID_TEMPLATE *FindDroidTemplate(const char * const name); static BOOL loadSaveDroid(char *pFileData, UDWORD filesize, DROID **ppsCurrentDroidLists); static BOOL loadSaveDroidV11(char *pFileData, UDWORD filesize, UDWORD numDroids, UDWORD version, DROID **ppsCurrentDroidLists); @@ -5118,7 +5118,7 @@ BOOL loadSaveDroidInitV2(char *pFileData, UDWORD filesize,UDWORD quantity) } - psTemplate = (DROID_TEMPLATE *)FindDroidTemplate(pDroidInit->name,pDroidInit->player); + psTemplate = (DROID_TEMPLATE *)FindDroidTemplate(pDroidInit->name); if(psTemplate==NULL) { @@ -5160,11 +5160,12 @@ BOOL loadSaveDroidInitV2(char *pFileData, UDWORD filesize,UDWORD quantity) // ----------------------------------------------------------------------------------------- -DROID_TEMPLATE *FindDroidTemplate(char *name,UDWORD player) +DROID_TEMPLATE *FindDroidTemplate(const char * const name) { UDWORD TempPlayer; DROID_TEMPLATE *Template; UDWORD id; + const char* nameStr; //get the name from the resource associated with it if (!strresGetIDNum(psStringRes, name, &id)) @@ -5174,15 +5175,15 @@ DROID_TEMPLATE *FindDroidTemplate(char *name,UDWORD player) return NULL; } //get the string from the id - name = strresGetString(psStringRes, id); + nameStr = strresGetString(psStringRes, id); for(TempPlayer=0; TempPlayerpName)==0) { - if(strcmp(name,Template->aName)==0) { + //if(strcmp(nameStr,Template->pName)==0) { + if(strcmp(nameStr,Template->aName)==0) { return Template; } Template = Template->psNext; diff --git a/src/message.c b/src/message.c index 2f1978541..9278df7ca 100644 --- a/src/message.c +++ b/src/message.c @@ -551,7 +551,7 @@ VIEWDATA *loadViewData(const char *pViewMsgData, UDWORD bufferSize) return NULL; } //get the string from the id - psViewData->ppTextMsg[dataInc] = strresGetString(psStringRes, id); + psViewData->ppTextMsg[dataInc] = strdup(strresGetString(psStringRes, id)); } sscanf(pViewMsgData, ",%d%n", &readint, &cnt); @@ -704,7 +704,7 @@ VIEWDATA *loadViewData(const char *pViewMsgData, UDWORD bufferSize) } //get the string from the id - psViewReplay->pSeqList[dataInc].ppTextMsg[seqInc] = strresGetString(psStringRes, id); + psViewReplay->pSeqList[dataInc].ppTextMsg[seqInc] = strdup(strresGetString(psStringRes, id)); } //get the audio text string sscanf(pViewMsgData,",%[^','],%d%n", audioName, &count,&cnt); diff --git a/src/scriptobj.c b/src/scriptobj.c index 4dc988b67..4409706b4 100644 --- a/src/scriptobj.c +++ b/src/scriptobj.c @@ -1189,7 +1189,21 @@ BOOL scrValDefLoad(SDWORD version, INTERP_VAL *psVal, char *pBuffer, UDWORD size } else { - psVal->v.sval = strresGetString(psStringRes, id); + const char * const str = strresGetString(psStringRes, id); + if (!str) + { + debug(LOG_ERROR, "Couldn't find string with id %u", id); + abort(); + return false; + } + + psVal->v.sval = strdup(str); + if (!psVal->v.sval) + { + debug(LOG_ERROR, "Out of memory"); + abort(); + return false; + } } break; case ST_LEVEL: diff --git a/src/scriptvals.c b/src/scriptvals.c index 8f1e61faf..c5da74377 100644 --- a/src/scriptvals.c +++ b/src/scriptvals.c @@ -238,20 +238,18 @@ BOOL scrvGetContext(char *pID, SCRIPT_CONTEXT **ppsContext) // Find a string from it's (string)id -BOOL scrvGetString(const char *pStringID, char **ppString) +const char* scrvGetString(const char* stringID) { UDWORD id; //get the ID for the string - if (!strresGetIDNum(psStringRes, pStringID, &id)) + if (!strresGetIDNum(psStringRes, stringID, &id)) { - debug( LOG_ERROR, "Cannot find the string id %s ", pStringID ); + debug(LOG_ERROR, "Cannot find the string for id \"%s\"", stringID); abort(); - return false; + return NULL; } //get the string from the id - *ppString = strresGetString(psStringRes, id); - - return true; + return strresGetString(psStringRes, id); } diff --git a/src/scriptvals.h b/src/scriptvals.h index f842800ef..15f640e3b 100644 --- a/src/scriptvals.h +++ b/src/scriptvals.h @@ -109,6 +109,6 @@ extern BOOL scrvLoad(PHYSFS_file* fileHandle); //extern BOOL scrvLinkValues(void); // Find a string from it's (string)id -extern BOOL scrvGetString(const char *pStringID, char **ppString); +extern const char* scrvGetString(const char* stringID); #endif // __INCLUDED_SRC_SCRIPTVALS_H__ diff --git a/src/scriptvals_parser.y b/src/scriptvals_parser.y index 3e5bacc97..771f2be6c 100644 --- a/src/scriptvals_parser.y +++ b/src/scriptvals_parser.y @@ -231,7 +231,6 @@ var_init: var_entry TYPE var_value { INTERP_VAL data; /* structure to to hold all types */ BASE_OBJECT *psObj; - char *pString; SDWORD compIndex; /* set type */ @@ -618,23 +617,34 @@ var_init: var_entry TYPE var_value } break; case ST_TEXTSTRING: + { + const char* pString; + if ($3.type != IT_STRING) { yyerror("Typemismatch for variable %d", $1); YYABORT; } - if (!scrvGetString($3.pString, &pString)) + pString = scrvGetString($3.pString); + if (!pString) { yyerror("String %s not found", $3.pString); YYABORT; } - data.v.sval = pString; + data.v.sval = strdup(pString); + if (!data.v.sval) + { + debug(LOG_ERROR, "Out of memory"); + abort(); + YYABORT; + } if (!eventSetContextVar(psCurrContext, $1, &data)) { yyerror("Set Value Failed for %u", $1); YYABORT; } break; + } case ST_LEVEL: { LEVEL_DATASET *psLevel; diff --git a/src/stats.c b/src/stats.c index 1f97f7fe0..f62696d73 100644 --- a/src/stats.c +++ b/src/stats.c @@ -2613,8 +2613,8 @@ BOOL getResourceName(const char *pName) const char* getName(const char *pNameID) { UDWORD id; - char *pName; - static char Unknown[] = "Name Unknown"; + const char* pName; + static const char Unknown[] = "Name Unknown"; /*see if the name has a resource associated with it by trying to get the ID for the string*/