Hack the "integer overflow" code some more.
Jarkko Hietaniemi [Sat, 31 Jul 1999 20:26:22 +0000 (20:26 +0000)]
p4raw-id: //depot/cfgperl@3840

perl.h
toke.c
util.c

diff --git a/perl.h b/perl.h
index 8665704..e9e86cf 100644 (file)
--- a/perl.h
+++ b/perl.h
@@ -1024,6 +1024,8 @@ Free_t   Perl_mfree (Malloc_t where);
 #    define UV_MAX PERL_UQUAD_MAX
 #    define UV_MIN PERL_UQUAD_MIN
 #  endif
+#  define IV_SIZEOF 8
+#  define UV_SIZEOF 8
 #else
    typedef          long               IV;
    typedef         unsigned long      UV;
@@ -1038,6 +1040,8 @@ Free_t   Perl_mfree (Malloc_t where);
 #    define UV_MAX PERL_ULONG_MAX
 #    define UV_MIN PERL_ULONG_MIN
 #  endif
+#  define UV_SIZEOF LONGSIZE
+#  define IV_SIZEOF LONGSIZE
 #endif
 
 #ifdef USE_LONG_DOUBLE
diff --git a/toke.c b/toke.c
index 23a8cb4..d5e8fb7 100644 (file)
--- a/toke.c
+++ b/toke.c
@@ -6410,21 +6410,23 @@ Perl_scan_num(pTHX_ char *start)
            sv = NEWSV(92,0);
            if (overflowed) {
                dTHR;
-               if (ckWARN(WARN_UNSAFE) && (double) n > 4294967295.0)
+               if (ckWARN(WARN_UNSAFE) && (NV) n > 4294967295.0)
                    Perl_warner(aTHX_ WARN_UNSAFE,
                                "%s number > %s non-portable",
                                Base, max);
                sv_setnv(sv, n);
            }
            else {
+#if UV_SIZEOF > 4
                dTHR;
-               if (ckWARN(WARN_UNSAFE) && u > 4294967295)
+               if (ckWARN(WARN_UNSAFE) && u > 0xffffffff)
                    Perl_warner(aTHX_ WARN_UNSAFE,
                                "%s number > %s non-portable",
                                Base, max);
+#endif
                sv_setuv(sv, u);
            }
-           if ( PL_hints & HINT_NEW_BINARY)
+           if (PL_hints & HINT_NEW_BINARY)
                sv = new_constant(start, s - start, "binary", sv, Nullsv, NULL);
        }
        break;
diff --git a/util.c b/util.c
index 4ef55f2..9d35e21 100644 (file)
--- a/util.c
+++ b/util.c
@@ -2784,13 +2784,12 @@ Perl_scan_bin(pTHX_ char *start, I32 len, I32 *retlen)
     register UV ruv = 0;
     register bool seenb = FALSE;
     register bool overflowed = FALSE;
-    char *nonzero = NULL;
 
     for (; len-- && *s; s++) {
        if (!(*s == '0' || *s == '1')) {
            if (*s == '_')
                continue; /* Note: does not check for __ and the like. */
-           if (seenb == FALSE && *s == 'b' && nonzero == NULL) {
+           if (seenb == FALSE && *s == 'b' && ruv == 0) {
                /* Disallow 0bbb0b0bbb... */
                seenb = TRUE;
                continue;
@@ -2802,9 +2801,6 @@ Perl_scan_bin(pTHX_ char *start, I32 len, I32 *retlen)
                                "Illegal binary digit '%c' ignored", *s);
                break;
            }
-       } else {
-           if (nonzero == NULL && *s != '0')
-               nonzero = s;
        }
        if (!overflowed) {
            register UV xuv = ruv << 1;
@@ -2826,13 +2822,13 @@ Perl_scan_bin(pTHX_ char *start, I32 len, I32 *retlen)
             * is a waste of time (because the NV cannot preserve
             * the low-order bits anyway): we could just remember when
             * did we overflow and in the end just multiply rnv by the
-            * right amount of 16-tuples. */
+            * right amount. */
            rnv += (*s - '0');
        }
     }
     if (!overflowed)
        rnv = (NV) ruv;
-    if (sizeof(UV) > 4 && nonzero && (s - nonzero) > 32) {
+    if (rnv > 4294967295.0) {
        dTHR;
        if (ckWARN(WARN_UNSAFE))
            Perl_warner(aTHX_ WARN_UNSAFE,
@@ -2849,7 +2845,6 @@ Perl_scan_oct(pTHX_ char *start, I32 len, I32 *retlen)
     register NV rnv = 0.0;
     register UV ruv = 0;
     register bool overflowed = FALSE;
-    char *nonzero = NULL;
 
     for (; len-- && *s; s++) {
        if (!(*s >= '0' && *s <= '7')) {
@@ -2868,10 +2863,6 @@ Perl_scan_oct(pTHX_ char *start, I32 len, I32 *retlen)
                break;
            }
        }
-       else {
-           if (nonzero == NULL && *s != '0')
-               nonzero = s;
-       }
        if (!overflowed) {
            register xuv = ruv << 3;
 
@@ -2898,9 +2889,7 @@ Perl_scan_oct(pTHX_ char *start, I32 len, I32 *retlen)
     }
     if (!overflowed)
        rnv = (NV) ruv;
-    if (sizeof(UV) > 4 &&
-       overflowed ? rnv > 4294967295.0 :
-       (nonzero && (s - nonzero) > 10 && (ruv >> 30) > 3)) {
+    if (rnv > 4294967295.0) { 
        dTHR;
        if (ckWARN(WARN_UNSAFE))
            Perl_warner(aTHX_ WARN_UNSAFE,
@@ -2918,7 +2907,6 @@ Perl_scan_hex(pTHX_ char *start, I32 len, I32 *retlen)
     register UV ruv = 0;
     register bool seenx = FALSE;
     register bool overflowed = FALSE;
-    char *nonzero = NULL;
     char *hexdigit;
 
     for (; len-- && *s; s++) {
@@ -2926,7 +2914,7 @@ Perl_scan_hex(pTHX_ char *start, I32 len, I32 *retlen)
        if (!hexdigit) {
            if (*s == '_')
                continue; /* Note: does not check for __ and the like. */
-           if (seenx == FALSE && *s == 'x' && nonzero == NULL) {
+           if (seenx == FALSE && *s == 'x' && ruv == 0) {
                /* Disallow 0xxx0x0xxx... */
                seenx = TRUE;
                continue;
@@ -2939,10 +2927,6 @@ Perl_scan_hex(pTHX_ char *start, I32 len, I32 *retlen)
                break;
            }
        }
-       else {
-           if (nonzero == NULL && *s != '0')
-               nonzero = s;
-       }
        if (!overflowed) {
            register UV xuv = ruv << 4;
 
@@ -2969,8 +2953,7 @@ Perl_scan_hex(pTHX_ char *start, I32 len, I32 *retlen)
     }
     if (!overflowed)
        rnv = (NV) ruv;
-    if (sizeof(UV) > 4 &&
-       nonzero && (s - nonzero) > 8) {
+    if (rnv > 4294967295.0) {
        dTHR;
        if (ckWARN(WARN_UNSAFE))
            Perl_warner(aTHX_ WARN_UNSAFE,