sudo

changeset 5411:a09c6812eaec 1.7.2

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.
author Todd C. Miller <Todd.Miller@courtesan.com>
date Fri May 28 10:05:25 2010 -0400 (20 months ago)
parents c17c54dc03b3
children a780aed9db17
files env.c
line diff
     1.1 --- a/env.c	Thu Apr 29 18:47:23 2010 -0400
     1.2 +++ b/env.c	Fri May 28 10:05:25 2010 -0400
     1.3 @@ -317,7 +317,7 @@
     1.4  unsetenv(var)
     1.5      const char *var;
     1.6  {
     1.7 -    char **ep;
     1.8 +    char **ep = env.envp;
     1.9      size_t len;
    1.10  
    1.11      if (strchr(var, '=') != NULL) {
    1.12 @@ -355,13 +355,15 @@
    1.13      }
    1.14  
    1.15      len = strlen(var);
    1.16 -    for (ep = env.envp; *ep; ep++) {
    1.17 +    while (*ep != NULL) {
    1.18  	if (strncmp(var, *ep, len) == 0 && (*ep)[len] == '=') {
    1.19  	    /* Found it; shift remainder + NULL over by one and update len. */
    1.20  	    memmove(ep, ep + 1,
    1.21  		(env.env_len - (ep - env.envp)) * sizeof(char *));
    1.22  	    env.env_len--;
    1.23 -	    break;
    1.24 +	    /* Keep going, could be multiple instances of the var. */
    1.25 +	} else {
    1.26 +	    ep++;
    1.27  	}
    1.28      }
    1.29  #ifndef UNSETENV_VOID
    1.30 @@ -429,6 +431,7 @@
    1.31  {
    1.32      char **ep;
    1.33      size_t len;
    1.34 +    int found = FALSE;
    1.35  
    1.36      /* Make sure there is room for the new entry plus a NULL. */
    1.37      if (env.env_len + 2 > env.env_size) {
    1.38 @@ -447,20 +450,34 @@
    1.39  #endif
    1.40  
    1.41      if (dupcheck) {
    1.42 -	    len = (strchr(str, '=') - str) + 1;
    1.43 -	    for (ep = env.envp; *ep; ep++) {
    1.44 +	len = (strchr(str, '=') - str) + 1;
    1.45 +	for (ep = env.envp; !found && *ep != NULL; ep++) {
    1.46 +	    if (strncmp(str, *ep, len) == 0) {
    1.47 +		if (overwrite)
    1.48 +		    *ep = str;
    1.49 +		found = TRUE;
    1.50 +	    }
    1.51 +	}
    1.52 +	/* Prune out duplicate variables. */
    1.53 +	if (found && overwrite) {
    1.54 +	    while (*ep != NULL) {
    1.55  		if (strncmp(str, *ep, len) == 0) {
    1.56 -		    if (overwrite)
    1.57 -			*ep = str;
    1.58 -		    return;
    1.59 +		    memmove(ep, ep + 1,
    1.60 +			(env.env_len - (ep - env.envp)) * sizeof(char *));
    1.61 +		    env.env_len--;
    1.62 +		} else {
    1.63 +		    ep++;
    1.64  		}
    1.65  	    }
    1.66 -    } else
    1.67 +	}
    1.68 +    }
    1.69 +
    1.70 +    if (!found) {
    1.71  	ep = env.envp + env.env_len;
    1.72 -
    1.73 -    env.env_len++;
    1.74 -    *ep++ = str;
    1.75 -    *ep = NULL;
    1.76 +	env.env_len++;
    1.77 +	*ep++ = str;
    1.78 +	*ep = NULL;
    1.79 +    }
    1.80  }
    1.81  
    1.82  /*