diff options
-rw-r--r-- | media/audio/win/audio_output_win.cc | 13 | ||||
-rw-r--r-- | media/audio/win/audio_output_win_unittest.cc | 32 | ||||
-rw-r--r-- | media/audio/win/waveout_output_win.cc | 5 |
3 files changed, 50 insertions, 0 deletions
diff --git a/media/audio/win/audio_output_win.cc b/media/audio/win/audio_output_win.cc index 5990e27..1ece5eb 100644 --- a/media/audio/win/audio_output_win.cc +++ b/media/audio/win/audio_output_win.cc @@ -85,6 +85,14 @@ class AudioOutputStreamMockWin : public AudioOutputStream { }; namespace { + +// The next 3 constants are some sensible limits to prevent integer overflow +// at this layer. +// TODO(cpu): Some day expand the support and API to more than stereo. +const int kMaxChannels = 2; +const int kMaxSampleRate = 192000; +const int kMaxBitsPerSample = 64; + AudioOutputStreamMockWin* g_last_mock_stream = NULL; AudioManagerWin* g_audio_manager = NULL; @@ -109,6 +117,11 @@ bool AudioManagerWin::HasAudioDevices() { AudioOutputStream* AudioManagerWin::MakeAudioStream(Format format, int channels, int sample_rate, char bits_per_sample) { + if ((channels > kMaxChannels) || (channels <= 0) || + (sample_rate > kMaxSampleRate) || (sample_rate <= 0) || + (bits_per_sample > kMaxBitsPerSample) || (bits_per_sample <= 0)) + return NULL; + if (format == AUDIO_MOCK) { return new AudioOutputStreamMockWin(this); } else if (format == AUDIO_PCM_LINEAR) { diff --git a/media/audio/win/audio_output_win_unittest.cc b/media/audio/win/audio_output_win_unittest.cc index c71d944..fae74ac 100644 --- a/media/audio/win/audio_output_win_unittest.cc +++ b/media/audio/win/audio_output_win_unittest.cc @@ -260,6 +260,23 @@ TEST(WinAudioTest, PCMWaveStreamGetAndClose) { oas->Close(); } +// Test that can it be cannot be created with crazy parameters +TEST(WinAudioTest, SanityOnMakeParams) { + if (IsRunningHeadless()) + return; + AudioManager* audio_man = AudioManager::GetAudioManager(); + ASSERT_TRUE(NULL != audio_man); + if (!audio_man->HasAudioDevices()) + return; + AudioManager::Format fmt = AudioManager::AUDIO_PCM_LINEAR; + EXPECT_TRUE(NULL == audio_man->MakeAudioStream(fmt, 8, 8000, 16)); + EXPECT_TRUE(NULL == audio_man->MakeAudioStream(fmt, 1, 1024 * 1024, 16)); + EXPECT_TRUE(NULL == audio_man->MakeAudioStream(fmt, 2, 8000, 80)); + EXPECT_TRUE(NULL == audio_man->MakeAudioStream(fmt, -2, 8000, 16)); + EXPECT_TRUE(NULL == audio_man->MakeAudioStream(fmt, 2, -8000, 16)); + EXPECT_TRUE(NULL == audio_man->MakeAudioStream(fmt, 2, -8000, -16)); +} + // Test that it can be opened and closed. TEST(WinAudioTest, PCMWaveStreamOpenAndClose) { if (IsRunningHeadless()) @@ -275,6 +292,21 @@ TEST(WinAudioTest, PCMWaveStreamOpenAndClose) { oas->Close(); } +// Test that it has a maximum packet size. +TEST(WinAudioTest, PCMWaveStreamOpenLimit) { + if (IsRunningHeadless()) + return; + AudioManager* audio_man = AudioManager::GetAudioManager(); + ASSERT_TRUE(NULL != audio_man); + if (!audio_man->HasAudioDevices()) + return; + AudioOutputStream* oas = + audio_man->MakeAudioStream(AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16); + ASSERT_TRUE(NULL != oas); + EXPECT_FALSE(oas->Open(1024 * 1024 * 1024)); + oas->Close(); +} + // Test that it uses the double buffers correctly. Because it uses the actual // audio device, you might hear a short pop noise for a short time. TEST(WinAudioTest, PCMWaveStreamDoubleBuffer) { diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc index 9828bd8..77b2d36 100644 --- a/media/audio/win/waveout_output_win.cc +++ b/media/audio/win/waveout_output_win.cc @@ -38,6 +38,9 @@ const size_t kNumBuffers = 2; // perceived volume increase sounds linear. const double kMaxVolumeLevel = 65535.0; +// Sixty four MB is the maximum buffer size per AudioOutputStream. +const size_t kMaxOpenBufferSize = 1024 * 1024 * 64; + // Our sound buffers are allocated once and kept in a linked list using the // the WAVEHDR::dwUser variable. The last buffer points to the first buffer. WAVEHDR* GetNextBuffer(WAVEHDR* current) { @@ -75,6 +78,8 @@ PCMWaveOutAudioOutputStream::~PCMWaveOutAudioOutputStream() { bool PCMWaveOutAudioOutputStream::Open(size_t buffer_size) { if (state_ != PCMA_BRAND_NEW) return false; + if (buffer_size > kMaxOpenBufferSize) + return false; // Open the device. We'll be getting callback in WaveCallback function. They // occur in a magic, time-critical thread that windows creates. MMRESULT result = ::waveOutOpen(&waveout_, device_id_, &format_, |