diff options
author | millert <> | 2010-08-23 22:31:50 +0000 |
---|---|---|
committer | millert <> | 2010-08-23 22:31:50 +0000 |
commit | 7242e103c3ca65b3f003c382301a3d65fe40846e (patch) | |
tree | 56ce07a012b5a620934d84e0ff9d7fb119096762 | |
parent | b3f615278798dc6689163d9c4243572a0011a133 (diff) | |
download | openbsd-7242e103c3ca65b3f003c382301a3d65fe40846e.tar.gz openbsd-7242e103c3ca65b3f003c382301a3d65fe40846e.tar.bz2 openbsd-7242e103c3ca65b3f003c382301a3d65fe40846e.zip |
Check for duplicate variables in the environment when setting a value
via setenv() or putenv(). OK miod@
-rw-r--r-- | src/lib/libc/stdlib/getenv.c | 9 | ||||
-rw-r--r-- | src/lib/libc/stdlib/setenv.c | 26 |
2 files changed, 24 insertions, 11 deletions
diff --git a/src/lib/libc/stdlib/getenv.c b/src/lib/libc/stdlib/getenv.c index 5aff11c61a..fd8482e9e3 100644 --- a/src/lib/libc/stdlib/getenv.c +++ b/src/lib/libc/stdlib/getenv.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: getenv.c,v 1.9 2009/06/03 15:52:16 millert Exp $ */ | 1 | /* $OpenBSD: getenv.c,v 1.10 2010/08/23 22:31:50 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1987, 1993 | 3 | * Copyright (c) 1987, 1993 |
4 | * The Regents of the University of California. All rights reserved. | 4 | * The Regents of the University of California. All rights reserved. |
@@ -36,8 +36,9 @@ char *__findenv(const char *name, int len, int *offset); | |||
36 | /* | 36 | /* |
37 | * __findenv -- | 37 | * __findenv -- |
38 | * Returns pointer to value associated with name, if any, else NULL. | 38 | * Returns pointer to value associated with name, if any, else NULL. |
39 | * Starts searching within the environmental array at offset. | ||
39 | * Sets offset to be the offset of the name/value combination in the | 40 | * Sets offset to be the offset of the name/value combination in the |
40 | * environmental array, for use by setenv(3) and unsetenv(3). | 41 | * environmental array, for use by putenv(3), setenv(3) and unsetenv(3). |
41 | * Explicitly removes '=' in argument name. | 42 | * Explicitly removes '=' in argument name. |
42 | * | 43 | * |
43 | * This routine *should* be a static; don't use it. | 44 | * This routine *should* be a static; don't use it. |
@@ -52,7 +53,7 @@ __findenv(const char *name, int len, int *offset) | |||
52 | 53 | ||
53 | if (name == NULL || environ == NULL) | 54 | if (name == NULL || environ == NULL) |
54 | return (NULL); | 55 | return (NULL); |
55 | for (p = environ; (cp = *p) != NULL; ++p) { | 56 | for (p = environ + *offset; (cp = *p) != NULL; ++p) { |
56 | for (np = name, i = len; i && *cp; i--) | 57 | for (np = name, i = len; i && *cp; i--) |
57 | if (*cp++ != *np++) | 58 | if (*cp++ != *np++) |
58 | break; | 59 | break; |
@@ -71,7 +72,7 @@ __findenv(const char *name, int len, int *offset) | |||
71 | char * | 72 | char * |
72 | getenv(const char *name) | 73 | getenv(const char *name) |
73 | { | 74 | { |
74 | int offset; | 75 | int offset = 0; |
75 | const char *np; | 76 | const char *np; |
76 | 77 | ||
77 | for (np = name; *np && *np != '='; ++np) | 78 | for (np = name; *np && *np != '='; ++np) |
diff --git a/src/lib/libc/stdlib/setenv.c b/src/lib/libc/stdlib/setenv.c index 89d1e88911..089ab92d38 100644 --- a/src/lib/libc/stdlib/setenv.c +++ b/src/lib/libc/stdlib/setenv.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: setenv.c,v 1.12 2010/06/29 04:09:34 naddy Exp $ */ | 1 | /* $OpenBSD: setenv.c,v 1.13 2010/08/23 22:31:50 millert Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1987 Regents of the University of California. | 3 | * Copyright (c) 1987 Regents of the University of California. |
4 | * All rights reserved. | 4 | * All rights reserved. |
@@ -47,7 +47,7 @@ putenv(char *str) | |||
47 | { | 47 | { |
48 | char **P, *cp; | 48 | char **P, *cp; |
49 | size_t cnt; | 49 | size_t cnt; |
50 | int offset; | 50 | int offset = 0; |
51 | 51 | ||
52 | for (cp = str; *cp && *cp != '='; ++cp) | 52 | for (cp = str; *cp && *cp != '='; ++cp) |
53 | ; | 53 | ; |
@@ -57,7 +57,13 @@ putenv(char *str) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | if (__findenv(str, (int)(cp - str), &offset) != NULL) { | 59 | if (__findenv(str, (int)(cp - str), &offset) != NULL) { |
60 | environ[offset] = str; | 60 | environ[offset++] = str; |
61 | /* could be set multiple times */ | ||
62 | while (__findenv(str, (int)(cp - str), &offset)) { | ||
63 | for (P = &environ[offset];; ++P) | ||
64 | if (!(*P = *(P + 1))) | ||
65 | break; | ||
66 | } | ||
61 | return (0); | 67 | return (0); |
62 | } | 68 | } |
63 | 69 | ||
@@ -84,9 +90,9 @@ putenv(char *str) | |||
84 | int | 90 | int |
85 | setenv(const char *name, const char *value, int rewrite) | 91 | setenv(const char *name, const char *value, int rewrite) |
86 | { | 92 | { |
87 | char *C; | 93 | char *C, **P; |
88 | const char *np; | 94 | const char *np; |
89 | int l_value, offset; | 95 | int l_value, offset = 0; |
90 | 96 | ||
91 | for (np = name; *np && *np != '='; ++np) | 97 | for (np = name; *np && *np != '='; ++np) |
92 | ; | 98 | ; |
@@ -99,6 +105,7 @@ setenv(const char *name, const char *value, int rewrite) | |||
99 | 105 | ||
100 | l_value = strlen(value); | 106 | l_value = strlen(value); |
101 | if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { | 107 | if ((C = __findenv(name, (int)(np - name), &offset)) != NULL) { |
108 | int tmpoff = offset + 1; | ||
102 | if (!rewrite) | 109 | if (!rewrite) |
103 | return (0); | 110 | return (0); |
104 | #if 0 /* XXX - existing entry may not be writable */ | 111 | #if 0 /* XXX - existing entry may not be writable */ |
@@ -108,9 +115,14 @@ setenv(const char *name, const char *value, int rewrite) | |||
108 | return (0); | 115 | return (0); |
109 | } | 116 | } |
110 | #endif | 117 | #endif |
118 | /* could be set multiple times */ | ||
119 | while (__findenv(name, (int)(np - name), &tmpoff)) { | ||
120 | for (P = &environ[tmpoff];; ++P) | ||
121 | if (!(*P = *(P + 1))) | ||
122 | break; | ||
123 | } | ||
111 | } else { /* create new slot */ | 124 | } else { /* create new slot */ |
112 | size_t cnt; | 125 | size_t cnt; |
113 | char **P; | ||
114 | 126 | ||
115 | for (P = environ; *P != NULL; P++) | 127 | for (P = environ; *P != NULL; P++) |
116 | ; | 128 | ; |
@@ -143,7 +155,7 @@ unsetenv(const char *name) | |||
143 | { | 155 | { |
144 | char **P; | 156 | char **P; |
145 | const char *np; | 157 | const char *np; |
146 | int offset; | 158 | int offset = 0; |
147 | 159 | ||
148 | if (!name || !*name) { | 160 | if (!name || !*name) { |
149 | errno = EINVAL; | 161 | errno = EINVAL; |