fix leak when $LANG unset
authorDavid Mitchell <davem@iabyn.com>
Tue, 16 Apr 2019 15:49:47 +0000 (16:49 +0100)
committerDavid Mitchell <davem@iabyn.com>
Tue, 16 Apr 2019 15:49:47 +0000 (16:49 +0100)
The following leaked:

    LANG=  perl -e1

because in S_emulate_setlocale(), it was
1) making a copy of $ENV{"LANG"};
2) throwing that copy away and replacing it with "C" when it discovered
   that the string was empty.

A little judicious reordering of that chunk of code makes the issue go
away.

Showed up as failures of lib/locale_threads.t under valgrind / ASan.

locale.c

index 8a1ddc2..c3ce587 100644 (file)
--- a/locale.c
+++ b/locale.c
@@ -769,22 +769,19 @@ S_emulate_setlocale(const int category,
 
             const char * default_name;
 
-            /* To minimize other threads messing with the environment, we copy
-             * the variable, making it a temporary.  But this doesn't work upon
-             * program initialization before any scopes are created, and at
-             * this time, there's nothing else going on that would interfere.
-             * So skip the copy in that case */
-            if (PL_scopestack_ix == 0) {
-                default_name = PerlEnv_getenv("LANG");
-            }
-            else {
-                default_name = savepv(PerlEnv_getenv("LANG"));
-            }
+            default_name = PerlEnv_getenv("LANG");
 
             if (! default_name || strEQ(default_name, "")) {
                 default_name = "C";
             }
             else if (PL_scopestack_ix != 0) {
+                /* To minimize other threads messing with the environment,
+                 * we copy the variable, making it a temporary.  But this
+                 * doesn't work upon program initialization before any
+                 * scopes are created, and at this time, there's nothing
+                 * else going on that would interfere.  So skip the copy
+                 * in that case */
+                default_name = savepv(default_name);
                 SAVEFREEPV(default_name);
             }