ALSA: pcm: oss: Place the plugin buffer overflow checks correctly

The checks of the plugin buffer overflow in the previous fix by commit
  f2ecf903ef ("ALSA: pcm: oss: Avoid plugin buffer overflow")
are put in the wrong places mistakenly, which leads to the expected
(repeated) sound when the rate plugin is involved.  Fix in the right
places.

Also, at those right places, the zero check is needed for the
termination node, so added there as well, and let's get it done,
finally.

Fixes: f2ecf903ef ("ALSA: pcm: oss: Avoid plugin buffer overflow")
Cc: <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Takashi Iwai <[email protected]>
This commit is contained in:
Takashi Iwai committed 2020-04-24 21:34:52 +02:00
1 parent ae769d3556
commit 4285de0725
1 file changed
+12 -8
+12 -8
View File
@@ -211,21 +211,23 @@ static snd_pcm_sframes_t plug_client_size(struct snd_pcm_substream *plug,
if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
plugin = snd_pcm_plug_last(plug);
while (plugin && drv_frames > 0) {
if (check_size && drv_frames > plugin->buf_frames)
drv_frames = plugin->buf_frames;
plugin_prev = plugin->prev;
if (plugin->src_frames)
drv_frames = plugin->src_frames(plugin, drv_frames);
if (check_size && plugin->buf_frames &&
drv_frames > plugin->buf_frames)
drv_frames = plugin->buf_frames;
plugin = plugin_prev;
}
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
plugin = snd_pcm_plug_first(plug);
while (plugin && drv_frames > 0) {
plugin_next = plugin->next;
if (check_size && plugin->buf_frames &&
drv_frames > plugin->buf_frames)
drv_frames = plugin->buf_frames;
if (plugin->dst_frames)
drv_frames = plugin->dst_frames(plugin, drv_frames);
if (check_size && drv_frames > plugin->buf_frames)
drv_frames = plugin->buf_frames;
plugin = plugin_next;
}
} else
@@ -251,26 +253,28 @@ static snd_pcm_sframes_t plug_slave_size(struct snd_pcm_substream *plug,
plugin = snd_pcm_plug_first(plug);
while (plugin && frames > 0) {
plugin_next = plugin->next;
if (check_size && plugin->buf_frames &&
frames > plugin->buf_frames)
frames = plugin->buf_frames;
if (plugin->dst_frames) {
frames = plugin->dst_frames(plugin, frames);
if (frames < 0)
return frames;
}
if (check_size && frames > plugin->buf_frames)
frames = plugin->buf_frames;
plugin = plugin_next;
}
} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
plugin = snd_pcm_plug_last(plug);
while (plugin) {
if (check_size && frames > plugin->buf_frames)
frames = plugin->buf_frames;
plugin_prev = plugin->prev;
if (plugin->src_frames) {
frames = plugin->src_frames(plugin, frames);
if (frames < 0)
return frames;
}
if (check_size && plugin->buf_frames &&
frames > plugin->buf_frames)
frames = plugin->buf_frames;
plugin = plugin_prev;
}
} else