Skip to content

Commit

Permalink
expr: fix memory management
Browse files Browse the repository at this point in the history
Andy Chu's patch from the mailing list, modified slightly to fit
the current source.
http://lists.landley.net/htdig.cgi/toybox-landley.net/2016-March/008113.html
  • Loading branch information
E5ten committed Oct 10, 2019
1 parent 3d0bb23 commit b8c86b4
Showing 1 changed file with 21 additions and 5 deletions.
26 changes: 21 additions & 5 deletions toys/pending/expr.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ config EXPR
GLOBALS(
char **tok; // current token, not on the stack since recursive calls mutate it

char *refree;
struct arg_list *allocated; // list of strings allocated during evaluation
)

// Scalar value. If s != NULL, it's a string, otherwise it's an int.
Expand All @@ -68,6 +68,14 @@ struct value {
long long i;
};

// Keep track of an allocated string.
void track_str(char* str) {
struct arg_list *node = xmalloc(sizeof(struct arg_list));
node->arg = str;
node->next = TT.allocated;
TT.allocated = node;
}

// Get the value as a string.
char *get_str(struct value *v)
{
Expand Down Expand Up @@ -115,8 +123,7 @@ static void re(char *target, char *pattern, struct value *ret)
if (pat.re_nsub>0) {
ret->s = xmprintf("%.*s", (int)(m[1].rm_eo-m[1].rm_so),
target+m[1].rm_so);
if (TT.refree) free(TT.refree);
TT.refree = ret->s;
track_str(ret->s); // free it later
} else assign_int(ret, m[0].rm_eo);
} else {
if (pat.re_nsub>0) ret->s = "";
Expand Down Expand Up @@ -255,7 +262,16 @@ void expr_main(void)
if (ret.s) printf("%s\n", ret.s);
else printf("%lld\n", ret.i);

toys.exitval = is_false(&ret);
int status = is_false(&ret);

// Free all the strings we allocated.
struct arg_list *h, *head = TT.allocated;
while (head) {
h = head;
head = head->next;
free(h->arg); // free the string
free(h); // free the node for tracking the string
}

if (TT.refree) free(TT.refree);
toys.exitval = status;
}

0 comments on commit b8c86b4

Please sign in to comment.