diff options
| -rw-r--r-- | libbb/xfuncs_printf.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/libbb/xfuncs_printf.c b/libbb/xfuncs_printf.c index 1b11caf6b..f569b0263 100644 --- a/libbb/xfuncs_printf.c +++ b/libbb/xfuncs_printf.c | |||
| @@ -344,20 +344,28 @@ void FAST_FUNC xsetenv(const char *key, const char *value) | |||
| 344 | */ | 344 | */ |
| 345 | void FAST_FUNC bb_unsetenv(const char *var) | 345 | void FAST_FUNC bb_unsetenv(const char *var) |
| 346 | { | 346 | { |
| 347 | char *tp = strchr(var, '='); | 347 | char onstack[128 - 16]; /* smaller stack setup code on x86 */ |
| 348 | 348 | char *tp; | |
| 349 | if (!tp) { | 349 | |
| 350 | unsetenv(var); | 350 | tp = strchr(var, '='); |
| 351 | return; | 351 | if (tp) { |
| 352 | /* In case var was putenv'ed, we can't replace '=' | ||
| 353 | * with NUL and unsetenv(var) - it won't work, | ||
| 354 | * env is modified by the replacement, unsetenv | ||
| 355 | * sees "VAR" instead of "VAR=VAL" and does not remove it! | ||
| 356 | * Horror :( | ||
| 357 | */ | ||
| 358 | unsigned sz = tp - var; | ||
| 359 | if (sz < sizeof(onstack)) { | ||
| 360 | ((char*)mempcpy(onstack, var, sz))[0] = '\0'; | ||
| 361 | tp = NULL; | ||
| 362 | var = onstack; | ||
| 363 | } else { | ||
| 364 | /* unlikely: very long var name */ | ||
| 365 | var = tp = xstrndup(var, sz); | ||
| 366 | } | ||
| 352 | } | 367 | } |
| 353 | 368 | unsetenv(var); | |
| 354 | /* In case var was putenv'ed, we can't replace '=' | ||
| 355 | * with NUL and unsetenv(var) - it won't work, | ||
| 356 | * env is modified by the replacement, unsetenv | ||
| 357 | * sees "VAR" instead of "VAR=VAL" and does not remove it! | ||
| 358 | * horror :( */ | ||
| 359 | tp = xstrndup(var, tp - var); | ||
| 360 | unsetenv(tp); | ||
| 361 | free(tp); | 369 | free(tp); |
| 362 | } | 370 | } |
| 363 | 371 | ||
