aboutsummaryrefslogtreecommitdiff
path: root/engines/lastexpress
diff options
context:
space:
mode:
authorEvgeny Grechnikov2018-10-16 00:49:07 +0300
committerEvgeny Grechnikov2018-10-16 00:49:07 +0300
commit8162309212bbc287632fc375d1740a64733019fb (patch)
tree0b78997549fd0de4ad18dbf09fbb7b2e886eb770 /engines/lastexpress
parent45641f3de5c598b534b36d4ba0f30ac6b41d9bac (diff)
downloadscummvm-rg350-8162309212bbc287632fc375d1740a64733019fb.tar.gz
scummvm-rg350-8162309212bbc287632fc375d1740a64733019fb.tar.bz2
scummvm-rg350-8162309212bbc287632fc375d1740a64733019fb.zip
LASTEXPRESS: fix race condition in sound code
SoundEntry::play() calls StreamedSound::setFilterId(), StreamSound::setFilterId() requires the underlying reference to be alive. SoundQueue::handleTimer() checks that the stream is still alive by calling SoundEntry::isFinished(). However, if the stream is finalized just between calls to SoundEntry::isFinished() and SoundEntry::play(), the sound mixer frees the stream leading to use-after-free in setFilterId(). Turn off the automatical disposing, delete the stream in SoundEntry::~SoundEntry().
Diffstat (limited to 'engines/lastexpress')
-rw-r--r--engines/lastexpress/data/snd.cpp14
-rw-r--r--engines/lastexpress/data/snd.h2
2 files changed, 11 insertions, 5 deletions
diff --git a/engines/lastexpress/data/snd.cpp b/engines/lastexpress/data/snd.cpp
index e310bafd18..4cff837193 100644
--- a/engines/lastexpress/data/snd.cpp
+++ b/engines/lastexpress/data/snd.cpp
@@ -446,8 +446,9 @@ LastExpress_ADPCMStream *SimpleSound::makeDecoder(Common::SeekableReadStream *in
return new LastExpress_ADPCMStream(in, DisposeAfterUse::YES, size, _blockSize, filterId);
}
-void SimpleSound::play(Audio::AudioStream *as) {
- g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, as);
+void SimpleSound::play(Audio::AudioStream *as, DisposeAfterUse::Flag autofreeStream) {
+ g_system->getMixer()->playStream(Audio::Mixer::kPlainSoundType, &_handle, as,
+ -1, Audio::Mixer::kMaxChannelVolume, 0, autofreeStream);
}
//////////////////////////////////////////////////////////////////////////
@@ -456,6 +457,7 @@ void SimpleSound::play(Audio::AudioStream *as) {
StreamedSound::StreamedSound() : _as(NULL), _loaded(false) {}
StreamedSound::~StreamedSound() {
+ delete _as;
_as = NULL;
}
@@ -467,11 +469,15 @@ bool StreamedSound::load(Common::SeekableReadStream *stream, int32 filterId) {
loadHeader(stream);
+ if (_as) {
+ stop();
+ delete _as;
+ }
// Start decoding the input stream
_as = makeDecoder(stream, _size, filterId);
// Start playing the decoded audio stream
- play(_as);
+ play(_as, DisposeAfterUse::NO);
_loaded = true;
@@ -501,7 +507,7 @@ AppendableSound::AppendableSound() : SimpleSound() {
_finished = false;
// Start playing the decoded audio stream
- play(_as);
+ play(_as, DisposeAfterUse::YES);
// Initialize the block size
// TODO: get it as an argument?
diff --git a/engines/lastexpress/data/snd.h b/engines/lastexpress/data/snd.h
index 19e5fda9c9..23aae905ac 100644
--- a/engines/lastexpress/data/snd.h
+++ b/engines/lastexpress/data/snd.h
@@ -62,7 +62,7 @@ public:
protected:
void loadHeader(Common::SeekableReadStream *in);
LastExpress_ADPCMStream *makeDecoder(Common::SeekableReadStream *in, uint32 size, int32 filterId = -1) const;
- void play(Audio::AudioStream *as);
+ void play(Audio::AudioStream *as, DisposeAfterUse::Flag autofreeStream);
uint32 _size; ///< data size
///< - NIS: size of all blocks, including those located in the matching LNK file