stanza: fix memory leaks
Free attribute "to" before replacing it in xmpp_stanza_reply(). Free value on insertion error in xmpp_stanza_set_attribute(). Don't copy attributes manually. Use xmpp_stanza_set_attribute() instead.
This commit is contained in:
56
src/stanza.c
56
src/stanza.c
@@ -76,35 +76,27 @@ xmpp_stanza_t *xmpp_stanza_clone(xmpp_stanza_t * const stanza)
|
|||||||
static int _stanza_copy_attributes(xmpp_stanza_t * dst,
|
static int _stanza_copy_attributes(xmpp_stanza_t * dst,
|
||||||
const xmpp_stanza_t * const src)
|
const xmpp_stanza_t * const src)
|
||||||
{
|
{
|
||||||
hash_iterator_t *iter = NULL;
|
hash_iterator_t *iter;
|
||||||
const char *key;
|
const char *key;
|
||||||
void *val;
|
const char *val;
|
||||||
|
int rc = XMPP_EOK;
|
||||||
|
|
||||||
dst->attributes = hash_new(src->ctx, 8, xmpp_free);
|
|
||||||
if (!dst->attributes)
|
|
||||||
return -1;
|
|
||||||
iter = hash_iter_new(src->attributes);
|
iter = hash_iter_new(src->attributes);
|
||||||
if (!iter)
|
if (!iter) rc = XMPP_EMEM;
|
||||||
goto error;
|
|
||||||
while ((key = hash_iter_next(iter))) {
|
|
||||||
val = xmpp_strdup(src->ctx,
|
|
||||||
(char *)hash_get(src->attributes, key));
|
|
||||||
if (!val)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (hash_add(dst->attributes, key, val)) {
|
while (rc == XMPP_EOK && (key = hash_iter_next(iter))) {
|
||||||
xmpp_free(src->ctx, val);
|
val = hash_get(src->attributes, key);
|
||||||
goto error;
|
if (!val) rc = XMPP_EINT;
|
||||||
}
|
if (rc == XMPP_EOK)
|
||||||
|
rc = xmpp_stanza_set_attribute(dst, key, val);
|
||||||
}
|
}
|
||||||
hash_iter_release(iter);
|
hash_iter_release(iter);
|
||||||
return 0;
|
|
||||||
|
|
||||||
error:
|
if (rc != XMPP_EOK && dst->attributes) {
|
||||||
if (iter != NULL)
|
hash_release(dst->attributes);
|
||||||
hash_iter_release(iter);
|
dst->attributes = NULL;
|
||||||
hash_release(dst->attributes);
|
}
|
||||||
return -1;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Copy a stanza and its children.
|
/** Copy a stanza and its children.
|
||||||
@@ -570,6 +562,7 @@ int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza,
|
|||||||
const char * const value)
|
const char * const value)
|
||||||
{
|
{
|
||||||
char *val;
|
char *val;
|
||||||
|
int rc;
|
||||||
|
|
||||||
if (stanza->type != XMPP_STANZA_TAG) return XMPP_EINVOP;
|
if (stanza->type != XMPP_STANZA_TAG) return XMPP_EINVOP;
|
||||||
|
|
||||||
@@ -584,7 +577,11 @@ int xmpp_stanza_set_attribute(xmpp_stanza_t * const stanza,
|
|||||||
return XMPP_EMEM;
|
return XMPP_EMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
hash_add(stanza->attributes, key, val);
|
rc = hash_add(stanza->attributes, key, val);
|
||||||
|
if (rc < 0) {
|
||||||
|
xmpp_free(stanza->ctx, val);
|
||||||
|
return XMPP_EMEM;
|
||||||
|
}
|
||||||
|
|
||||||
return XMPP_EOK;
|
return XMPP_EOK;
|
||||||
}
|
}
|
||||||
@@ -1047,7 +1044,12 @@ int xmpp_stanza_del_attribute(xmpp_stanza_t * const stanza,
|
|||||||
*/
|
*/
|
||||||
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t * const stanza)
|
xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t * const stanza)
|
||||||
{
|
{
|
||||||
xmpp_stanza_t *copy;
|
xmpp_stanza_t *copy = NULL;
|
||||||
|
const char *from;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
from = xmpp_stanza_get_from(stanza);
|
||||||
|
if (!from) goto copy_error;
|
||||||
|
|
||||||
copy = xmpp_stanza_new(stanza->ctx);
|
copy = xmpp_stanza_new(stanza->ctx);
|
||||||
if (!copy) goto copy_error;
|
if (!copy) goto copy_error;
|
||||||
@@ -1060,12 +1062,14 @@ xmpp_stanza_t *xmpp_stanza_reply(xmpp_stanza_t * const stanza)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (stanza->attributes) {
|
if (stanza->attributes) {
|
||||||
if (_stanza_copy_attributes(copy, stanza) == -1)
|
if (_stanza_copy_attributes(copy, stanza) < 0)
|
||||||
goto copy_error;
|
goto copy_error;
|
||||||
}
|
}
|
||||||
|
|
||||||
xmpp_stanza_set_to(copy, xmpp_stanza_get_from(stanza));
|
xmpp_stanza_del_attribute(copy, "to");
|
||||||
xmpp_stanza_del_attribute(copy, "from");
|
xmpp_stanza_del_attribute(copy, "from");
|
||||||
|
rc = xmpp_stanza_set_to(copy, from);
|
||||||
|
if (rc != XMPP_EOK) goto copy_error;
|
||||||
|
|
||||||
return copy;
|
return copy;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user