diff options
author | scf <scf@FreeBSD.org> | 2007-07-06 04:04:58 +0000 |
---|---|---|
committer | scf <scf@FreeBSD.org> | 2007-07-06 04:04:58 +0000 |
commit | 667a20c9f2be44a1dbbd965f877be28d64f34db1 (patch) | |
tree | 9a0b26209392097b99c382d498042c295f556fbf | |
parent | 7a16dbe954b1adf5640a179adfe8c6d0773df1d5 (diff) | |
download | FreeBSD-src-667a20c9f2be44a1dbbd965f877be28d64f34db1.zip FreeBSD-src-667a20c9f2be44a1dbbd965f877be28d64f34db1.tar.gz |
Take care that the input to setenv() may actually be a pointer straight
from environ; make a copy before manipulating it and passing it to
setenv().
Approved by: wes
Approved by: re (kensmith)
-rw-r--r-- | bin/sh/var.c | 42 |
1 files changed, 28 insertions, 14 deletions
diff --git a/bin/sh/var.c b/bin/sh/var.c index afb3c86..6f7c578 100644 --- a/bin/sh/var.c +++ b/bin/sh/var.c @@ -278,6 +278,30 @@ localevar(char *s) return 0; } + +/* + * Sets/unsets an environment variable from a pointer that may actually be a + * pointer into environ where the string should not be manipulated. + */ +static void +change_env(char *s, int set) +{ + char *eqp; + char *ss; + + ss = savestr(s); + if ((eqp = strchr(ss, '=')) != NULL) + *eqp = '\0'; + if (set && eqp != NULL) + (void) setenv(ss, eqp + 1, 1); + else + (void) unsetenv(ss); + ckfree(ss); + + return; +} + + /* * Same as setvar except that the variable and value are passed in * the first argument as name=value. Since the first argument will @@ -289,7 +313,6 @@ void setvareq(char *s, int flags) { struct var *vp, **vpp; - char *p; int len; if (aflag) @@ -320,10 +343,7 @@ setvareq(char *s, int flags) if (vp == &vmpath || (vp == &vmail && ! mpathset())) chkmail(1); if ((vp->flags & VEXPORT) && localevar(s)) { - p = strchr(s, '='); - *p = '\0'; - (void) setenv(s, p + 1, 1); - *p = '='; + change_env(s, 1); (void) setlocale(LC_ALL, ""); } INTON; @@ -339,10 +359,7 @@ setvareq(char *s, int flags) INTOFF; *vpp = vp; if ((vp->flags & VEXPORT) && localevar(s)) { - p = strchr(s, '='); - *p = '\0'; - (void) setenv(s, p + 1, 1); - *p = '='; + change_env(s, 1); (void) setlocale(LC_ALL, ""); } INTON; @@ -603,10 +620,7 @@ exportcmd(int argc, char **argv) vp->flags |= flag; if ((vp->flags & VEXPORT) && localevar(vp->text)) { - p = strchr(vp->text, '='); - *p = '\0'; - (void) setenv(vp->text, p + 1, 1); - *p = '='; + change_env(vp->text, 1); (void) setlocale(LC_ALL, ""); } goto found; @@ -798,7 +812,7 @@ unsetvar(char *s) if (*(strchr(vp->text, '=') + 1) != '\0') setvar(s, nullstr, 0); if ((vp->flags & VEXPORT) && localevar(vp->text)) { - unsetenv(s); + change_env(s, 0); setlocale(LC_ALL, ""); } vp->flags &= ~VEXPORT; |