#include "llvm/Support/Endian.h"
#include "llvm/Support/Error.h"
#include "llvm/Support/raw_ostream.h"
+#include <cstdint>
#include <vector>
namespace clang {
uint32_t consumeVar() {
constexpr static uint8_t More = 1 << 7;
- uint8_t B = consume8();
+
+ // Use a 32 bit unsigned here to prevent promotion to signed int (unless int
+ // is wider than 32 bits).
+ uint32_t B = consume8();
if (LLVM_LIKELY(!(B & More)))
return B;
uint32_t Val = B & ~More;
for (int Shift = 7; B & More && Shift < 32; Shift += 7) {
B = consume8();
+ // 5th byte of a varint can only have lowest 4 bits set.
+ assert((Shift != 28 || B == (B & 0x0f)) && "Invalid varint encoding");
Val |= (B & ~More) << Shift;
}
return Val;
Pos += FileDigest.size();
// Varints are little-endian base-128 numbers, where the top-bit of each byte
- // indicates whether there are more. 8fffffff7f -> 0xffffffff.
+ // indicates whether there are more. ffffffff0f -> 0xffffffff.
std::string CorruptSrcs =
- (Srcs->Data.take_front(Pos) + llvm::fromHex("8fffffff7f") +
+ (Srcs->Data.take_front(Pos) + llvm::fromHex("ffffffff0f") +
"some_random_garbage")
.str();
Srcs->Data = CorruptSrcs;