libbb: avoid malloc/free in bb_unsetenv()
authorDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Jul 2017 00:15:17 +0000 (02:15 +0200)
committerDenys Vlasenko <vda.linux@googlemail.com>
Sat, 22 Jul 2017 00:15:17 +0000 (02:15 +0200)
function                                             old     new   delta
bb_unsetenv                                           55      83     +28

Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
libbb/xfuncs_printf.c

index 1b11caf6b1001555138e88c02ee46099aea0c1b1..f569b0263bfe2ceb0aee4433db59a34bcdce24f2 100644 (file)
@@ -344,20 +344,28 @@ void FAST_FUNC xsetenv(const char *key, const char *value)
  */
 void FAST_FUNC bb_unsetenv(const char *var)
 {
-       char *tp = strchr(var, '=');
-
-       if (!tp) {
-               unsetenv(var);
-               return;
+       char onstack[128 - 16]; /* smaller stack setup code on x86 */
+       char *tp;
+
+       tp = strchr(var, '=');
+       if (tp) {
+               /* In case var was putenv'ed, we can't replace '='
+                * with NUL and unsetenv(var) - it won't work,
+                * env is modified by the replacement, unsetenv
+                * sees "VAR" instead of "VAR=VAL" and does not remove it!
+                * Horror :(
+                */
+               unsigned sz = tp - var;
+               if (sz < sizeof(onstack)) {
+                       ((char*)mempcpy(onstack, var, sz))[0] = '\0';
+                       tp = NULL;
+                       var = onstack;
+               } else {
+                       /* unlikely: very long var name */
+                       var = tp = xstrndup(var, sz);
+               }
        }
-
-       /* In case var was putenv'ed, we can't replace '='
-        * with NUL and unsetenv(var) - it won't work,
-        * env is modified by the replacement, unsetenv
-        * sees "VAR" instead of "VAR=VAL" and does not remove it!
-        * horror :( */
-       tp = xstrndup(var, tp - var);
-       unsetenv(tp);
+       unsetenv(var);
        free(tp);
 }