diff options
author | Ron Yorston <rmy@pobox.com> | 2020-08-21 09:42:00 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2020-08-21 09:59:10 +0100 |
commit | 90418d34c5517691fa78d90e632fa5f9f6b35c03 (patch) | |
tree | 92f6931d18b74e11db1905dd6a37eb25bff600aa | |
parent | 871115c02a7adead20939c3f68371d92127861b8 (diff) | |
download | busybox-w32-90418d34c5517691fa78d90e632fa5f9f6b35c03.tar.gz busybox-w32-90418d34c5517691fa78d90e632fa5f9f6b35c03.tar.bz2 busybox-w32-90418d34c5517691fa78d90e632fa5f9f6b35c03.zip |
win32: allow putenv() to set empty values
WIN32 _putenv() can't set an environment variable with an empty
value because 'NAME=' is treated as a request to delete the variable.
Allow mingw_putenv() to set an empty value by first setting a fake
value and then truncating it.
This problem has always been present in mingw_putenv() but it became
particularly pressing when ash started treating all applets as NOEXEC.
The environment of NOEXEC applets is created by clearing the current
environment and using putenv() to set a new one from the shell
variables. Empty variable were not being set.
See GitHub issue #197.
-rw-r--r-- | win32/env.c | 22 |
1 files changed, 18 insertions, 4 deletions
diff --git a/win32/env.c b/win32/env.c index a7ab7851a..4d4e9c8fd 100644 --- a/win32/env.c +++ b/win32/env.c | |||
@@ -78,16 +78,30 @@ int clearenv(void) | |||
78 | 78 | ||
79 | int mingw_putenv(const char *env) | 79 | int mingw_putenv(const char *env) |
80 | { | 80 | { |
81 | char *s; | 81 | char *s, **envp; |
82 | int ret = 0; | ||
82 | 83 | ||
83 | if ( (s=strchr(env, '=')) == NULL ) { | 84 | if ( (s=strchr(env, '=')) == NULL ) { |
84 | return unsetenv(env); | 85 | return unsetenv(env); |
85 | } | 86 | } |
86 | 87 | ||
87 | if ( s[1] != '\0' ) { | 88 | if (s[1] != '\0') { |
89 | /* setting non-empty value is fine */ | ||
88 | return _putenv(env); | 90 | return _putenv(env); |
89 | } | 91 | } |
92 | else { | ||
93 | /* set empty value by setting a non-empty one then truncating */ | ||
94 | char *envstr = xasprintf("%s0", env); | ||
95 | ret = _putenv(envstr); | ||
96 | |||
97 | for (envp = environ; *envp; ++envp) { | ||
98 | if (strcmp(*envp, envstr) == 0) { | ||
99 | (*envp)[s - env + 1] = '\0'; | ||
100 | break; | ||
101 | } | ||
102 | } | ||
103 | free(envstr); | ||
104 | } | ||
90 | 105 | ||
91 | /* can't set empty value */ | 106 | return ret; |
92 | return 0; | ||
93 | } | 107 | } |