shithub: rgbds

Download patch

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;
 }