Browse Source

Check for duplicate variables in the environment when setting a value

via setenv() or putenv().  OK miod@
OPENBSD_4_9
millert 14 years ago
parent
commit
9ee6c65862
2 changed files with 24 additions and 11 deletions
  1. +5
    -4
      src/lib/libc/stdlib/getenv.c
  2. +19
    -7
      src/lib/libc/stdlib/setenv.c

+ 5
- 4
src/lib/libc/stdlib/getenv.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: getenv.c,v 1.9 2009/06/03 15:52:16 millert Exp $ */
/* $OpenBSD: getenv.c,v 1.10 2010/08/23 22:31:50 millert Exp $ */
/* /*
* Copyright (c) 1987, 1993 * Copyright (c) 1987, 1993
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
@ -36,8 +36,9 @@ char *__findenv(const char *name, int len, int *offset);
/* /*
* __findenv -- * __findenv --
* Returns pointer to value associated with name, if any, else NULL. * Returns pointer to value associated with name, if any, else NULL.
* Starts searching within the environmental array at offset.
* Sets offset to be the offset of the name/value combination in the * Sets offset to be the offset of the name/value combination in the
* environmental array, for use by setenv(3) and unsetenv(3).
* environmental array, for use by putenv(3), setenv(3) and unsetenv(3).
* Explicitly removes '=' in argument name. * Explicitly removes '=' in argument name.
* *
* This routine *should* be a static; don't use it. * This routine *should* be a static; don't use it.
@ -52,7 +53,7 @@ __findenv(const char *name, int len, int *offset)
if (name == NULL || environ == NULL) if (name == NULL || environ == NULL)
return (NULL); return (NULL);
for (p = environ; (cp = *p) != NULL; ++p) {
for (p = environ + *offset; (cp = *p) != NULL; ++p) {
for (np = name, i = len; i && *cp; i--) for (np = name, i = len; i && *cp; i--)
if (*cp++ != *np++) if (*cp++ != *np++)
break; break;
@ -71,7 +72,7 @@ __findenv(const char *name, int len, int *offset)
char * char *
getenv(const char *name) getenv(const char *name)
{ {
int offset;
int offset = 0;
const char *np; const char *np;
for (np = name; *np && *np != '='; ++np) for (np = name; *np && *np != '='; ++np)


+ 19
- 7
src/lib/libc/stdlib/setenv.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: setenv.c,v 1.12 2010/06/29 04:09:34 naddy Exp $ */
/* $OpenBSD: setenv.c,v 1.13 2010/08/23 22:31:50 millert Exp $ */
/* /*
* Copyright (c) 1987 Regents of the University of California. * Copyright (c) 1987 Regents of the University of California.
* All rights reserved. * All rights reserved.
@ -47,7 +47,7 @@ putenv(char *str)
{ {
char **P, *cp; char **P, *cp;
size_t cnt; size_t cnt;
int offset;
int offset = 0;
for (cp = str; *cp && *cp != '='; ++cp) for (cp = str; *cp && *cp != '='; ++cp)
; ;
@ -57,7 +57,13 @@ putenv(char *str)
} }
if (__findenv(str, (int)(cp - str), &offset) != NULL) { if (__findenv(str, (int)(cp - str), &offset) != NULL) {
environ[offset] = str;
environ[offset++] = str;
/* could be set multiple times */
while (__findenv(str, (int)(cp - str), &offset)) {
for (P = &environ[offset];; ++P)
if (!(*P = *(P + 1)))
break;
}
return (0); return (0);
} }
@ -84,9 +90,9 @@ putenv(char *str)
int int
setenv(const char *name, const char *value, int rewrite) setenv(const char *name, const char *value, int rewrite)
{ {
char *C;
char *C, **P;
const char *np; const char *np;
int l_value, offset;
int l_value, offset = 0;
for (np = name; *np && *np != '='; ++np) for (np = name; *np && *np != '='; ++np)
; ;
@ -99,6 +105,7 @@ setenv(const char *name, const char *value, int rewrite)
l_value = strlen(value); l_value = strlen(value);
if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) {
int tmpoff = offset + 1;
if (!rewrite) if (!rewrite)
return (0); return (0);
#if 0 /* XXX - existing entry may not be writable */ #if 0 /* XXX - existing entry may not be writable */
@ -108,9 +115,14 @@ setenv(const char *name, const char *value, int rewrite)
return (0); return (0);
} }
#endif #endif
/* could be set multiple times */
while (__findenv(name, (int)(np - name), &tmpoff)) {
for (P = &environ[tmpoff];; ++P)
if (!(*P = *(P + 1)))
break;
}
} else { /* create new slot */ } else { /* create new slot */
size_t cnt; size_t cnt;
char **P;
for (P = environ; *P != NULL; P++) for (P = environ; *P != NULL; P++)
; ;
@ -143,7 +155,7 @@ unsetenv(const char *name)
{ {
char **P; char **P;
const char *np; const char *np;
int offset;
int offset = 0;
if (!name || !*name) { if (!name || !*name) {
errno = EINVAL; errno = EINVAL;


Loading…
Cancel
Save