summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--t/porting/customized.dat2
-rw-r--r--vutil.c32
2 files changed, 33 insertions, 1 deletions
diff --git a/t/porting/customized.dat b/t/porting/customized.dat
index 47d977b7c5..a8ee6ecb4e 100644
--- a/t/porting/customized.dat
+++ b/t/porting/customized.dat
@@ -16,5 +16,5 @@ autodie cpan/autodie/t/utf8_open.t 5295851351c49f939008c5aca6a798742b1e503d
podlators cpan/podlators/scripts/pod2man.PL f81acf53f3ff46cdcc5ebdd661c5d13eb35d20d6
podlators cpan/podlators/scripts/pod2text.PL b4693fcfe4a0a1b38a215cfb8985a65d5d025d69
version cpan/version/lib/version.pm fa9931d4db05aff9a0a6ef558610b1a472d9306e
-version vutil.c abd88f59a6e0cfe7b4e45b1859f414042ea254aa
+version vutil.c 668f17ca43e2527645674d29ba772b86330d5663
version vxs.inc 9064aacbdfe42bb584a068f62b505dd11dbb4dc4
diff --git a/vutil.c b/vutil.c
index b687103de0..20fb522ee5 100644
--- 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);