UV casting to avoid intermediate sign extension.

[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.
This commit is contained in:
Jarkko Hietaniemi 2014-05-29 10:01:13 -04:00
parent e5a8a0fbd7
commit e7aca353f7
2 changed files with 12 additions and 9 deletions

4
doop.c
View File

@ -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
}

17
utf8.c
View File

@ -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);