Fix undefined shifts (#1156) * Fix undefined shifts Found by oss-fuzz uint8_t gets promoted to integer and integers shift cannot overflow on sign bit * Fix undefined shifts shifting 31 bits the sign bit
diff --git a/arch/AArch64/AArch64AddressingModes.h b/arch/AArch64/AArch64AddressingModes.h index e162fda..8902cf6 100644 --- a/arch/AArch64/AArch64AddressingModes.h +++ b/arch/AArch64/AArch64AddressingModes.h
@@ -198,7 +198,7 @@ // where B = NOT(b); FPUnion.I = 0; - FPUnion.I |= Sign << 31; + FPUnion.I |= ((uint32_t) Sign) << 31; FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; FPUnion.I |= (Exp & 0x3) << 23;
diff --git a/arch/AArch64/AArch64Disassembler.c b/arch/AArch64/AArch64Disassembler.c index a05970f..d4d548d 100644 --- a/arch/AArch64/AArch64Disassembler.c +++ b/arch/AArch64/AArch64Disassembler.c
@@ -240,9 +240,9 @@ if (MODE_IS_BIG_ENDIAN(ud->mode)) insn = (code[3] << 0) | (code[2] << 8) | - (code[1] << 16) | (code[0] << 24); + (code[1] << 16) | (((uint32_t) code[0]) << 24); else - insn = (code[3] << 24) | (code[2] << 16) | + insn = (((uint32_t) code[3]) << 24) | (code[2] << 16) | (code[1] << 8) | (code[0] << 0); // Calling the auto-generated decoder function.
diff --git a/arch/ARM/ARMAddressingModes.h b/arch/ARM/ARMAddressingModes.h index fcf0abf..f038b81 100644 --- a/arch/ARM/ARMAddressingModes.h +++ b/arch/ARM/ARMAddressingModes.h
@@ -658,7 +658,7 @@ // where B = NOT(b); FPUnion.I = 0; - FPUnion.I |= Sign << 31; + FPUnion.I |= ((uint32_t) Sign) << 31; FPUnion.I |= ((Exp & 0x4) != 0 ? 0 : 1) << 30; FPUnion.I |= ((Exp & 0x4) != 0 ? 0x1f : 0) << 25; FPUnion.I |= (Exp & 0x3) << 23;
diff --git a/arch/ARM/ARMDisassembler.c b/arch/ARM/ARMDisassembler.c index 0764595..3ba5a03 100644 --- a/arch/ARM/ARMDisassembler.c +++ b/arch/ARM/ARMDisassembler.c
@@ -466,9 +466,9 @@ insn = (bytes[3] << 0) | (bytes[2] << 8) | (bytes[1] << 16) | - (bytes[0] << 24); + (((uint32_t) bytes[0]) << 24); else - insn = (bytes[3] << 24) | + insn = (((uint32_t) bytes[3]) << 24) | (bytes[2] << 16) | (bytes[1] << 8) | (bytes[0] << 0); @@ -761,11 +761,11 @@ insn32 = (bytes[3] << 0) | (bytes[2] << 8) | (bytes[1] << 16) | - (bytes[0] << 24); + (((uint32_t) bytes[0]) << 24); else insn32 = (bytes[3] << 8) | (bytes[2] << 0) | - (bytes[1] << 24) | + (((uint32_t) bytes[1]) << 24) | (bytes[0] << 16); MCInst_clear(MI);
diff --git a/arch/Mips/MipsDisassembler.c b/arch/Mips/MipsDisassembler.c index 8fc5c7a..13c99c8 100644 --- a/arch/Mips/MipsDisassembler.c +++ b/arch/Mips/MipsDisassembler.c
@@ -295,7 +295,7 @@ *insn = (code[3] << 0) | (code[2] << 8) | (code[1] << 16) | - (code[0] << 24); + (((uint32_t) code[0]) << 24); } else { // Encoded as a small-endian 32-bit word in the stream. // Little-endian byte ordering: @@ -305,12 +305,12 @@ *insn = (code[2] << 0) | (code[3] << 8) | (code[0] << 16) | - (code[1] << 24); + (((uint32_t) code[1]) << 24); } else { *insn = (code[0] << 0) | (code[1] << 8) | (code[2] << 16) | - (code[3] << 24); + (((uint32_t) code[3]) << 24); } }
diff --git a/arch/PowerPC/PPCDisassembler.c b/arch/PowerPC/PPCDisassembler.c index 5935a84..6481980 100644 --- a/arch/PowerPC/PPCDisassembler.c +++ b/arch/PowerPC/PPCDisassembler.c
@@ -343,10 +343,10 @@ // The instruction is big-endian encoded. if (MODE_IS_BIG_ENDIAN(MI->csh->mode)) - insn = (code[0] << 24) | (code[1] << 16) | + insn = (((uint32_t) code[0]) << 24) | (code[1] << 16) | (code[2] << 8) | (code[3] << 0); else - insn = (code[3] << 24) | (code[2] << 16) | + insn = (((uint32_t) code[3]) << 24) | (code[2] << 16) | (code[1] << 8) | (code[0] << 0); if (MI->flat_insn->detail) {
diff --git a/arch/Sparc/SparcDisassembler.c b/arch/Sparc/SparcDisassembler.c index 87fa9c1..e080a51 100644 --- a/arch/Sparc/SparcDisassembler.c +++ b/arch/Sparc/SparcDisassembler.c
@@ -216,7 +216,7 @@ *Insn = (Bytes[3] << 0) | (Bytes[2] << 8) | (Bytes[1] << 16) | - (Bytes[0] << 24); + (((uint32_t) Bytes[0]) << 24); return MCDisassembler_Success; }
diff --git a/arch/XCore/XCoreDisassembler.c b/arch/XCore/XCoreDisassembler.c index efa565f..0e16476 100644 --- a/arch/XCore/XCoreDisassembler.c +++ b/arch/XCore/XCoreDisassembler.c
@@ -50,7 +50,7 @@ return false; // Encoded as a little-endian 32-bit word in the stream. - *insn = (code[0] << 0) | (code[1] << 8) | (code[2] << 16) | (code[3] << 24); + *insn = (code[0] << 0) | (code[1] << 8) | (code[2] << 16) | (((uint32_t) code[3]) << 24); return true; }