Примеры ошибок, обнаруженных с помощью диагностики V629
V629. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. Consider inspecting the expression.
LLVM/Clang
V629 Consider inspecting the '1U << (NumBits - 1)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bitstreamwriter.h 173
void EmitVBR64(uint64_t Val, unsigned NumBits) {
if ((uint32_t)Val == Val)
return EmitVBR((uint32_t)Val, NumBits);
uint64_t Threshold = 1U << (NumBits-1);
....
}
LLVM/Clang
V629 Consider inspecting the '1U << (NumBits - 1)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bitstreamreader.h 362
uint64_t ReadVBR64(unsigned NumBits) {
....
Result |= uint64_t(Piece & ((1U << (NumBits-1))-1))
<< NextBit;
....
}
LLVM/Clang
V629 Consider inspecting the '1 << shift' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. dataextractor.cpp 171
int64_t DataExtractor::getSLEB128(....) const {
int64_t result = 0;
....
// Sign bit of byte is 2nd high order bit (0x40)
if (shift < 64 && (byte & 0x40))
result |= -(1 << shift);
....
}
LLVM/Clang
V629 Consider inspecting the 'Bit->getValue() << i' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. record.cpp 248
Init *IntRecTy::convertValue(BitsInit *BI) {
int64_t Result = 0;
for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
if (....) {
Result |= Bit->getValue() << i;
} else {
return 0;
}
return IntInit::get(Result);
}
Xpdf
V629 Consider inspecting the 'zaehler << 16' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. swftools.c 37
typedef signed long long S64;
SFIXED RFXSWF_QFIX(int zaehler, int nenner)
{
S64 z = zaehler<<16;
S64 a = z/(S64)nenner;
return (SFIXED)a;
}
SeqAn
V629 Consider inspecting the '1 << BitsPerValue < TValue >::VALUE' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. tuple_bit_compressed.h 88
template <typename TValue, unsigned SIZE>
struct Tuple<TValue, SIZE, BitPacked<> >
{
typedef typename
BitVector_<SIZE * BitsPerValue<TValue>::VALUE>::Type
TBitVector;
static const __uint64 BIT_MASK =
(1 << BitsPerValue<TValue>::VALUE) - 1;
....
}
Snes9x
V629 Consider inspecting the '- 1 << (64 - n)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. sar.h 217
static inline int64 SAR (const int64 b, const int n)
{
#ifndef RIGHTSHIFT_int64_IS_SAR
if (b < 0)
return ((b >> n) | (-1 << (64 - n)));
#endif
return (b >> n);
}
SMHasher
V629 Consider inspecting the '(unsigned long) d << 32' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. Platform.h 78
__inline__ unsigned long long int rdtsc()
{
#ifdef __x86_64__
unsigned int a, d;
__asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
return (unsigned long)a | ((unsigned long)d << 32);
#elif defined(__i386__)
unsigned long long int x;
__asm__ volatile ("rdtsc" : "=A" (x));
return x;
#else
#define NO_CYCLE_COUNTER
return 0;
#endif
}
It may fail if the long type appears 32-bit - an overflow will occur in the "(unsigned long)d << 32" expression.
The JUCE Library
V629 Consider inspecting the 'samples << hs' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vorbisfile.c 1676
typedef __int64 ogg_int64_t;
ogg_int64_t pcm_offset;
int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
....
int hs = ....;
long samples=....;
....
vf->pcm_offset+=samples<<hs;
....
}
Similar errors can be found in some other places:
- V629 Consider inspecting the 'samples << hs' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vorbisfile.c 1998
- V629 Consider inspecting the 'samples << hs' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vorbisfile.c 2039
Unreal Engine 4
V629 Consider inspecting the '1 << (HashKeyShift - PoolBitShift)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. mallocbinned.h 800
class FMallocBinned : public FMalloc
{
....
/* Used to mask off the bits that have been used to
lookup the indirect table */
uint64 PoolMask;
....
FMallocBinned(uint32 InPageSize, uint64 AddressLimit)
{
....
PoolMask = ( ( 1 << ( HashKeyShift - PoolBitShift ) ) - 1 );
....
}
}
Tesseract
V629 Consider inspecting the '~0 << flag_start_bit_' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. libtesseract303 dawg.cpp 187
uinT64 letter_mask_;
void Dawg::init(....)
{
....
letter_mask_ = ~(~0 << flag_start_bit_);
....
}
Similar errors can be found in some other places:
- V629 Consider inspecting the '~0 << (flag_start_bit_ + 3)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. libtesseract303 dawg.cpp 188
Bitcoin
V629 Consider inspecting the '0x80 << (8 * (vch.size() - 1))' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. script.h 169
static int64_t set_vch(const std::vector<unsigned char>& vch)
{
if (vch.empty())
return 0;
int64_t result = 0;
for (size_t i = 0; i != vch.size(); ++i)
result |= static_cast<int64_t>(vch[i]) << 8*i;
// If the input vector's most significant byte is 0x80,
// remove it from the result's msb and return a negative.
if (vch.back() & 0x80)
return -(result & ~(0x80 << (8 * (vch.size() - 1))));
return result;
}
Alembic
V629 Consider inspecting the '1 << iStreamID' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. StreamManager.cpp 176
void StreamManager::put( std::size_t iStreamID )
{
....
// CAS (compare and swap) non locking version
Alembic::Util::int64_t oldVal = 0;
Alembic::Util::int64_t newVal = 0;
....
oldVal = m_streams;
newVal = oldVal | ( 1 << iStreamID ); // <=
}
TensorFlow
V629 Consider inspecting the '1 << c->Value(tree_depth)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. unpack_path_op.cc 55
class InferenceContext {
....
inline int64 Value(DimensionOrConstant d) const {
return d.dim.IsSet() ? d.dim->value_ : d.val;
}
....
}
REGISTER_OP("UnpackPath")
.Input("path: int32")
.Input("path_values: float")
.Output("unpacked_path: float")
.SetShapeFn([](InferenceContext* c) {
....
int64 num_nodes = InferenceContext::kUnknownDim;
if (c->ValueKnown(tree_depth)) {
num_nodes = (1 << c->Value(tree_depth)) - 1; // <=
}
....
})
....;
Android
V629 CWE-190 Consider inspecting the '1 << reg' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. RegsInfo.h 47
template <typename AddressType>
struct RegsInfo {
....
uint64_t saved_reg_map = 0;
AddressType saved_regs[64];
....
inline AddressType* Save(uint32_t reg) {
if (reg > sizeof(saved_regs) / sizeof(AddressType)) {
abort();
}
saved_reg_map |= 1 << reg;
saved_regs[reg] = (*regs)[reg];
return &(*regs)[reg];
}
....
}
LLVM/Clang
V629 [CWE-190] Consider inspecting the '~(Size - 1) << 1' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. AArch64AddressingModes.h 260
static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
uint64_t &Encoding) {
....
unsigned Size = RegSize;
....
uint64_t NImms = ~(Size-1) << 1;
....
}
Similar errors can be found in some other places:
- V629 [CWE-190] Consider inspecting the 'Immr << 6' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. AArch64AddressingModes.h 269
Qemu
V629 Consider inspecting the 'n << 9' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. qemu-img.c 1839
#define BDRV_SECTOR_BITS 9
static int coroutine_fn convert_co_read(ImgConvertState *s,
int64_t sector_num, int nb_sectors, uint8_t *buf)
{
uint64_t single_read_until = 0;
int n;
....
while (nb_sectors > 0) {
....
uint64_t offset;
....
single_read_until = offset + (n << BDRV_SECTOR_BITS);
....
}
....
}
jsoncons
V629 Consider inspecting the '1 << k' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bigint.hpp 744
static constexpr uint64_t basic_type_bits = sizeof(uint64_t) * 8;
uint64_t* data()
{
return is_dynamic() ? dynamic_stor_.data_ : short_stor_.values_;
}
basic_bigint& operator<<=( uint64_t k )
{
size_type q = (size_type)(k / basic_type_bits);
if ( q ) // Increase common_stor_.length_ by q:
{
resize(length() + q);
for (size_type i = length(); i-- > 0; )
data()[i] = ( i < q ? 0 : data()[i - q]);
k %= basic_type_bits;
}
if ( k ) // 0 < k < basic_type_bits:
{
uint64_t k1 = basic_type_bits - k;
uint64_t mask = (1 << k) - 1; // <=
resize( length() + 1 );
for (size_type i = length(); i-- > 0; )
{
data()[i] <<= k;
if ( i > 0 )
data()[i] |= (data()[i-1] >> k1) & mask;
}
}
reduce();
return *this;
}
Similar errors can be found in some other places:
- V629 Consider inspecting the '1 << k' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bigint.hpp 779
PGM-index
V629 Consider inspecting the '1 << log_s' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. sdsl.hpp 1350
template<class t_int_vec>
t_int_vec rnd_positions(uint8_t log_s, uint64_t& mask,
uint64_t mod=0, uint64_t seed=17)
{
mask = (1<<log_s)-1; // <=
t_int_vec rands(1<<log_s ,0);
set_random_bits(rands, seed);
if (mod > 0) {
util::mod(rands, mod);
}
return rands;
}
YTsaurus
V629 Consider inspecting the '1 << value.Data.Uint64' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. range_inferrer.cpp:378
TDivisors GetDivisors(const TSchemaColumns& columns,
int keyIndex,
TConstExpressionPtr expr)
{
....
if (binaryOp->Opcode == EBinaryOp::Divide)
{
....
}
else if (binaryOp->Opcode == EBinaryOp::RightShift)
{
TUnversionedValue value = literal->Value;
value.Data.Uint64 = 1 << value.Data.Uint64; // <=
value.Id = 0;
return TDivisors{value};
}
....
}
iSulad
V629 [CWE-190, CERT-INT00-C] Consider inspecting the '1 << exponent' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. cri_helpers.cc 1098
int64_t ParseBinaryQuantity(bool positive, const std::string &numStr,
const std::string &denomStr, int64_t &exponent,
Errors &error)
{
int64_t result = 0;
int64_t mult = 1 << exponent;
....
}
PPSSPP
V629 Consider inspecting the '1 << size' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. Arm64Emitter.cpp 4298
bool ARM64FloatEmitter::TryMOVI(u8 size, ARM64Reg Rd, uint64_t elementValue)
{
if (size == 8)
{
// Can always do 8.
MOVI(size, Rd, elementValue & 0xFF);
return true;
}
....
}
....
bool ARM64FloatEmitter::TryAnyMOVI(u8 size,
ARM64Reg Rd,
uint64_t elementValue)
{
// Try the original size first in case that's more optimal.
if (TryMOVI(size, Rd, elementValue))
return true;
if (size != 64)
{
uint64_t masked = elementValue & ((1 << size) - 1); // <=
for (int i = size; i < 64; ++i)
{
value |= masked << i;
}
}
....
}
Let's take a look at the declaration of the 'masked' variable. There are two problems in this line. Let's start with bitwise shift. When size == 32 we shift the '1' literal which has the int type. The size of int is determined by the implementation, but on many platforms it is 32 bits. We get the expression 1 << 32. The behavior in this case is not defined. But there's more. We'll take a closer look at the bitwise AND operation. Let's say that shifting one to the left works fine and all 32 bits are filled correctly. However, we are doing a bitwise AND with a 64-bit variable. According to the standard, the right operand should be sign-extended to 64 bits. If the shift results in a positive number, the most significant bits will be zero when extended. So, a bitwise AND zeroes the most significant part of the 'elementValue' variable.