>From 64fa84073cf0d8b0f8d604b88e92b0a1450ccdc4 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Mon, 18 Jan 2016 10:31:07 -0800 Subject: [PATCH 1/3] regex: fix memory leaks Problem and draft fix reported by Aharon Robbins in: http://lists.gnu.org/archive/html/bug-gnulib/2016-01/msg00082.html * lib/regcomp.c (build_range_exp, build_charclass_op): * lib/regex_internal.c (re_dfa_add_node): Fix memory leak on failure. --- ChangeLog | 9 +++++++++ lib/regcomp.c | 27 +++++++++++++-------------- lib/regex_internal.c | 8 +++++++- 3 files changed, 29 insertions(+), 15 deletions(-) diff --git a/ChangeLog b/ChangeLog index fac13e6..ecb0746 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2016-01-18 Paul Eggert + + regex: fix memory leaks + Problem and draft fix reported by Aharon Robbins in: + http://lists.gnu.org/archive/html/bug-gnulib/2016-01/msg00082.html + * lib/regcomp.c (build_range_exp, build_charclass_op): + * lib/regex_internal.c (re_dfa_add_node): + Fix memory leak on failure. + 2016-01-18 Pádraig Brady fts: don't unconditionally use leaf optimization for NFS diff --git a/lib/regcomp.c b/lib/regcomp.c index 43999d0..0369f26 100644 --- a/lib/regcomp.c +++ b/lib/regcomp.c @@ -2779,7 +2779,11 @@ build_range_exp (const reg_syntax_t syntax, new_nranges); if (BE (new_array_start == NULL || new_array_end == NULL, 0)) - return REG_ESPACE; + { + re_free (new_array_start); + re_free (new_array_end); + return REG_ESPACE; + } mbcset->range_starts = new_array_start; mbcset->range_ends = new_array_end; @@ -3676,26 +3680,21 @@ build_charclass_op (re_dfa_t *dfa, RE_TRANSLATE_TYPE trans, bin_tree_t *tree; sbcset = (re_bitset_ptr_t) calloc (sizeof (bitset_t), 1); -#ifdef RE_ENABLE_I18N - mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); -#endif /* RE_ENABLE_I18N */ - -#ifdef RE_ENABLE_I18N - if (BE (sbcset == NULL || mbcset == NULL, 0)) -#else /* not RE_ENABLE_I18N */ if (BE (sbcset == NULL, 0)) -#endif /* not RE_ENABLE_I18N */ { *err = REG_ESPACE; return NULL; } - - if (non_match) - { #ifdef RE_ENABLE_I18N - mbcset->non_match = 1; -#endif /* not RE_ENABLE_I18N */ + mbcset = (re_charset_t *) calloc (sizeof (re_charset_t), 1); + if (BE (mbcset == NULL, 0)) + { + re_free (sbcset); + *err = REG_ESPACE; + return NULL; } + mbcset->non_match = non_match; +#endif /* RE_ENABLE_I18N */ /* We don't care the syntax in this case. */ ret = build_charclass (trans, sbcset, diff --git a/lib/regex_internal.c b/lib/regex_internal.c index fd20407..9dc7124 100644 --- a/lib/regex_internal.c +++ b/lib/regex_internal.c @@ -1428,7 +1428,13 @@ 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 REG_MISSING; + { + re_free (new_nexts); + re_free (new_indices); + re_free (new_edests); + re_free (new_eclosures); + return REG_MISSING; + } dfa->nexts = new_nexts; dfa->org_indices = new_indices; dfa->edests = new_edests; -- 2.5.0