summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Marc Valin <jmvalin@jmvalin.ca>2016-07-30 22:40:48 -0400
committerJean-Marc Valin <jmvalin@jmvalin.ca>2016-08-17 16:04:00 -0400
commit8ab3e80ec46e8f811c5f880890488029261dea70 (patch)
tree6673bbdfe9392b6000314e10fabd941db7e67005
parent18335e8e4d6ddb289b31d8a4a362f5e15c24ff0a (diff)
downloadopus-8ab3e80ec46e8f811c5f880890488029261dea70.tar.gz
Fixes an overflow in LPC_inverse_pred_gain_QA()
We now declare that anything that would overflow is not stable enough
-rw-r--r--silk/LPC_inv_pred_gain.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/silk/LPC_inv_pred_gain.c b/silk/LPC_inv_pred_gain.c
index 257b28fd..87d9a499 100644
--- a/silk/LPC_inv_pred_gain.c
+++ b/silk/LPC_inv_pred_gain.c
@@ -77,10 +77,21 @@ static opus_int32 LPC_inverse_pred_gain_QA( /* O Returns inver
/* Update AR coefficient */
for( n = 0; n < (k + 1) >> 1; n++ ) {
+ opus_int64 tmp64;
tmp1 = A_QA[ n ];
tmp2 = A_QA[ k - n - 1 ];
- A_QA[ n ] = MUL32_FRAC_Q( tmp1 - MUL32_FRAC_Q( tmp2, rc_Q31, 31 ), rc_mult2, mult2Q );
- A_QA[ k - n - 1 ] = MUL32_FRAC_Q( tmp2 - MUL32_FRAC_Q( tmp1, rc_Q31, 31 ), rc_mult2, mult2Q );
+ tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp1,
+ MUL32_FRAC_Q( tmp2, rc_Q31, 31 ) ), rc_mult2 ), mult2Q);
+ if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
+ return 0;
+ }
+ A_QA[ n ] = ( opus_int32 )tmp64;
+ tmp64 = silk_RSHIFT_ROUND64( silk_SMULL( silk_SUB_SAT32(tmp2,
+ MUL32_FRAC_Q( tmp1, rc_Q31, 31 ) ), rc_mult2), mult2Q);
+ if( tmp64 > silk_int32_MAX || tmp64 < silk_int32_MIN ) {
+ return 0;
+ }
+ A_QA[ k - n - 1 ] = ( opus_int32 )tmp64;
}
}