* don't take ownership of sDefaultDesignTemplate.pName as it triggers double free()s

* ASSERT on a condition that __will__ cause a double free()
 * Only assign &sDefaultDesignTemplate to pTemplate if we're sure we can use it


git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4400 4a71c877-e1ca-e34f-864e-861f7616d084
master
Giel van Schijndel 2008-03-28 21:32:34 +00:00
parent c90b50b75c
commit c3fcd4bf33
2 changed files with 13 additions and 5 deletions

View File

@ -470,6 +470,7 @@ static BOOL _intAddDesign( BOOL bShowCentreScreen )
else else
{ {
memcpy(&sCurrDesign, &sDefaultDesignTemplate, sizeof(DROID_TEMPLATE)); memcpy(&sCurrDesign, &sDefaultDesignTemplate, sizeof(DROID_TEMPLATE));
sCurrDesign.pName = NULL;
strlcpy(aCurrName, _("New Vehicle"), sizeof(aCurrName)); strlcpy(aCurrName, _("New Vehicle"), sizeof(aCurrName));
strlcpy(sCurrDesign.aName, aCurrName, sizeof(sCurrDesign.aName)); strlcpy(sCurrDesign.aName, aCurrName, sizeof(sCurrDesign.aName));
} }
@ -3455,6 +3456,7 @@ static void desCreateDefaultTemplate( void )
{ {
/* set current design to default */ /* set current design to default */
memcpy( &sCurrDesign, &sDefaultDesignTemplate, sizeof(DROID_TEMPLATE) ); memcpy( &sCurrDesign, &sDefaultDesignTemplate, sizeof(DROID_TEMPLATE) );
sCurrDesign.pName = NULL;
/* reset stats */ /* reset stats */
intSetDesignStats(&sCurrDesign); intSetDesignStats(&sCurrDesign);

View File

@ -2489,6 +2489,10 @@ BOOL loadDroidTemplates(const char *pDroidData, UDWORD bufferSize)
*/ */
if ( pDroidDesign->droidType == DROID_DEFAULT ) if ( pDroidDesign->droidType == DROID_DEFAULT )
{ {
// NOTE: sDefaultDesignTemplate.pName takes ownership
// of the memory allocated to pDroidDesign->pName
// here. Which is good because pDroidDesign leaves
// scope here anyway.
memcpy( &sDefaultDesignTemplate, pDroidDesign, sizeof(DROID_TEMPLATE) ); memcpy( &sDefaultDesignTemplate, pDroidDesign, sizeof(DROID_TEMPLATE) );
free(pDroidDesign); free(pDroidDesign);
} }
@ -2500,7 +2504,6 @@ BOOL loadDroidTemplates(const char *pDroidData, UDWORD bufferSize)
//increment the pointer to the start of the next record //increment the pointer to the start of the next record
pDroidData = strchr(pDroidData,'\n') + 1; pDroidData = strchr(pDroidData,'\n') + 1;
pDroidDesign++;
} }
if ( bDefaultTemplateFound == false ) if ( bDefaultTemplateFound == false )
@ -2677,8 +2680,11 @@ BOOL loadDroidWeapons(const char *pWeaponData, UDWORD bufferSize)
/* if Template not found - try default design */ /* if Template not found - try default design */
if (!pTemplate) if (!pTemplate)
{ {
pTemplate = &sDefaultDesignTemplate; if (strcmp(TemplateName, sDefaultDesignTemplate.pName) == 0)
if ( strcmp(TemplateName, pTemplate->pName) != 0 ) {
pTemplate = &sDefaultDesignTemplate;
}
else
{ {
debug( LOG_ERROR, "Unable to find Template - %s", TemplateName ); debug( LOG_ERROR, "Unable to find Template - %s", TemplateName );
abort(); abort();
@ -2759,10 +2765,10 @@ BOOL droidTemplateShutDown(void)
{ {
DROID_TEMPLATE *pTemplate, *pNext; DROID_TEMPLATE *pTemplate, *pNext;
for(pTemplate = apsDroidTemplates[player]; pTemplate != NULL; for (pTemplate = apsDroidTemplates[player]; pTemplate != NULL; pTemplate = pNext)
pTemplate = pNext)
{ {
pNext = pTemplate->psNext; pNext = pTemplate->psNext;
ASSERT(sDefaultDesignTemplate.pName != pTemplate->pName, "We'll soon be getting a double free()!!!");
if (pTemplate->pName != sDefaultDesignTemplate.pName) if (pTemplate->pName != sDefaultDesignTemplate.pName)
{ {
free(pTemplate->pName); free(pTemplate->pName);