This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
PATCH: [perl #121930] Bleadperl breaks MDOOTSON/Wx
[perl5.git] / vutil.c
diff --git a/vutil.c b/vutil.c
index b687103..20fb522 100644 (file)
--- a/vutil.c
+++ b/vutil.c
@@ -591,6 +591,37 @@ VER_NV:
        char tbuf[64];
        SV *sv = SvNVX(ver) > 10e50 ? newSV(64) : 0;
        char *buf;
+#ifdef USE_LOCALE_NUMERIC
+        const char * const cur_numeric = setlocale(LC_NUMERIC, NULL);
+        assert(cur_numeric);
+
+        /* XS code can set the locale without us knowing.  To protect the
+         * version number parsing, which requires the radix character to be a
+         * dot, update our records as to what the locale is, so that our
+         * existing macro mechanism can correctly change it to a dot and back
+         * if necessary.  This code is extremely unlikely to be in a loop, so
+         * the extra work will have a negligible performance impact.  See [perl
+         * #121930].
+         *
+         * If the current locale is a standard one, but we are expecting it to
+         * be a different, underlying locale, update our records to make the
+         * underlying locale this (standard) one.  If the current locale is not
+         * a standard one, we should be expecting a non-standard one, the same
+         * one that we have recorded as the underlying locale.  If not, update
+         * our records. */
+        if (strEQ(cur_numeric, "C") || strEQ(cur_numeric, "POSIX")) {
+            if (! PL_numeric_standard) {
+                new_numeric(cur_numeric);
+            }
+        }
+        else if (PL_numeric_standard
+                 || ! PL_numeric_name
+                 || strNE(PL_numeric_name, cur_numeric))
+        {
+            new_numeric(cur_numeric);
+        }
+#endif
+        { /* Braces needed because macro just below declares a variable */
         STORE_NUMERIC_LOCAL_SET_STANDARD();
         LOCK_NUMERIC_STANDARD();
        if (sv) {
@@ -604,6 +635,7 @@ VER_NV:
        }
         UNLOCK_NUMERIC_STANDARD();
         RESTORE_NUMERIC_LOCAL();
+        }
        while (buf[len-1] == '0' && len > 0) len--;
        if ( buf[len-1] == '.' ) len--; /* eat the trailing decimal */
        version = savepvn(buf, len);