This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
ensure locale_name_on_entry isn't clobbered
authorTony Cook <tony@develop-help.com>
Mon, 16 Sep 2019 06:38:26 +0000 (16:38 +1000)
committerKarl Williamson <khw@cpan.org>
Thu, 24 Oct 2019 19:10:34 +0000 (12:10 -0700)
If the return value of setlocale() is static storage, the call to
setlocale(LC_NUMERIC, "C"); could overwrite it.

If the return value of setlocale() is malloced, the call to
setlocale(LC_NUMERIC, "C"); could free it.

Either way, we need to copy it.  Fixes gh #17054 rt134212

t/porting/customized.dat
vutil.c

index 35a36b2..811b8e7 100644 (file)
@@ -33,4 +33,4 @@ autodie cpan/autodie/t/mkdir.t 9e70d2282a3cc7d76a78bf8144fccba20fb37dac
 autodie cpan/autodie/t/recv.t 63bea2daa330e44b67714527ddf701c1bf3a6954
 experimental cpan/experimental/t/basic.t cb9da8dd05b854375809872a05dd32637508d5da
 version cpan/version/lib/version.pm 7ef9219d1d5f1d71f08a79f3b0577df138b21b12
-version vutil.c 317c25a807f9503282d58917a4a53b667232a6c5
+version vutil.c 601cc57bbc0070ae33eab7fd2d667f20efbe15f8
diff --git a/vutil.c b/vutil.c
index 4314fb9..23627be 100644 (file)
--- a/vutil.c
+++ b/vutil.c
@@ -643,6 +643,8 @@ VER_NV:
             if (   strNE(locale_name_on_entry, "C")
                 && strNE(locale_name_on_entry, "POSIX"))
             {
+                /* the setlocale() call might free or overwrite the name */
+                locale_name_on_entry = savepv(locale_name_on_entry);
                 setlocale(LC_NUMERIC, "C");
             }
             else {  /* This value indicates to the restore code that we didn't
@@ -666,6 +668,8 @@ VER_NV:
                 if (   strNE(locale_name_on_entry, "C")
                     && strNE(locale_name_on_entry, "POSIX"))
                 {
+                    /* the setlocale() call might free or overwrite the name */
+                    locale_name_on_entry = savepv(locale_name_on_entry);
                     setlocale(LC_NUMERIC, "C");
                 }
                 else {  /* This value indicates to the restore code that we
@@ -715,6 +719,7 @@ VER_NV:
 
             if (locale_name_on_entry) {
                 setlocale(LC_NUMERIC, locale_name_on_entry);
+                Safefree(locale_name_on_entry);
             }
 
             LC_NUMERIC_UNLOCK;  /* End critical section */
@@ -723,6 +728,7 @@ VER_NV:
 
             if (locale_name_on_entry) {
                 setlocale(LC_NUMERIC, locale_name_on_entry);
+                Safefree(locale_name_on_entry);
                 LC_NUMERIC_UNLOCK;
             }
             else if (locale_obj_on_entry == PL_underlying_numeric_obj) {