summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/audio/win/audio_output_win.cc13
-rw-r--r--media/audio/win/audio_output_win_unittest.cc32
-rw-r--r--media/audio/win/waveout_output_win.cc5
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_,