From c3e4d0cf3f1fd24164e0a58db23b86b56c6dc7c8 Mon Sep 17 00:00:00 2001 From: "Arnold D. Robbins" Date: Sun, 8 Sep 2013 12:46:20 +0200 Subject: Fixes based on problems from a static checker. --- ChangeLog | 26 ++++++++++++++++++++++++++ array.c | 2 ++ builtin.c | 5 ++++- cint_array.c | 4 ++++ dfa.c | 3 ++- getopt.c | 2 +- io.c | 3 ++- re.c | 2 +- regcomp.c | 18 +++++++++++++++++- regex_internal.c | 13 ++++++++++++- symbol.c | 9 +++++---- 11 files changed, 76 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 2cec4432..d80680f3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,29 @@ +2013-09-08 Arnold D. Robbins + + Fixes based on reports from a static code checker. Thanks to + Anders Wallin for sending in the list. + + * array.c (asort_actual): Free list if it's not NULL. + * builtin.c (do_sub): Set buf to NULL and assert on it before using + it. + * cint_array.c (cint_array_init): Clamp any value of NHAT from the + environment such that it won't overflow power_two_table when used as + an index. + * dfa.c (parse_bracket_exp): Check that len is in range before using it + to index buf. + * getopt.c (_getopt_internal_r): Change call to alloca to use malloc. + * io.c (socket_open): Init read_len to zero. + (two_way_open): Upon failure to fork, close the slave fd also. + * re.c (research): Init try_backref to false. + * regcomp.c (build_range_exp): Free any items that were allocated in + the case where not all items were. + (build_charclass_op): Same. Init br_token to zero with memset. + (create_tree): Init token t to zero with memset. + * regex_internal.c (re_dfa_add_node): Free any items that were + allocated in the case where not all items were. + * symbol.c (destroy_symbol): On default, break, to fall into releasing + of resources. + 2013-08-29 Arnold D. Robbins * debug.c (HAVE_HISTORY_LIST): Move checks and defines to the top. diff --git a/array.c b/array.c index a0ddf580..37894da5 100644 --- a/array.c +++ b/array.c @@ -848,6 +848,8 @@ asort_actual(int nargs, sort_context_t ctxt) /* source array is empty */ if (dest != NULL && dest != array) assoc_clear(dest); + if (list != NULL) + efree(list); return make_number((AWKNUM) 0); } diff --git a/builtin.c b/builtin.c index b8e24cb3..eb823ac1 100644 --- a/builtin.c +++ b/builtin.c @@ -2955,13 +2955,16 @@ set_how_many: done: DEREF(s); - if ((matches == 0 || (flags & LITERAL) != 0) && buf != NULL) + if ((matches == 0 || (flags & LITERAL) != 0) && buf != NULL) { efree(buf); + buf = NULL; + } if (flags & GENSUB) { if (matches > 0) { /* return the result string */ DEREF(t); + assert(buf != NULL); return make_str_node(buf, textlen, ALREADY_MALLOCED); } diff --git a/cint_array.c b/cint_array.c index 1d34c2f7..3945e6e7 100644 --- a/cint_array.c +++ b/cint_array.c @@ -150,10 +150,14 @@ cint_array_init(NODE *symbol ATTRIBUTE_UNUSED, NODE *subs ATTRIBUTE_UNUSED) { if (symbol == NULL) { long newval; + size_t nelems = (sizeof(power_two_table) / sizeof(power_two_table[0])); /* check relevant environment variables */ if ((newval = getenv_long("NHAT")) > 1 && newval < INT32_BIT) NHAT = newval; + /* don't allow overflow off the end of the table */ + if (NHAT >= nelems) + NHAT = nelems - 2; THRESHOLD = power_two_table[NHAT + 1]; } else null_array(symbol); diff --git a/dfa.c b/dfa.c index 8b79eb77..490a0753 100644 --- a/dfa.c +++ b/dfa.c @@ -1038,7 +1038,8 @@ parse_bracket_exp (void) /* This is in any case an invalid class name. */ str[0] = '\0'; } - str[len] = '\0'; + if (len < BRACKET_BUFFER_SIZE) + str[len] = '\0'; /* Fetch bracket. */ FETCH_WC (c, wc, _("unbalanced [")); diff --git a/getopt.c b/getopt.c index bab52a05..fa258382 100644 --- a/getopt.c +++ b/getopt.c @@ -575,7 +575,7 @@ _getopt_internal_r (int argc, char *const *argv, const char *optstring, || pfound->val != p->val) { /* Second or later nonexact match found. */ - struct option_list *newp = alloca (sizeof (*newp)); + struct option_list *newp = malloc (sizeof (*newp)); newp->p = p; newp->needs_free = 1; newp->next = ambig_list; diff --git a/io.c b/io.c index 59ddd115..e0632d8b 100644 --- a/io.c +++ b/io.c @@ -1463,7 +1463,7 @@ socketopen(int family, int type, const char *localpname, #ifdef MSG_PEEK char buf[10]; struct sockaddr_storage remote_addr; - socklen_t read_len; + socklen_t read_len = 0; if (recvfrom(socket_fd, buf, 1, MSG_PEEK, (struct sockaddr *) & remote_addr, @@ -1915,6 +1915,7 @@ two_way_open(const char *str, struct redirect *rp) case -1: save_errno = errno; close(master); + close(slave); errno = save_errno; return false; diff --git a/re.c b/re.c index e427a8fe..b9db6556 100644 --- a/re.c +++ b/re.c @@ -259,7 +259,7 @@ research(Regexp *rp, char *str, int start, size_t len, int flags) { const char *ret = str; - int try_backref; + int try_backref = false; int need_start; int no_bol; int res; diff --git a/regcomp.c b/regcomp.c index d61a16b6..f3c4587d 100644 --- a/regcomp.c +++ b/regcomp.c @@ -2764,7 +2764,14 @@ build_range_exp (reg_syntax_t syntax, bitset_t sbcset, new_nranges); if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; + { + /* if one is not NULL, free it to avoid leaks */ + if (new_array_start != NULL) + re_free(new_array_start); + if (new_array_end != NULL) + re_free(new_array_end); + return REG_ESPACE; + } mbcset->range_starts = new_array_start; mbcset->range_ends = new_array_end; @@ -3673,6 +3680,13 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, if (BE (sbcset == NULL, 0)) #endif /* not RE_ENABLE_I18N */ { + /* if one is not NULL, free it to avoid leaks */ + if (sbcset != NULL) + free(sbcset); +#ifdef RE_ENABLE_I18N + if (mbcset != NULL) + free(mbcset); +#endif *err = REG_ESPACE; return NULL; } @@ -3715,6 +3729,7 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, #endif /* Build a tree for simple bracket. */ + memset(& br_token, 0, sizeof(br_token)); /* silence "not initialized" errors froms static checkers */ br_token.type = SIMPLE_BRACKET; br_token.opr.sbcset = sbcset; tree = create_token_tree (dfa, NULL, NULL, &br_token); @@ -3805,6 +3820,7 @@ create_tree (re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right, re_token_type_t type) { re_token_t t; + memset(& t, 0, sizeof(t)); /* silence "not initialized" errors froms static checkers */ t.type = type; return create_token_tree (dfa, left, right, &t); } diff --git a/regex_internal.c b/regex_internal.c index 5f77bcb0..c7de18b6 100644 --- a/regex_internal.c +++ b/regex_internal.c @@ -1451,7 +1451,18 @@ re_dfa_add_node (re_dfa_t *dfa, re_token_t token) new_eclosures = re_realloc (dfa->eclosures, re_node_set, new_nodes_alloc); if (BE (new_nexts == NULL || new_indices == NULL || new_edests == NULL || new_eclosures == NULL, 0)) - return -1; + { + /* if any are not NULL, free them, avoid leaks */ + if (new_nexts != NULL) + re_free(new_nexts); + if (new_indices != NULL) + re_free(new_indices); + if (new_edests != NULL) + re_free(new_edests); + if (new_eclosures != NULL) + re_free(new_eclosures); + return -1; + } dfa->nexts = new_nexts; dfa->org_indices = new_indices; dfa->edests = new_edests; diff --git a/symbol.c b/symbol.c index 2b5e2bbd..fe297d22 100644 --- a/symbol.c +++ b/symbol.c @@ -221,9 +221,10 @@ remove_symbol(NODE *r) } -/* destroy_symbol --- remove a symbol from symbol table -* and free all associated memory. -*/ +/* + * destroy_symbol --- remove a symbol from symbol table + * and free all associated memory. + */ void destroy_symbol(NODE *r) @@ -262,7 +263,7 @@ destroy_symbol(NODE *r) default: /* Node_param_list -- YYABORT */ - return; + break; /* use break so that storage is freed */ } efree(r->vname); -- cgit v1.2.3