[vlc-commits] [Git][videolan/vlc][master] araw: fix overflows in 24-bit decoder

Jean-Baptiste Kempf (@jbk) gitlab at videolan.org
Tue Aug 9 17:44:52 UTC 2022



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
9260acab by RĂ©mi Denis-Courmont at 2022-08-09T17:28:44+00:00
araw: fix overflows in 24-bit decoder

The high-order byte is promoted to 'int'. If the high-order bit is set,
this results in an overflow (into the sign bit) when shifted by 24 bits
to the left. This was flagged by the UB sanitiser. To fix that, promote
all bytes to 32-bit unsigned first, to perform overflow-proof unsigned
arithmetic.

Then to avoid aliasing errors, make sure the output is written as signed
32-bit values, since the decoder outputs S32N.

- - - - -


1 changed file:

- modules/codec/araw.c


Changes:

=====================================
modules/codec/araw.c
=====================================
@@ -422,36 +422,45 @@ static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
 
 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
 {
-    uint32_t *out = outp;
+    int32_t *out = outp;
+    union { int32_t s; uint32_t u; } u;
 
     for( size_t i = 0; i < samples; i++ )
     {
-        uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
-        *(out++) = s;
+        uint_fast32_t hi = in[0], mid = in[1], lo = in[2];
+
+        u.u = ((hi << 24) | (mid << 16) | (lo << 8)) - UINT32_C(0x80000000);
+        *(out++) = u.s;
         in += 3;
     }
 }
 
 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
 {
-    uint32_t *out = outp;
+    int32_t *out = outp;
+    union { int32_t s; uint32_t u; } u;
 
     for( size_t i = 0; i < samples; i++ )
     {
-        uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
-        *(out++) = s;
+        uint_fast32_t hi = in[2], mid = in[1], lo = in[0];
+
+        u.u = ((hi << 24) | (mid << 16) | (lo << 8)) - UINT32_C(0x80000000);
+        *(out++) = u.s;
         in += 3;
     }
 }
 
 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
 {
-    uint32_t *out = outp;
+    int32_t *out = outp;
+    union { int32_t s; uint32_t u; } u;
 
     for( size_t i = 0; i < samples; i++ )
     {
-        uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
-        *(out++) = s;
+        uint_fast32_t hi = in[0], mid = in[1], lo = in[2];
+
+        u.u = (hi << 24) | (mid << 16) | (lo << 8);
+        *(out++) = u.s;
         in += 3;
     }
 }
@@ -459,11 +468,14 @@ static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
 {
     uint32_t *out = outp;
+    union { int32_t s; uint32_t u; } u;
 
     for( size_t i = 0; i < samples; i++ )
     {
-        uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
-        *(out++) = s;
+        uint_fast32_t hi = in[2], mid = in[1], lo = in[0];
+
+        u.u = (hi << 24) | (mid << 16) | (lo << 8);
+        *(out++) = u.s;
         in += 3;
     }
 }



View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/9260acab6a7ecfd5118d3da2b885aeff39cf21da

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/9260acab6a7ecfd5118d3da2b885aeff39cf21da
You're receiving this email because of your account on code.videolan.org.


VideoLAN code repository instance


More information about the vlc-commits mailing list