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

David (@dfuhrmann) gitlab at videolan.org
Sat Sep 3 15:43:24 UTC 2022



David pushed to branch 3.0.x at VideoLAN / VLC


Commits:
50d44064 by RĂ©mi Denis-Courmont at 2022-09-03T14:51:33+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.

(cherry picked from commit 9260acab6a7ecfd5118d3da2b885aeff39cf21da)

- - - - -


1 changed file:

- modules/codec/araw.c


Changes:

=====================================
modules/codec/araw.c
=====================================
@@ -436,36 +436,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;
     }
 }
@@ -473,11 +482,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/50d440647bd5a4c5828316c8a13e79ad91bf0fa3

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/commit/50d440647bd5a4c5828316c8a13e79ad91bf0fa3
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