From b9c3014e6552253435af9a24122c87cf03bb35b2 Mon Sep 17 00:00:00 2001 From: Tomasz Kramkowski Date: Tue, 1 Nov 2022 23:38:48 +0100 Subject: unpack.c: Cast negative signed offset to signed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit As N1570ยง6.5.16.2p3 states, E1 += E2 is equivalent to E1 = E1 + (E2). This means that E1 + (E2) will be subject to (6.5.6p4) "the usual arithmetic conversions". Since both types have equal integer conversion rank (6.3.1.1p1), E1 which was intmax_t will first be converted to uintmax_t before being added to (E2). This is not the intended result as it relies on integer wrapping behaviour again. Casting E2 to intmax_t first prevents the conversion of E1 and produces the correct result. --- unpack.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/unpack.c b/unpack.c index 7786ca6..45ba8fd 100644 --- a/unpack.c +++ b/unpack.c @@ -79,7 +79,7 @@ static void read_fields(struct dest dest, const void *src_, enum pack_endian end vals = val.unsigned_; } else { vals = minval(s); - vals += val.unsigned_ ^ (UINTMAX_C(1) << (s * 8 - 1)); + vals += (intmax_t)(val.unsigned_ ^ (UINTMAX_C(1) << (s * 8 - 1))); } val.signed_ = vals; tr_debug("val.s: %" PRIdMAX, val.signed_); -- cgit v1.2.3-54-g00ecf