Fix memory leaks in config_parser.

push_token() doesn't take ownership of its str argument.
This commit is contained in:
Emil Mikulic 2012-11-24 16:02:20 +11:00 committed by Michael Stapelberg
parent eaf13eace2
commit d2b533328d
1 changed files with 7 additions and 4 deletions

View File

@ -91,7 +91,7 @@ static struct stack_entry stack[10];
* single array, since the number of entries we have to store is very small. * single array, since the number of entries we have to store is very small.
* *
*/ */
static void push_string(const char *identifier, char *str) { static void push_string(const char *identifier, const char *str) {
for (int c = 0; c < 10; c++) { for (int c = 0; c < 10; c++) {
if (stack[c].identifier != NULL && if (stack[c].identifier != NULL &&
strcmp(stack[c].identifier, identifier) != 0) strcmp(stack[c].identifier, identifier) != 0)
@ -99,11 +99,13 @@ static void push_string(const char *identifier, char *str) {
if (stack[c].identifier == NULL) { if (stack[c].identifier == NULL) {
/* Found a free slot, lets store it here. */ /* Found a free slot, lets store it here. */
stack[c].identifier = identifier; stack[c].identifier = identifier;
stack[c].val.str = str; stack[c].val.str = sstrdup(str);
stack[c].type = STACK_STR; stack[c].type = STACK_STR;
} else { } else {
/* Append the value. */ /* Append the value. */
sasprintf(&(stack[c].val.str), "%s,%s", stack[c].val.str, str); char *prev = stack[c].val.str;
sasprintf(&(stack[c].val.str), "%s,%s", prev, str);
free(prev);
} }
return; return;
} }
@ -352,7 +354,7 @@ struct ConfigResult *parse_config(const char *input, struct context *context) {
if (token->name[0] == '\'') { if (token->name[0] == '\'') {
if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) { if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
if (token->identifier != NULL) if (token->identifier != NULL)
push_string(token->identifier, sstrdup(token->name + 1)); push_string(token->identifier, token->name + 1);
walk += strlen(token->name) - 1; walk += strlen(token->name) - 1;
next_state(token); next_state(token);
token_handled = true; token_handled = true;
@ -424,6 +426,7 @@ struct ConfigResult *parse_config(const char *input, struct context *context) {
} }
if (token->identifier) if (token->identifier)
push_string(token->identifier, str); push_string(token->identifier, str);
free(str);
/* If we are at the end of a quoted string, skip the ending /* If we are at the end of a quoted string, skip the ending
* double quote. */ * double quote. */
if (*walk == '"') if (*walk == '"')