summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2013-06-04 15:58:34 +0200
committerJaroslav Kysela <perex@perex.cz>2013-06-04 15:58:34 +0200
commitca487c9511c1500184023dfea803a5e785d725e2 (patch)
treeda26bf4b9536b381665ef15ef8caf70eea2b1d94
parentf2d39afe6139ab16aa2aeea0f51f32db79ab1262 (diff)
downloadalsa-lib-ca487c9511c1500184023dfea803a5e785d725e2.tar.gz
pcm_direct: fix the memory leak when parsing the slave definitions
Reported-by: <bolsunov@telum.ru> Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r--src/pcm/pcm_direct.c32
1 files changed, 23 insertions, 9 deletions
diff --git a/src/pcm/pcm_direct.c b/src/pcm/pcm_direct.c
index 38c6c662..101d3c8a 100644
--- a/src/pcm/pcm_direct.c
+++ b/src/pcm/pcm_direct.c
@@ -1453,7 +1453,7 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
int hop)
{
snd_config_iterator_t i, next;
- snd_config_t *pcm_conf;
+ snd_config_t *pcm_conf, *pcm_conf2;
int err;
long card = 0, device = 0, subdevice = 0;
const char *str;
@@ -1484,14 +1484,28 @@ static int _snd_pcm_direct_get_slave_ipc_offset(snd_config_t *root,
}
#endif
- if (snd_config_search(sconf, "slave", &pcm_conf) >= 0 &&
- (snd_config_search(pcm_conf, "pcm", &pcm_conf) >= 0 ||
- (snd_config_get_string(pcm_conf, &str) >= 0 &&
- snd_config_search_definition(root, "pcm_slave", str, &pcm_conf) >= 0 &&
- snd_config_search(pcm_conf, "pcm", &pcm_conf) >= 0)))
- return _snd_pcm_direct_get_slave_ipc_offset(root, pcm_conf,
- direction,
- hop + 1);
+ if (snd_config_search(sconf, "slave", &pcm_conf) >= 0) {
+ if (snd_config_search(pcm_conf, "pcm", &pcm_conf) >= 0) {
+ return _snd_pcm_direct_get_slave_ipc_offset(root,
+ pcm_conf,
+ direction,
+ hop + 1);
+ } else {
+ if (snd_config_get_string(pcm_conf, &str) >= 0 &&
+ snd_config_search_definition(root, "pcm_slave",
+ str, &pcm_conf) >= 0) {
+ if (snd_config_search(pcm_conf, "pcm",
+ &pcm_conf2) >= 0) {
+ err =
+ _snd_pcm_direct_get_slave_ipc_offset(
+ root, pcm_conf2, direction, hop + 1);
+ snd_config_delete(pcm_conf);
+ return err;
+ }
+ snd_config_delete(pcm_conf);
+ }
+ }
+ }
snd_config_for_each(i, next, sconf) {
snd_config_t *n = snd_config_iterator_entry(i);