diff options
| author | Ben Fuhrmannek | 2021-08-03 15:37:40 +0200 |
|---|---|---|
| committer | Ben Fuhrmannek | 2021-08-03 15:37:40 +0200 |
| commit | 62f6d31d88e4536269b60471d7a4f7431442276a (patch) | |
| tree | 152388be3eb9e2c6bc245cd4a897d380a08425a5 /src/sp_var_parser.c | |
| parent | 238c363b48a9189ad3f1df80cc330e01aed09cb4 (diff) | |
fixed mem leak in parser
Diffstat (limited to 'src/sp_var_parser.c')
| -rw-r--r-- | src/sp_var_parser.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/src/sp_var_parser.c b/src/sp_var_parser.c index eb57f70..cc75d83 100644 --- a/src/sp_var_parser.c +++ b/src/sp_var_parser.c | |||
| @@ -44,13 +44,15 @@ static int create_var(sp_tree *tree, const char *restrict value, | |||
| 44 | size_t value_len, elem_type _type, | 44 | size_t value_len, elem_type _type, |
| 45 | const char *restrict idx) { | 45 | const char *restrict idx) { |
| 46 | sp_tree *var_node = NULL; | 46 | sp_tree *var_node = NULL; |
| 47 | 47 | bool free_node_on_error = false; | |
| 48 | int err = 0; | ||
| 48 | assert(tree); | 49 | assert(tree); |
| 49 | 50 | ||
| 50 | if (tree->next == NULL && tree->type == UNDEFINED) { | 51 | if (tree->next == NULL && tree->type == UNDEFINED) { |
| 51 | var_node = tree; | 52 | var_node = tree; |
| 52 | } else { | 53 | } else { |
| 53 | var_node = pecalloc(sizeof(sp_tree), 1, 1); | 54 | var_node = pecalloc(sizeof(sp_tree), 1, 1); |
| 55 | free_node_on_error = true; | ||
| 54 | } | 56 | } |
| 55 | 57 | ||
| 56 | var_node->value = NULL; | 58 | var_node->value = NULL; |
| @@ -66,14 +68,15 @@ static int create_var(sp_tree *tree, const char *restrict value, | |||
| 66 | if (!(var_node->value = pestrndup(value, value_len, 1))) { | 68 | if (!(var_node->value = pestrndup(value, value_len, 1))) { |
| 67 | // LCOV_EXCL_START | 69 | // LCOV_EXCL_START |
| 68 | sp_log_err("config", "Can't allocate a strndup"); | 70 | sp_log_err("config", "Can't allocate a strndup"); |
| 69 | return -1; | 71 | err = -1; goto err; |
| 70 | // LCOV_EXCL_STOP | 72 | // LCOV_EXCL_STOP |
| 71 | } | 73 | } |
| 72 | if (var_node->type != INTERPRETED_STRING && | 74 | if (var_node->type != INTERPRETED_STRING && |
| 73 | !is_var_name_valid(var_node->value)) { | 75 | !is_var_name_valid(var_node->value)) { |
| 74 | sp_log_err("config", "Invalid var name: %s.", var_node->value); | 76 | sp_log_err("config", "Invalid var name: %s.", var_node->value); |
| 75 | return -1; | 77 | err = -1; goto err; |
| 76 | } | 78 | } |
| 79 | |||
| 77 | var_node->idx = sp_parse_var(idx); | 80 | var_node->idx = sp_parse_var(idx); |
| 78 | 81 | ||
| 79 | if (tree != var_node) { | 82 | if (tree != var_node) { |
| @@ -82,7 +85,19 @@ static int create_var(sp_tree *tree, const char *restrict value, | |||
| 82 | } | 85 | } |
| 83 | tree->next = var_node; | 86 | tree->next = var_node; |
| 84 | } | 87 | } |
| 85 | return 0; | 88 | |
| 89 | if (err) { | ||
| 90 | err: | ||
| 91 | if (free_node_on_error) { | ||
| 92 | sp_tree_free(var_node); | ||
| 93 | } else { | ||
| 94 | var_node->next = var_node->idx = NULL; | ||
| 95 | var_node->value = NULL; | ||
| 96 | var_node->type = UNDEFINED; | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | return err; | ||
| 86 | } | 101 | } |
| 87 | 102 | ||
| 88 | int cmp_tokens(sp_list_node const *const list1, | 103 | int cmp_tokens(sp_list_node const *const list1, |
