Handle duplicate variables in the environment. For unsetenv(),

keep looking even after remove the first instance.  For sudo_putenv(),
check for and remove dupes after we replace an existing value.
This commit is contained in:
Todd C. Miller
2010-05-28 09:42:50 -04:00
parent 12aedc6757
commit c31ed2cd22

View File

@@ -336,7 +336,7 @@ int
#endif #endif
unsetenv(const char *var) unsetenv(const char *var)
{ {
char **ep; char **ep = env.envp;
size_t len; size_t len;
if (strchr(var, '=') != NULL) { if (strchr(var, '=') != NULL) {
@@ -354,13 +354,15 @@ unsetenv(const char *var)
#endif #endif
len = strlen(var); len = strlen(var);
for (ep = env.envp; *ep; ep++) { while (*ep != NULL) {
if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') { if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
/* Found it; shift remainder + NULL over by one and update len. */ /* Found it; shift remainder + NULL over by one and update len. */
memmove(ep, ep + 1, memmove(ep, ep + 1,
(env.env_len - (ep - env.envp)) * sizeof(char *)); (env.env_len - (ep - env.envp)) * sizeof(char *));
env.env_len--; env.env_len--;
break; /* Keep going, could be multiple instances of the var. */
} else {
ep++;
} }
} }
#ifndef UNSETENV_VOID #ifndef UNSETENV_VOID
@@ -401,6 +403,7 @@ sudo_putenv(char *str, int dupcheck, int overwrite)
{ {
char **ep; char **ep;
size_t len; size_t len;
int found = FALSE;
/* Make sure there is room for the new entry plus a NULL. */ /* Make sure there is room for the new entry plus a NULL. */
if (env.env_len + 2 > env.env_size) { if (env.env_len + 2 > env.env_size) {
@@ -418,20 +421,34 @@ sudo_putenv(char *str, int dupcheck, int overwrite)
#endif #endif
if (dupcheck) { if (dupcheck) {
len = (strchr(str, '=') - str) + 1; len = (strchr(str, '=') - str) + 1;
for (ep = env.envp; *ep; ep++) { for (ep = env.envp; !found && *ep != NULL; ep++) {
if (strncmp(str, *ep, len) == 0) {
if (overwrite)
*ep = str;
found = TRUE;
}
}
/* Prune out duplicate variables. */
if (found && overwrite) {
while (*ep != NULL) {
if (strncmp(str, *ep, len) == 0) { if (strncmp(str, *ep, len) == 0) {
if (overwrite) memmove(ep, ep + 1,
*ep = str; (env.env_len - (ep - env.envp)) * sizeof(char *));
return; env.env_len--;
} else {
ep++;
} }
} }
} else }
ep = env.envp + env.env_len; }
env.env_len++; if (!found) {
*ep++ = str; ep = env.envp + env.env_len;
*ep = NULL; env.env_len++;
*ep++ = str;
*ep = NULL;
}
} }
/* /*