libFLAC/bitreader.c: Fix undefined behaviour
The function FLAC__bitreader_read_raw_int32() triggered undefined behaviour
when sign extending an unsigned value. The Stanford Grahpics bithacks page
provided an alternative that avoided UB.
diff --git a/src/libFLAC/bitreader.c b/src/libFLAC/bitreader.c
index f61229b..67d0f37 100644
--- a/src/libFLAC/bitreader.c
+++ b/src/libFLAC/bitreader.c
@@ -418,12 +418,14 @@
FLAC__bool FLAC__bitreader_read_raw_int32(FLAC__BitReader *br, FLAC__int32 *val, unsigned bits)
{
+ FLAC__uint32 uval, mask;
/* OPT: inline raw uint32 code here, or make into a macro if possible in the .h file */
- if(!FLAC__bitreader_read_raw_uint32(br, (FLAC__uint32*)val, bits))
+ if(!FLAC__bitreader_read_raw_uint32(br, &uval, bits))
return false;
- /* sign-extend: */
- *val <<= (32-bits);
- *val >>= (32-bits);
+ /* sign-extend *val assuming it is currently bits wide. */
+ /* From: https://graphics.stanford.edu/~seander/bithacks.html#FixedSignExtend */
+ mask = 1u << (bits - 1);
+ *val = (uval ^ mask) - mask;
return true;
}