Fix several memory leaks in level_parser.y that occur when parsing errors occur:
* In case of a semantic error (i.e. we detect something is wrong in a parsing rule) deallocate the resources of our current tokens __before__ calling YYABORT * Only add a LEVEL_DATASET* to the psLevels list when we've fully and succesfully finished parsing of the corresponding level_entry * Add a bison "destructor" that handles destruction of tokens on the parsing stack when a syntax error occurs (i.e. the current tokens cannot be matched to any parsing rule) git-svn-id: svn+ssh://svn.gna.org/svn/warzone/trunk@4888 4a71c877-e1ca-e34f-864e-861f7616d084master
parent
efd188a632
commit
0071531040
|
@ -43,6 +43,21 @@ void yyerror(const char* msg)
|
|||
debug(LOG_ERROR, "Level File parse error: `%s` at line `%d` text `%s`", msg, levGetErrorLine(), levGetErrorText());
|
||||
}
|
||||
|
||||
static void freeDataSet(LEVEL_DATASET * const d)
|
||||
{
|
||||
unsigned int i;
|
||||
for (i = 0; i < ARRAY_SIZE(d->apDataFiles); ++i)
|
||||
{
|
||||
if (d->apDataFiles[i] != NULL)
|
||||
{
|
||||
free(d->apDataFiles[i]);
|
||||
}
|
||||
}
|
||||
|
||||
free(d->pName);
|
||||
free(d);
|
||||
}
|
||||
|
||||
#define YYPARSE_PARAM yyparse_param
|
||||
#define yycontext ((parser_context*)yyparse_param)
|
||||
|
||||
|
@ -63,7 +78,18 @@ void yyerror(const char* msg)
|
|||
%token <sval> QTEXT
|
||||
%token <ival> INTEGER
|
||||
|
||||
%destructor { free($$); } IDENTIFIER QTEXT
|
||||
%destructor {
|
||||
// Force type checking by the compiler
|
||||
char * const s = $$;
|
||||
|
||||
if (s != NULL)
|
||||
free(s);
|
||||
} IDENTIFIER QTEXT
|
||||
|
||||
%destructor {
|
||||
if ($$ != NULL)
|
||||
freeDataSet($$);
|
||||
} level_line level_rule
|
||||
|
||||
/* keywords */
|
||||
%token LEVEL
|
||||
|
@ -83,7 +109,7 @@ void yyerror(const char* msg)
|
|||
%token MISS_CLEAR
|
||||
|
||||
/* rule types */
|
||||
%type <dataset> level_rule
|
||||
%type <dataset> level_line level_rule
|
||||
%type <ltype> level_type
|
||||
|
||||
%start lev_file
|
||||
|
@ -99,6 +125,9 @@ lev_file: /* Empty to allow empty files */
|
|||
;
|
||||
|
||||
level_entry: level_line level_directives_1st dataload_directives
|
||||
{
|
||||
LIST_ADDEND(psLevels, $1, LEVEL_DATASET);
|
||||
}
|
||||
;
|
||||
|
||||
level_line: level_rule IDENTIFIER
|
||||
|
@ -111,12 +140,16 @@ level_line: level_rule IDENTIFIER
|
|||
if (psFoundData == NULL)
|
||||
{
|
||||
yyerror("Cannot find full data set for `camchange'");
|
||||
freeDataSet($1);
|
||||
free($2);
|
||||
YYABORT;
|
||||
}
|
||||
|
||||
if (psFoundData->type != LDS_CAMSTART)
|
||||
{
|
||||
yyerror("Invalid data set name for `camchange'");
|
||||
freeDataSet($1);
|
||||
free($2);
|
||||
YYABORT;
|
||||
}
|
||||
psFoundData->psChange = $1;
|
||||
|
@ -127,6 +160,7 @@ level_line: level_rule IDENTIFIER
|
|||
|
||||
// Make this dataset current to our parsing context
|
||||
yycontext->dataset = $1;
|
||||
$$ = $1;
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -145,7 +179,6 @@ level_rule: level_type
|
|||
$$->game = -1;
|
||||
$$->dataDir = yycontext->datadir;
|
||||
|
||||
LIST_ADDEND(psLevels, $$, LEVEL_DATASET);
|
||||
yycontext->currData = 0;
|
||||
yycontext->dataLoaded = false;
|
||||
|
||||
|
|
Loading…
Reference in New Issue