conf: fix snd_config_substitute() - memory leak

There's an issue with the current code: It says append for compounds,
but it does overwrite without the proper members delete from
the overwritten (destination) compound node.

Don't change the behaviour, just fix the comment and memory leak.

Signed-off-by: Jaroslav Kysela <perex@perex.cz>
This commit is contained in:
Jaroslav Kysela 2021-05-12 11:39:05 +02:00
parent 1a52373fbc
commit 8f236983b6

View file

@ -1694,8 +1694,9 @@ static int _snd_config_save_children(snd_config_t *config, snd_output_t *out,
* \param src Handle to the source node. Must not be the same as \a dst. * \param src Handle to the source node. Must not be the same as \a dst.
* \return Zero if successful, otherwise a negative error code. * \return Zero if successful, otherwise a negative error code.
* *
* If both nodes are compounds, the source compound node members are * If both nodes are compounds, the source compound node members will
* appended to the destination compound node. * be moved to the destination compound node. The original destination
* compound node members will be deleted (overwritten).
* *
* If the destination node is a compound and the source node is * If the destination node is a compound and the source node is
* an ordinary type, the compound members are deleted (including * an ordinary type, the compound members are deleted (including
@ -1710,8 +1711,13 @@ static int _snd_config_save_children(snd_config_t *config, snd_output_t *out,
int snd_config_substitute(snd_config_t *dst, snd_config_t *src) int snd_config_substitute(snd_config_t *dst, snd_config_t *src)
{ {
assert(dst && src); assert(dst && src);
if (dst->type == SND_CONFIG_TYPE_COMPOUND) {
int err = snd_config_delete_compound_members(dst);
if (err < 0)
return err;
}
if (dst->type == SND_CONFIG_TYPE_COMPOUND && if (dst->type == SND_CONFIG_TYPE_COMPOUND &&
src->type == SND_CONFIG_TYPE_COMPOUND) { /* append */ src->type == SND_CONFIG_TYPE_COMPOUND) { /* overwrite */
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
snd_config_for_each(i, next, src) { snd_config_for_each(i, next, src) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
@ -1719,11 +1725,6 @@ int snd_config_substitute(snd_config_t *dst, snd_config_t *src)
} }
src->u.compound.fields.next->prev = &dst->u.compound.fields; src->u.compound.fields.next->prev = &dst->u.compound.fields;
src->u.compound.fields.prev->next = &dst->u.compound.fields; src->u.compound.fields.prev->next = &dst->u.compound.fields;
} else if (dst->type == SND_CONFIG_TYPE_COMPOUND) {
int err;
err = snd_config_delete_compound_members(dst);
if (err < 0)
return err;
} }
free(dst->id); free(dst->id);
dst->id = src->id; dst->id = src->id;