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