Avoid UB when checking truncation range

Fixes #1818
This commit is contained in:
Rangi42
2025-09-04 12:04:10 -04:00
parent 5b67dc94b6
commit bdc885bd69

View File

@@ -505,8 +505,10 @@ void patch_CheckAssertions() {
} }
static void checkPatchSize(Patch const &patch, int32_t v, uint8_t n) { static void checkPatchSize(Patch const &patch, int32_t v, uint8_t n) {
static constexpr unsigned m = CHAR_BIT * sizeof(int); assume(n != 0); // That doesn't make sense
if (n < m && (v < -(1 << n) || v >= 1 << n)) { assume(n < CHAR_BIT * sizeof(int)); // Otherwise `1 << n` is UB
if (v < -(1 << n) || v >= 1 << n) {
diagnosticAt( diagnosticAt(
patch, patch,
WARNING_TRUNCATION_1, WARNING_TRUNCATION_1,
@@ -515,8 +517,7 @@ static void checkPatchSize(Patch const &patch, int32_t v, uint8_t n) {
v < 0 ? " (may be negative?)" : "", v < 0 ? " (may be negative?)" : "",
n n
); );
return; } else if (v < -(1 << (n - 1))) {
} else if (n < m + 1 && v < -(1 << (n - 1))) {
diagnosticAt( diagnosticAt(
patch, patch,
WARNING_TRUNCATION_2, WARNING_TRUNCATION_2,
@@ -568,7 +569,9 @@ static void applyFilePatches(Section &section, Section &dataSection) {
dataSection.data[offset] = jumpOffset & 0xFF; dataSection.data[offset] = jumpOffset & 0xFF;
} else { } else {
// Patch a certain number of bytes // Patch a certain number of bytes
if (typeSize < sizeof(int)) {
checkPatchSize(patch, value, typeSize * 8); checkPatchSize(patch, value, typeSize * 8);
}
for (uint8_t i = 0; i < typeSize; ++i) { for (uint8_t i = 0; i < typeSize; ++i) {
dataSection.data[offset + i] = value & 0xFF; dataSection.data[offset + i] = value & 0xFF;
value >>= 8; value >>= 8;