diff --git a/src/link/object.cpp b/src/link/object.cpp index a8c60bb9..5976970f 100644 --- a/src/link/object.cpp +++ b/src/link/object.cpp @@ -57,13 +57,8 @@ static int64_t readLong(FILE *file) { if (byte == EOF) { return INT64_MAX; } - // This must be casted to `unsigned`, not `uint8_t`. Rationale: - // the type of the shift is the type of `byte` after undergoing - // integer promotion, which would be `int` if this was casted to - // `uint8_t`, because int is large enough to hold a byte. This - // however causes values larger than 127 to be too large when - // shifted, potentially triggering undefined behavior. - value |= static_cast(byte) << shift; + // Cast to `uint32_t` to avoid UB when shifting a byte >= 128 by a count >= 24. + value |= static_cast(byte) << shift; } return value; } diff --git a/src/link/sdas_obj.cpp b/src/link/sdas_obj.cpp index cf6d74ff..dc7fbedd 100644 --- a/src/link/sdas_obj.cpp +++ b/src/link/sdas_obj.cpp @@ -622,7 +622,8 @@ void sdobj_ReadFile(FileStackNode const &src, FILE *file, std::vector &f ); } for (uint8_t i = 0; i < nbBaseBytes; ++i) { - baseValue = baseValue | data[offset + i] << (8 * i); + // Cast to `uint32_t` to avoid UB when shifting a byte >= 128 by a count >= 24. + baseValue = baseValue | static_cast(data[offset + i]) << (8 * i); } // Bit 4 specifies signedness, but I don't think that matters?