diff options
author | Arnold D. Robbins <arnold@skeeve.com> | 2020-01-08 20:40:45 +0200 |
---|---|---|
committer | Arnold D. Robbins <arnold@skeeve.com> | 2020-01-08 20:40:45 +0200 |
commit | 660a55b365e4ee22f3f0efe69c887e2fd1f71303 (patch) | |
tree | 5c56f2d517b145627e1d637676d2b6177e6ad168 | |
parent | d0b68138521e670178068999dc308ce5beace7ef (diff) | |
download | gawk-660a55b365e4ee22f3f0efe69c887e2fd1f71303.tar.gz |
Fix a number of memory leaks.
-rw-r--r-- | ChangeLog | 16 | ||||
-rw-r--r-- | builtin.c | 46 | ||||
-rw-r--r-- | debug.c | 3 | ||||
-rw-r--r-- | field.c | 7 | ||||
-rw-r--r-- | interpret.h | 5 | ||||
-rw-r--r-- | test/ChangeLog | 5 | ||||
-rw-r--r-- | test/indirectbuiltin.awk | 4 | ||||
-rw-r--r-- | test/numrange.awk | 4 | ||||
-rw-r--r-- | test/numrange.ok | 4 |
9 files changed, 78 insertions, 16 deletions
@@ -1,3 +1,19 @@ +2020-01-08 Arnold D. Robbins <arnold@skeeve.com> + + Fix a number of subtle memory leaks. Thanks to the + combination of MEMDEBUG and valgrind for finding them. + + * builtin.c (do_print): Unref tmp if force_string_ofmt + returned something different. + (call_sub, call_match, call_split_func): Free any + created regexp. + * debug.c (do_eval): Free the node holding the @eval function + when done with it. + * field.c (init_fields): Create fields_arr[0] and Nnull_field + in a rational fashion. + * interpret.h (Op_assign_concat): Handle newly created node + better. + 2019-12-22 Arnold D. Robbins <arnold@skeeve.com> * config.guess: Updated from GNULIB. @@ -2270,6 +2270,8 @@ do_print(int nargs, int redirtype) // Let force_string_ofmt handle checking if things // are already valid. args_array[i] = force_string_ofmt(tmp); + if (args_array[i] != tmp) + DEREF(tmp); } if (redir_exp != NULL) { @@ -3236,6 +3238,7 @@ call_sub(const char *name, int nargs) flags = GSUB; } + bool need_free = false; if (flags == 0 || flags == GSUB) { /* sub or gsub */ if (nargs != 2) @@ -3250,8 +3253,10 @@ call_sub(const char *name, int nargs) */ if ((regex->flags & REGEX) != 0) regex = regex->typed_re; - else + else { regex = make_regnode(Node_regex, regex); + need_free = true; + } PUSH(regex); PUSH(replace); lhs = r_get_field(zero, (Func_ptr *) 0, true); @@ -3277,8 +3282,10 @@ call_sub(const char *name, int nargs) */ if ((regex->flags & REGEX) != 0) regex = regex->typed_re; - else + else { regex = make_regnode(Node_regex, regex); + need_free = true; + } PUSH(regex); PUSH(replace); PUSH(glob_flag); @@ -3295,6 +3302,14 @@ call_sub(const char *name, int nargs) unref(zero); result = do_sub(nargs, flags); + + if (need_free) { + refree(regex->re_reg[0]); + if (regex->re_reg[1] != NULL) + refree(regex->re_reg[1]); + freenode(regex); + } + if (flags != GENSUB) reset_record(); return result; @@ -3315,10 +3330,13 @@ call_match(int nargs) /* Don't need to pop the string just to push it back ... */ + bool need_free = false; if ((regex->flags & REGEX) != 0) regex = regex->typed_re; - else + else { regex = make_regnode(Node_regex, regex); + need_free = true; + } PUSH(regex); @@ -3326,6 +3344,14 @@ call_match(int nargs) PUSH(array); result = do_match(nargs); + + if (need_free) { + refree(regex->re_reg[0]); + if (regex->re_reg[1] != NULL) + refree(regex->re_reg[1]); + freenode(regex); + } + return result; } @@ -3345,18 +3371,23 @@ call_split_func(const char *name, int nargs) if (nargs == 4) seps = POP(); + bool need_free = false; if (nargs >= 3) { regex = POP_STRING(); if ((regex->flags & REGEX) != 0) regex = regex->typed_re; - else + else { regex = make_regnode(Node_regex, regex); + need_free = true; + } } else { if (name[0] == 's') { regex = make_regnode(Node_regex, FS_node->var_value); regex->re_flags |= FS_DFLT; } else regex = make_regnode(Node_regex, FPAT_node->var_value); + + need_free = true; nargs++; } @@ -3369,6 +3400,13 @@ call_split_func(const char *name, int nargs) result = (name[0] == 's') ? do_split(nargs) : do_patsplit(nargs); + if (need_free) { + refree(regex->re_reg[0]); + if (regex->re_reg[1] != NULL) + refree(regex->re_reg[1]); + freenode(regex); + } + return result; } @@ -5718,6 +5718,9 @@ do_eval(CMDARG *arg, int cmd ATTRIBUTE_UNUSED) unref(s); } + free(f->vname); + freenode(f); + free_srcfile(the_source); return false; @@ -94,16 +94,13 @@ init_fields() { emalloc(fields_arr, NODE **, sizeof(NODE *), "init_fields"); - getnode(fields_arr[0]); - *fields_arr[0] = *Nnull_string; + fields_arr[0] = make_string("", 0); fields_arr[0]->flags |= NULL_FIELD; parse_extent = fields_arr[0]->stptr; save_FS = dupnode(FS_node->var_value); - getnode(Null_field); - *Null_field = *Nnull_string; - Null_field->valref = 1; + Null_field = make_string("", 0); Null_field->flags = (STRCUR|STRING|NULL_FIELD); /* do not set MALLOC */ field0_valid = true; diff --git a/interpret.h b/interpret.h index 6cfff3a6..4a7979bd 100644 --- a/interpret.h +++ b/interpret.h @@ -741,7 +741,10 @@ mod: if (t1 != *lhs) { unref(*lhs); - *lhs = dupnode(t1); + if (t1->valref == 1) + *lhs = t1; + else + *lhs = dupnode(t1); } if (t1 != t2 && t1->valref == 1 && (t1->flags & (MALLOC|MPFN|MPZN)) == MALLOC) { diff --git a/test/ChangeLog b/test/ChangeLog index 9ff97b2e..f0eac9bd 100644 --- a/test/ChangeLog +++ b/test/ChangeLog @@ -1,3 +1,8 @@ +2020-01-08 Arnold D. Robbins <arnold@skeeve.com> + + * indirectbuiltin.awk, numrange.awk, numrange.ok: Changes + after code changes. + 2019-11-09 Alexey Pawlow <alexey.pawlow@gmail.com> * Makefile.am (mbprintf5): Add check for MSYS. diff --git a/test/indirectbuiltin.awk b/test/indirectbuiltin.awk index c9e75217..8ca8f6c6 100644 --- a/test/indirectbuiltin.awk +++ b/test/indirectbuiltin.awk @@ -198,10 +198,10 @@ BEGIN { # regexp functions fun = "match" - b1 = match("o+", "fooob") + b1 = match("fooob", "o+") rstart = RSTART rlength = RLENGTH - i1 = @fun("o+", "fooob") + i1 = @fun("fooob", "o+") print_result("regexp", fun, b1, i1) if (rstart != RSTART) { printf("match: failure: biRSTART (%d) != iRSTART (%d)\n", diff --git a/test/numrange.awk b/test/numrange.awk index 3ad2cab5..4cb62602 100644 --- a/test/numrange.awk +++ b/test/numrange.awk @@ -1,5 +1,5 @@ BEGIN { n = split("-1.2e+931 1.2e+931", a) - for (i=1; i<=n; ++i) - print a[i], +a[i] + for (i = 1; i <= n; ++i) + print a[i], +a[i], -a[i] } diff --git a/test/numrange.ok b/test/numrange.ok index 73210bd3..1d747530 100644 --- a/test/numrange.ok +++ b/test/numrange.ok @@ -1,2 +1,2 @@ --1.2e+931 -inf -1.2e+931 +inf +-1.2e+931 -inf +inf +1.2e+931 +inf -inf |