diff options
author | turaj@webrtc.org <turaj@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2013-05-14 17:42:22 +0000 |
---|---|---|
committer | turaj@webrtc.org <turaj@webrtc.org@4adac7df-926f-26a2-2b94-8c16560cd09d> | 2013-05-14 17:42:22 +0000 |
commit | f6e0404878530323f642d00b758b4d6105969c93 (patch) | |
tree | 04d22eecd18f2e58a5352af99acefa788be00bee | |
parent | 2cc529f0d55ce2768945b8009c9b3013ca077e0e (diff) | |
download | webrtc-f6e0404878530323f642d00b758b4d6105969c93.tar.gz |
Address sanitizer out of bounds read in iSAC
BUG=issue1770
TBR=tlegrand@google.com
Review URL: https://webrtc-codereview.appspot.com/1472006
git-svn-id: http://webrtc.googlecode.com/svn/trunk/webrtc@4030 4adac7df-926f-26a2-2b94-8c16560cd09d
3 files changed, 131 insertions, 12 deletions
diff --git a/modules/audio_coding/codecs/isac/main/source/isac.c b/modules/audio_coding/codecs/isac/main/source/isac.c index ed794a5b..1e902720 100644 --- a/modules/audio_coding/codecs/isac/main/source/isac.c +++ b/modules/audio_coding/codecs/isac/main/source/isac.c @@ -272,17 +272,21 @@ int16_t WebRtcIsac_Assign(ISACStruct** ISAC_main_inst, int16_t WebRtcIsac_Create(ISACStruct** ISAC_main_inst) { ISACMainStruct* instISAC; - instISAC = (ISACMainStruct*)WEBRTC_SPL_VNEW(ISACMainStruct, 1); - *ISAC_main_inst = (ISACStruct*)instISAC; - if (*ISAC_main_inst != NULL) { - instISAC->errorCode = 0; - instISAC->initFlag = 0; - /* Default is wideband. */ - instISAC->bandwidthKHz = isac8kHz; - instISAC->encoderSamplingRateKHz = kIsacWideband; - instISAC->decoderSamplingRateKHz = kIsacWideband; - instISAC->in_sample_rate_hz = 16000; - return 0; + if (ISAC_main_inst != NULL) { + instISAC = (ISACMainStruct*)WEBRTC_SPL_VNEW(ISACMainStruct, 1); + *ISAC_main_inst = (ISACStruct*)instISAC; + if (*ISAC_main_inst != NULL) { + instISAC->errorCode = 0; + instISAC->initFlag = 0; + /* Default is wideband. */ + instISAC->bandwidthKHz = isac8kHz; + instISAC->encoderSamplingRateKHz = kIsacWideband; + instISAC->decoderSamplingRateKHz = kIsacWideband; + instISAC->in_sample_rate_hz = 16000; + return 0; + } else { + return -1; + } } else { return -1; } @@ -1015,7 +1019,9 @@ int16_t WebRtcIsac_UpdateBwEstimate(ISACStruct* ISAC_main_inst, return -1; } - if (packet_size <= 0) { + /* Check that the size of the packet is valid, and if not return without + * updating the bandwidth estimate. A valid size is at least 10 bytes. */ + if (packet_size < 10) { /* Return error code if the packet length is null. */ instISAC->errorCode = ISAC_EMPTY_PACKET; return -1; diff --git a/modules/audio_coding/codecs/isac/main/source/isac_unittest.cc b/modules/audio_coding/codecs/isac/main/source/isac_unittest.cc new file mode 100644 index 00000000..3c55bd3d --- /dev/null +++ b/modules/audio_coding/codecs/isac/main/source/isac_unittest.cc @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ +#include <string> + +#include "testing/gtest/include/gtest/gtest.h" +#include "webrtc/modules/audio_coding/codecs/isac/main/interface/isac.h" +#include "webrtc/test/testsupport/fileutils.h" + +struct WebRtcISACStruct; + +namespace webrtc { + +// Number of samples in a 60 ms, sampled at 32 kHz. +const int kIsacNumberOfSamples = 320 * 6; +// Maximum number of bytes in output bitstream. +const size_t kMaxBytes = 1000; + +class IsacTest : public ::testing::Test { + protected: + IsacTest(); + virtual void SetUp(); + + WebRtcISACStruct* isac_codec_; + + int16_t speech_data_[kIsacNumberOfSamples]; + int16_t output_data_[kIsacNumberOfSamples]; + int16_t bitstream_[kMaxBytes / 2]; + uint8_t bitstream_small_[7]; // Simulate sync packets. +}; + +IsacTest::IsacTest() + : isac_codec_(NULL) { +} + +void IsacTest::SetUp() { + // Read some samples from a speech file, to be used in the encode test. + FILE* input_file; + const std::string file_name = + webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm"); + input_file = fopen(file_name.c_str(), "rb"); + ASSERT_TRUE(input_file != NULL); + ASSERT_EQ(kIsacNumberOfSamples, + static_cast<int32_t>(fread(speech_data_, sizeof(int16_t), + kIsacNumberOfSamples, input_file))); + fclose(input_file); + input_file = NULL; +} + +// Test failing Create. +TEST_F(IsacTest, IsacCreateFail) { + // Test to see that an invalid pointer is caught. + EXPECT_EQ(-1, WebRtcIsac_Create(NULL)); +} + +// Test failing Free. +TEST_F(IsacTest, IsacFreeFail) { + // Test to see that free function doesn't crash. + EXPECT_EQ(0, WebRtcIsac_Free(NULL)); +} + +// Test normal Create and Free. +TEST_F(IsacTest, IsacCreateFree) { + EXPECT_EQ(0, WebRtcIsac_Create(&isac_codec_)); + EXPECT_TRUE(isac_codec_ != NULL); + EXPECT_EQ(0, WebRtcIsac_Free(isac_codec_));} + +TEST_F(IsacTest, IsacUpdateBWE) { + // Create encoder memory. + EXPECT_EQ(0, WebRtcIsac_Create(&isac_codec_)); + + // Init encoder (adaptive mode) and decoder. + WebRtcIsac_EncoderInit(isac_codec_, 0); + WebRtcIsac_DecoderInit(isac_codec_); + + // Encode & decode. + int16_t encoded_bytes; + uint16_t* coded = reinterpret_cast<uint16_t*>(bitstream_); + uint16_t* coded_small = reinterpret_cast<uint16_t*>(bitstream_small_); + + // Test with call with a small packet (sync packet). + EXPECT_EQ(-1, WebRtcIsac_UpdateBwEstimate(isac_codec_, coded_small, 7, 1, + 12345, 56789)); + + // Encode 60 ms of data (needed to create a first packet). + encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_); + EXPECT_EQ(0, encoded_bytes); + encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_); + EXPECT_EQ(0, encoded_bytes); + encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_); + EXPECT_EQ(0, encoded_bytes); + encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_); + EXPECT_EQ(0, encoded_bytes); + encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_); + EXPECT_EQ(0, encoded_bytes); + encoded_bytes = WebRtcIsac_Encode(isac_codec_, speech_data_, bitstream_); + + // Call to update bandwidth estimator with real data. + EXPECT_EQ(0, WebRtcIsac_UpdateBwEstimate(isac_codec_, coded, encoded_bytes, 1, + 12345, 56789)); + + // Free memory. + EXPECT_EQ(0, WebRtcIsac_Free(isac_codec_)); +} + +} // namespace webrtc diff --git a/modules/audio_coding/main/source/audio_coding_module.gypi b/modules/audio_coding/main/source/audio_coding_module.gypi index 3208e818..753291ba 100644 --- a/modules/audio_coding/main/source/audio_coding_module.gypi +++ b/modules/audio_coding/main/source/audio_coding_module.gypi @@ -188,6 +188,7 @@ '../../codecs/isac/fix/source/filterbanks_unittest.cc', '../../codecs/isac/fix/source/lpc_masking_model_unittest.cc', '../../codecs/isac/fix/source/transform_unittest.cc', + '../../codecs/isac/main/source/isac_unittest.cc', '../../codecs/opus/opus_unittest.cc', # Test for NetEq 4. '../../neteq4/audio_multi_vector_unittest.cc', |