From f262d3b34bb60c71390dd2dc1ee70d99140083e8 Mon Sep 17 00:00:00 2001 From: ISSOtm Date: Sat, 7 Dec 2019 21:19:13 +0100 Subject: [PATCH] Fix undefined behavior in `readlong` See the new comment for what caused the UB, and how it was fixed --- src/link/object.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/link/object.c b/src/link/object.c index 3f194267..df78c51c 100644 --- a/src/link/object.c +++ b/src/link/object.c @@ -55,7 +55,14 @@ static int64_t readlong(FILE *file) 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; }