aboutsummaryrefslogtreecommitdiff
path: root/silk/SigProc_FIX.h
diff options
context:
space:
mode:
authorRay Essick <essick@google.com>2019-01-28 14:10:29 -0800
committerRay Essick <essick@google.com>2019-01-29 12:33:58 -0800
commit7f037a253e60a0b3d77dccc56fb23e1219f6513b (patch)
treec3892eb363dbb91bdac682f77b6b0233cb5a6492 /silk/SigProc_FIX.h
parent31ed9ac202461bb76d36cf42fcf1f3e1e31ef745 (diff)
downloadlibopus-7f037a253e60a0b3d77dccc56fb23e1219f6513b.tar.gz
Fix integer overflow diagnostics within opus
Recast several points in the Opus code where integer overflow happens. The code expects overflow in these macros, but doesn't expect the system to abort when it happens. This also includes saturating math. Bug: 123428774 Test: Cts android.media.cts.EncoderTest#testOpusEncoders
Diffstat (limited to 'silk/SigProc_FIX.h')
-rw-r--r--silk/SigProc_FIX.h29
1 files changed, 25 insertions, 4 deletions
diff --git a/silk/SigProc_FIX.h b/silk/SigProc_FIX.h
index f9ae3263..a9068908 100644
--- a/silk/SigProc_FIX.h
+++ b/silk/SigProc_FIX.h
@@ -448,13 +448,29 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
/* Adds two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
(just standard two's complement implementation-specific behaviour) */
-#define silk_ADD32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) + (opus_uint32)(b)))
+static OPUS_INLINE opus_int32 silk_ADD32_ovflw(opus_int32 a, opus_int32 b) {
+ opus_int32 _c;
+ __builtin_add_overflow(a, b, &_c);
+ return _c;
+}
+
/* Subtractss two signed 32-bit values in a way that can overflow, while not relying on undefined behaviour
(just standard two's complement implementation-specific behaviour) */
-#define silk_SUB32_ovflw(a, b) ((opus_int32)((opus_uint32)(a) - (opus_uint32)(b)))
+static OPUS_INLINE opus_int32 silk_SUB32_ovflw(opus_int32 a, opus_int32 b) {
+ opus_int32 _c;
+ __builtin_sub_overflow(a, b, &_c);
+ return _c;
+}
/* Multiply-accumulate macros that allow overflow in the addition (ie, no asserts in debug mode) */
-#define silk_MLA_ovflw(a32, b32, c32) silk_ADD32_ovflw((a32), (opus_uint32)(b32) * (opus_uint32)(c32))
+/* .. also ignoring multiply overflows; caller has comment about this happening occasionally */
+static OPUS_INLINE opus_int32 silk_MLA_ovflw(opus_int32 a, opus_int32 b, opus_int32 c) {
+ opus_int32 _d, _e;
+ __builtin_mul_overflow(b, c, &_d);
+ __builtin_add_overflow(a, _d, &_e);
+ return _e;
+}
+
#define silk_SMLABB_ovflw(a32, b32, c32) (silk_ADD32_ovflw((a32) , ((opus_int32)((opus_int16)(b32))) * (opus_int32)((opus_int16)(c32))))
#define silk_DIV32_16(a32, b16) ((opus_int32)((a32) / (b16)))
@@ -496,7 +512,12 @@ static OPUS_INLINE opus_int32 silk_ROR32( opus_int32 a32, opus_int rot )
/* Add with saturation for positive input values */
#define silk_ADD_POS_SAT8(a, b) ((((a)+(b)) & 0x80) ? silk_int8_MAX : ((a)+(b)))
#define silk_ADD_POS_SAT16(a, b) ((((a)+(b)) & 0x8000) ? silk_int16_MAX : ((a)+(b)))
-#define silk_ADD_POS_SAT32(a, b) ((((opus_uint32)(a)+(opus_uint32)(b)) & 0x80000000) ? silk_int32_MAX : ((a)+(b)))
+static OPUS_INLINE opus_int32 silk_ADD_POS_SAT32(opus_int32 a, opus_int32 b) {
+ opus_int32 _c;
+ if (__builtin_add_overflow(a, b, &_c))
+ return silk_int32_MAX;
+ return _c;
+}
#define silk_LSHIFT8(a, shift) ((opus_int8)((opus_uint8)(a)<<(shift))) /* shift >= 0, shift < 8 */
#define silk_LSHIFT16(a, shift) ((opus_int16)((opus_uint16)(a)<<(shift))) /* shift >= 0, shift < 16 */