summary refs log tree commit diff
path: root/src/expand.c
diff options
context:
space:
mode:
authorHerbert Xu <herbert@gondor.apana.org.au>2010-09-08 20:07:26 +0800
committerHerbert Xu <herbert@gondor.apana.org.au>2010-09-08 20:07:26 +0800
commitf42e443bb511ed3224f09b4fcf0772438ebdbbfa (patch)
treefc2523d1f399d4d4a8a6432e3855de649ddf7346 /src/expand.c
parent[JOBS] Debug compile fix (diff)
downloaddash-f42e443bb511ed3224f09b4fcf0772438ebdbbfa.tar.gz
dash-f42e443bb511ed3224f09b4fcf0772438ebdbbfa.zip
[EXPAND] Fix ifsfirst/ifslastp leak
As it stands expandarg may return with a non-NULL ifslastp which
then confuses any subsequent ifsbreakup user that doesn't clear
it directly.

What's worse, if we get interrupted before we hit ifsfree in
expandarg we will leak memory.

This patch fixes this by always calling ifsfree in expandarg
thus ensuring that ifslastp is always NULL on the normal path.
It also adds an ifsfree call to the RESET path to ensure that
memory isn't leaked.

Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Diffstat (limited to 'src/expand.c')
-rw-r--r--src/expand.c30
1 files changed, 19 insertions, 11 deletions
diff --git a/src/expand.c b/src/expand.c
index f2f964c..d6c6416 100644
--- a/src/expand.c
+++ b/src/expand.c
@@ -117,7 +117,6 @@ STATIC char *evalvar(char *, int);
 STATIC size_t strtodest(const char *, const char *, int);
 STATIC void memtodest(const char *, size_t, const char *, int);
 STATIC ssize_t varvalue(char *, int, int);
-STATIC void ifsfree(void);
 STATIC void expandmeta(struct strlist *, int);
 #ifdef HAVE_GLOB
 STATIC void addglob(const glob_t *);
@@ -191,8 +190,6 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
 
 	argbackq = arg->narg.backquote;
 	STARTSTACKSTR(expdest);
-	ifsfirst.next = NULL;
-	ifslastp = NULL;
 	argstr(arg->narg.text, flag);
 	p = _STPUTC('\0', expdest);
 	expdest = p - 1;
@@ -215,8 +212,7 @@ expandarg(union node *arg, struct arglist *arglist, int flag)
 		*exparg.lastp = sp;
 		exparg.lastp = &sp->next;
 	}
-	if (ifsfirst.next)
-		ifsfree();
+	ifsfree();
 	*exparg.lastp = NULL;
 	if (exparg.list) {
 		*arglist->lastp = exparg.list;
@@ -1108,22 +1104,25 @@ add:
 	arglist->lastp = &sp->next;
 }
 
-STATIC void
-ifsfree(void)
+void ifsfree(void)
 {
-	struct ifsregion *p;
+	struct ifsregion *p = ifsfirst.next;
+
+	if (!p)
+		goto out;
 
 	INTOFF;
-	p = ifsfirst.next;
 	do {
 		struct ifsregion *ifsp;
 		ifsp = p->next;
 		ckfree(p);
 		p = ifsp;
 	} while (p);
-	ifslastp = NULL;
 	ifsfirst.next = NULL;
 	INTON;
+
+out:
+	ifslastp = NULL;
 }
 
 
@@ -1678,7 +1677,6 @@ casematch(union node *pattern, char *val)
 	setstackmark(&smark);
 	argbackq = pattern->narg.backquote;
 	STARTSTACKSTR(expdest);
-	ifslastp = NULL;
 	argstr(pattern->narg.text, EXP_TILDE | EXP_CASE);
 	STACKSTRNUL(expdest);
 	result = patmatch(stackblock(), val);
@@ -1718,3 +1716,13 @@ varunset(const char *end, const char *var, const char *umsg, int varflags)
 	}
 	sh_error("%.*s: %s%s", end - var - 1, var, msg, tail);
 }
+
+#ifdef mkinit
+
+INCLUDE "expand.h"
+
+RESET {
+	ifsfree();
+}
+
+#endif
an title='2021-01-12 16:55:34 -0500'>2021-01-12Use mandoc and htagml for bin htmlJune McEnroe 2021-01-12Add htagmlJune McEnroe 2021-01-12Replace causal.agency with a simple mdoc pageJune McEnroe 2021-01-11Publish "Using vi"June McEnroe 2021-01-11Enable diff.colorMovedJune McEnroe 2021-01-10Set less search case-insensitiveJune McEnroe 2021-01-10Set EXINITJune McEnroe 2021-01-09Add c -t flag to print expression typeJune McEnroe 2021-01-05Update taglineJune McEnroe