ref: f262d3b34bb60c71390dd2dc1ee70d99140083e8
parent: 32f7860a4e447167b72d87509313cfa527d37b82
author: ISSOtm <[email protected]>
date: Sat Dec 7 16:19:13 EST 2019
Fix undefined behavior in `readlong` See the new comment for what caused the UB, and how it was fixed
--- a/src/link/object.c
+++ b/src/link/object.c
@@ -55,7 +55,14 @@
if (byte == EOF)
return INT64_MAX;
- value |= (uint8_t)byte << shift;
+ /* 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 |= (unsigned)byte << shift;
}
return value;
}