ash: [EXPAND] Fix ifsfirst/ifslastp leak
No binary (build failed)
—
(log yok)
| @@ -5663,19 +5663,22 @@ ifsbreakup(char *string, struct arglist *arglist) | |
| static void | |
| ifsfree(void) | |
| { | |
| - | struct ifsregion *p; |
| + | struct ifsregion *p = ifsfirst.next; |
| + | |
| + | if (!p) |
| + | goto out; |
| INT_OFF; | |
| - | p = ifsfirst.next; |
| do { | |
| struct ifsregion *ifsp; | |
| ifsp = p->next; | |
| free(p); | |
| p = ifsp; | |
| } while (p); | |
| - | ifslastp = NULL; |
| ifsfirst.next = NULL; | |
| INT_ON; | |
| + | out: |
| + | ifslastp = NULL; |
| } | |
| static size_t | |
| @@ -5989,6 +5992,7 @@ evalbackcmd(union node *n, struct backcmd *result) | |
| * For now, preserve bash-like behavior, it seems to be somewhat more useful: | |
| */ | |
| eflag = 0; | |
| + | ifsfree(); |
| evaltree(n, EV_EXIT); /* actually evaltreenr... */ | |
| /* NOTREACHED */ | |
| } | |
| @@ -7296,15 +7300,14 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |
| argbackq = arg->narg.backquote; | |
| STARTSTACKSTR(expdest); | |
| - | ifsfirst.next = NULL; |
| - | ifslastp = NULL; |
| TRACE(("expandarg: argstr('%s',flags:%x)\n", arg->narg.text, flag)); | |
| argstr(arg->narg.text, flag, | |
| /* var_str_list: */ arglist ? arglist->list : NULL); | |
| p = _STPUTC('\0', expdest); | |
| expdest = p - 1; | |
| if (arglist == NULL) { | |
| - | return; /* here document expanded */ |
| + | /* here document expanded */ |
| + | goto out; |
| } | |
| p = grabstackstr(p); | |
| TRACE(("expandarg: p:'%s'\n", p)); | |
| @@ -7327,13 +7330,14 @@ expandarg(union node *arg, struct arglist *arglist, int flag) | |
| *exparg.lastp = sp; | |
| exparg.lastp = &sp->next; | |
| } | |
| - | if (ifsfirst.next) |
| - | ifsfree(); |
| *exparg.lastp = NULL; | |
| if (exparg.list) { | |
| *arglist->lastp = exparg.list; | |
| arglist->lastp = exparg.lastp; | |
| } | |
| + | |
| + | out: |
| + | ifsfree(); |
| } | |
| /* | |
| @@ -7367,10 +7371,10 @@ casematch(union node *pattern, char *val) | |
| setstackmark(&smark); | |
| argbackq = pattern->narg.backquote; | |
| STARTSTACKSTR(expdest); | |
| - | ifslastp = NULL; |
| argstr(pattern->narg.text, EXP_TILDE | EXP_CASE, | |
| /* var_str_list: */ NULL); | |
| STACKSTRNUL(expdest); | |
| + | ifsfree(); |
| result = patmatch(stackblock(), val); | |
| popstackmark(&smark); | |
| return result; | |
| @@ -13293,6 +13297,7 @@ read_profile(const char *name) | |
| /* | |
| * This routine is called when an error or an interrupt occurs in an | |
| * interactive shell and control is returned to the main command loop. | |
| + | * (In dash, this function is auto-generated by build machinery). |
| */ | |
| static void | |
| reset(void) | |
| @@ -13300,13 +13305,19 @@ reset(void) | |
| /* from eval.c: */ | |
| evalskip = 0; | |
| loopnest = 0; | |
| + | |
| + | /* from expand.c: */ |
| + | ifsfree(); |
| + | |
| /* from input.c: */ | |
| g_parsefile->left_in_buffer = 0; | |
| g_parsefile->left_in_line = 0; /* clear input buffer */ | |
| popallfiles(); | |
| + | |
| /* from parser.c: */ | |
| tokpushback = 0; | |
| checkkwd = 0; | |
| + | |
| /* from redir.c: */ | |
| while (redirlist) | |
| popredir(/*drop:*/ 0, /*restore:*/ 0); | |