Fix for integer overflow in NetEq.
BUG=chromium:668736
Review-Url: https://codereview.webrtc.org/2571483002
Cr-Commit-Position: refs/heads/master@{#15654}
diff --git a/webrtc/modules/audio_coding/neteq/expand.cc b/webrtc/modules/audio_coding/neteq/expand.cc
index ffe4370..da870d7 100644
--- a/webrtc/modules/audio_coding/neteq/expand.cc
+++ b/webrtc/modules/audio_coding/neteq/expand.cc
@@ -675,12 +675,20 @@
parameters.ar_filter,
kUnvoicedLpcOrder + 1,
128);
- int16_t unvoiced_prescale;
- if (WebRtcSpl_MaxAbsValueW16(unvoiced_vector, 128) > 4000) {
- unvoiced_prescale = 4;
- } else {
- unvoiced_prescale = 0;
- }
+ const int unvoiced_max_abs = [&] {
+ const int16_t max_abs = WebRtcSpl_MaxAbsValueW16(unvoiced_vector, 128);
+ // Since WebRtcSpl_MaxAbsValueW16 returns 2^15 - 1 when the input contains
+ // -2^15, we have to conservatively bump the return value by 1
+ // if it is 2^15 - 1.
+ return max_abs == WEBRTC_SPL_WORD16_MAX ? max_abs + 1 : max_abs;
+ }();
+ // Pick the smallest n such that 2^n > unvoiced_max_abs; then the maximum
+ // value of the dot product is less than 2^7 * 2^(2*n) = 2^(2*n + 7), so to
+ // prevent overflows we want 2n + 7 <= 31, which means we should shift by
+ // 2n + 7 - 31 bits, if this value is greater than zero.
+ int unvoiced_prescale =
+ std::max(0, 2 * WebRtcSpl_GetSizeInBits(unvoiced_max_abs) - 24);
+
int32_t unvoiced_energy = WebRtcSpl_DotProductWithScale(unvoiced_vector,
unvoiced_vector,
128,
diff --git a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
index b958e27..ecefc45 100644
--- a/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
+++ b/webrtc/modules/audio_coding/neteq/neteq_unittest.cc
@@ -442,10 +442,10 @@
webrtc::test::ResourcePath("audio_coding/neteq_universal_new", "rtp");
const std::string output_checksum = PlatformChecksum(
- "acd33f5c73625c1529c412ad59b5565132826f1b",
- "1a2e82a0410421c1d1d3eb0615334db5e2c63784",
- "acd33f5c73625c1529c412ad59b5565132826f1b",
- "52797b781758a1d2303140b80b9c5030c9093d6b");
+ "5a8184bc60c0d7dddb50af8966360675476a8d8b",
+ "be982d2c5685dd1ca4ea5d352283df50e8e5b46d",
+ "5a8184bc60c0d7dddb50af8966360675476a8d8b",
+ "c86aec95439748f4949de95b50c94be291118615");
const std::string network_stats_checksum = PlatformChecksum(
"f59b3dfdb9b1b8bbb61abedd7c8cf3fc47c21f5f",