From ea68a3bfa64a5e652ee45227d7aff1aba73c001b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Wed, 23 Jan 2019 20:19:51 -0800 Subject: ffi: almost bug: 64 bit signed big/little endian type. * ffi.c (ffi_be_i64_get, ffi_le_i64_get): The code here for 32 bit platforms is fishy: it is using the signed cnum type for the low 32 bits, when that should be ucnum. We are actually okay because ths code would only be executed on a platform where cnum is 32 bits. We are saved by the fact that we are doing left shifts (no sign extension), that shifting a 1 into a sign bit is harmless on two's complement machines, and that the lo32 value is ultimately passed to unum whereby it is coerced to a ucnum argument type (which preserves the bit representation) and prevents logior from seeing a negative value. --- ffi.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/ffi.c b/ffi.c index 17936396..672d5749 100644 --- a/ffi.c +++ b/ffi.c @@ -975,8 +975,8 @@ static val ffi_be_i64_get(struct txr_ffi_type *tft, mem_t *src, val self) #else cnum hi32 = (convert(cnum, src[0]) << 24 | convert(cnum, src[1]) << 16 | convert(cnum, src[2]) << 8 | src[3]); - cnum lo32 = (convert(cnum, src[4]) << 24 | convert(cnum, src[5]) << 16 | - convert(cnum, src[6]) << 8 | src[7]); + ucnum lo32 = (convert(ucnum, src[4]) << 24 | convert(ucnum, src[5]) << 16 | + convert(ucnum, src[6]) << 8 | src[7]); return logior(ash(num(hi32), num_fast(32)), unum(lo32)); #endif } @@ -1089,8 +1089,8 @@ static val ffi_le_i64_get(struct txr_ffi_type *tft, mem_t *src, val self) #else cnum hi32 = (convert(cnum, src[3]) << 24 | convert(cnum, src[2]) << 16 | convert(cnum, src[1]) << 8 | src[0]); - cnum lo32 = (convert(cnum, src[3]) << 24 | convert(cnum, src[2]) << 16 | - convert(cnum, src[1]) << 8 | src[0]); + ucnum lo32 = (convert(ucnum, src[3]) << 24 | convert(ucnum, src[2]) << 16 | + convert(ucnum, src[1]) << 8 | src[0]); return logior(ash(num(hi32), num_fast(32)), unum(lo32)); #endif } -- cgit v1.2.3