Skip to content

Commit 4612174

Browse files
committed
Fix issue with potential audio block leak
If there aren't enough audio blocks to allocate, the previous code returned without releasing the ones it had allocated, leaving them unavailable for re-use. This would almost certainly rapidly break the entire audio system.
1 parent d8a055e commit 4612174

File tree

1 file changed

+32
-19
lines changed

1 file changed

+32
-19
lines changed

src/playresmp.h

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -99,11 +99,12 @@ class AudioPlayResmp : public AudioStream
9999

100100
void update()
101101
{
102+
bool gotBlocks = true;
102103
int _numChannels = reader->getNumChannels();
103104
if (_numChannels == -1)
104105
return;
105106

106-
unsigned int i, n;
107+
unsigned int n;
107108
audio_block_t *blocks[_numChannels];
108109
int16_t *data[_numChannels];
109110
// only update if we're playing
@@ -112,28 +113,40 @@ class AudioPlayResmp : public AudioStream
112113
// allocate the audio blocks to transmit
113114
for (int i=0; i < _numChannels; i++) {
114115
blocks[i] = allocate();
115-
if (blocks[i] == nullptr) return;
116-
data[i] = blocks[i]->data;
116+
if (blocks[i] == nullptr)
117+
gotBlocks = false;
118+
else
119+
data[i] = blocks[i]->data;
117120
}
118121

119-
if (reader->available()) {
120-
// we can read more data from the file...
121-
n = reader->read((void**)data, AUDIO_BLOCK_SAMPLES);
122-
for (int channel=0; channel < _numChannels; channel++) {
123-
memset( &blocks[channel]->data[n], 0, (AUDIO_BLOCK_SAMPLES - n) * 2);
124-
transmit(blocks[channel], channel);
125-
}
126-
127-
if(_numChannels == 1) {
128-
transmit(blocks[0], 1);
129-
}
130-
} else {
131-
reader->close();
132-
}
133-
for (int channel=0; channel < _numChannels; channel++) {
134-
release(blocks[channel]);
122+
if (gotBlocks) // enough blocks, do the transmit
123+
{
124+
if (reader->available()) {
125+
// we can read more data from the file...
126+
n = reader->read((void**)data, AUDIO_BLOCK_SAMPLES);
127+
for (int channel=0; channel < _numChannels; channel++) {
128+
memset( &blocks[channel]->data[n], 0, (AUDIO_BLOCK_SAMPLES - n) * 2);
129+
transmit(blocks[channel], channel);
130+
}
131+
132+
if(_numChannels == 1) {
133+
transmit(blocks[0], 1);
134+
}
135+
136+
} else {
137+
reader->close();
138+
}
139+
}
140+
141+
// release all allocated blocks, even if there
142+
// weren't enough and we couldn't transmit
143+
for (int channel=0; channel < _numChannels; channel++)
144+
{
145+
if (nullptr != blocks[channel]) // only release if allocated!
146+
release(blocks[channel]);
135147
}
136148
}
149+
137150
uint32_t positionMillis()
138151
{
139152
return reader->positionMillis();

0 commit comments

Comments
 (0)