This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
UV casting to avoid intermediate sign extension.
authorJarkko Hietaniemi <jhi@iki.fi>
Thu, 29 May 2014 14:01:13 +0000 (10:01 -0400)
committerJarkko Hietaniemi <jhi@iki.fi>
Thu, 29 May 2014 14:03:26 +0000 (10:03 -0400)
[perl #121746]

Fix for Coverity perl5 CIDs 29069, 29070, 29071:
Unintended sign extension: ... ... if ... U8 (8 bits unsigned) ... 32
bits, signed ...  64 bits, unsigned ... is greater than 0x7FFFFFFF,
the upper bits of the result will all be 1.

doop.c
utf8.c

diff --git a/doop.c b/doop.c
index 96185bd..0ba4bb8 100644 (file)
--- a/doop.c
+++ b/doop.c
@@ -850,7 +850,7 @@ Perl_do_vecget(pTHX_ SV *sv, SSize_t offset, int size)
                        ((UV) s[uoffset + 1] << 48) +
                        ((UV) s[uoffset + 2] << 40) +
                        ((UV) s[uoffset + 3] << 32) +
-                       (     s[uoffset + 4] << 24);
+                       ((UV) s[uoffset + 4] << 24);
                else if (uoffset + 6 >= srclen)
                    retnum =
                        ((UV) s[uoffset    ] << 56) +
@@ -867,7 +867,7 @@ Perl_do_vecget(pTHX_ SV *sv, SSize_t offset, int size)
                        ((UV) s[uoffset + 3] << 32) +
                        ((UV) s[uoffset + 4] << 24) +
                        ((UV) s[uoffset + 5] << 16) +
-                       (     s[uoffset + 6] <<  8);
+                       ((UV) s[uoffset + 6] <<  8);
            }
 #endif
        }
diff --git a/utf8.c b/utf8.c
index e97115f..5d1b05a 100644 (file)
--- a/utf8.c
+++ b/utf8.c
@@ -2811,7 +2811,6 @@ Perl_swash_fetch(pTHX_ SV *swash, const U8 *ptr, bool do_utf8)
     STRLEN slen = 0;
     STRLEN needents;
     const U8 *tmps = NULL;
-    U32 bit;
     SV *swatch;
     const U8 c = *ptr;
 
@@ -2941,17 +2940,21 @@ Perl_swash_fetch(pTHX_ SV *swash, const U8 *ptr, bool do_utf8)
 
     switch ((int)((slen << 3) / needents)) {
     case 1:
-       bit = 1 << (off & 7);
-       off >>= 3;
-       return (tmps[off] & bit) != 0;
+       return ((UV) tmps[off >> 3] & (1 << (off & 7))) != 0;
     case 8:
-       return tmps[off];
+       return ((UV) tmps[off]);
     case 16:
        off <<= 1;
-       return (tmps[off] << 8) + tmps[off + 1] ;
+       return
+            ((UV) tmps[off    ] << 8) +
+            ((UV) tmps[off + 1]);
     case 32:
        off <<= 2;
-       return (tmps[off] << 24) + (tmps[off+1] << 16) + (tmps[off+2] << 8) + tmps[off + 3] ;
+       return
+            ((UV) tmps[off    ] << 24) +
+            ((UV) tmps[off + 1] << 16) +
+            ((UV) tmps[off + 2] <<  8) +
+            ((UV) tmps[off + 3]);
     }
     Perl_croak(aTHX_ "panic: swash_fetch got swatch of unexpected bit width, "
               "slen=%"UVuf", needents=%"UVuf, (UV)slen, (UV)needents);