78f1eb
From 14d26b44a1d7eee67837ec0ea8fb0368ac6fe33e Mon Sep 17 00:00:00 2001
78f1eb
From: Tony Cook <tony@develop-help.com>
78f1eb
Date: Tue, 20 Aug 2019 15:43:05 +1000
78f1eb
Subject: [PATCH] (perl #134230) don't interpret 0x, 0b when numifying strings
78f1eb
MIME-Version: 1.0
78f1eb
Content-Type: text/plain; charset=UTF-8
78f1eb
Content-Transfer-Encoding: 8bit
78f1eb
78f1eb
Signed-off-by: Petr Písař <ppisar@redhat.com>
78f1eb
---
78f1eb
 numeric.c  | 9 +++++++++
78f1eb
 t/op/int.t | 5 ++++-
78f1eb
 2 files changed, 13 insertions(+), 1 deletion(-)
78f1eb
78f1eb
diff --git a/numeric.c b/numeric.c
78f1eb
index f5eadc8173..fae2eb3c6d 100644
78f1eb
--- a/numeric.c
78f1eb
+++ b/numeric.c
78f1eb
@@ -1551,6 +1551,15 @@ Perl_my_atof3(pTHX_ const char* orig, NV* value, const STRLEN len)
78f1eb
         if ((endp = S_my_atof_infnan(aTHX_ s, negative, send, value)))
78f1eb
             return endp;
78f1eb
 
78f1eb
+        /* strtold() accepts 0x-prefixed hex and in POSIX implementations,
78f1eb
+           0b-prefixed binary numbers, which is backward incompatible
78f1eb
+        */
78f1eb
+        if ((len == 0 || len >= 2) && *s == '0' &&
78f1eb
+            (isALPHA_FOLD_EQ(s[1], 'x') || isALPHA_FOLD_EQ(s[1], 'b'))) {
78f1eb
+            *value = 0;
78f1eb
+            return (char *)s+1;
78f1eb
+        }
78f1eb
+
78f1eb
         /* If the length is passed in, the input string isn't NUL-terminated,
78f1eb
          * and in it turns out the function below assumes it is; therefore we
78f1eb
          * create a copy and NUL-terminate that */
78f1eb
diff --git a/t/op/int.t b/t/op/int.t
78f1eb
index 7e936da68d..b730ab2672 100644
78f1eb
--- a/t/op/int.t
78f1eb
+++ b/t/op/int.t
78f1eb
@@ -7,7 +7,7 @@ BEGIN {
78f1eb
     require Config;
78f1eb
 }
78f1eb
 
78f1eb
-plan 17;
78f1eb
+plan 19;
78f1eb
 
78f1eb
 # compile time evaluation
78f1eb
 
78f1eb
@@ -83,3 +83,6 @@ SKIP:
78f1eb
         cmp_ok($x, "==", int($x), "check $x == int($x)");
78f1eb
     }
78f1eb
 }
78f1eb
+
78f1eb
+is(1+"0x10", 1, "check string '0x' prefix not treated as hex");
78f1eb
+is(1+"0b10", 1, "check string '0b' prefix not treated as binary");
78f1eb
-- 
78f1eb
2.21.0
78f1eb