diff --git a/src/parser_expat.c b/src/parser_expat.c index e37460c..facd47b 100644 --- a/src/parser_expat.c +++ b/src/parser_expat.c @@ -295,12 +295,26 @@ char *parser_attr_name(xmpp_ctx_t *ctx, char *nsname) return _xml_name(ctx, nsname); } +static void _free_parent_stanza(xmpp_stanza_t *stanza) +{ + xmpp_stanza_t *parent; + + for (parent = stanza; parent->parent != NULL; parent = parent->parent) + ; + xmpp_stanza_release(parent); +} + /* free a parser */ void parser_free(parser_t *parser) { if (parser->expat) XML_ParserFree(parser->expat); + if (parser->stanza) { + _free_parent_stanza(parser->stanza); + parser->stanza = NULL; + } + if (parser->inner_text) { xmpp_free(parser->ctx, parser->inner_text); parser->inner_text = NULL; @@ -330,7 +344,7 @@ int parser_reset(parser_t *parser) } if (parser->stanza) { - xmpp_stanza_release(parser->stanza); + _free_parent_stanza(parser->stanza); parser->stanza = NULL; } diff --git a/src/parser_libxml2.c b/src/parser_libxml2.c index c0167d9..a2714c4 100644 --- a/src/parser_libxml2.c +++ b/src/parser_libxml2.c @@ -262,13 +262,22 @@ char *parser_attr_name(xmpp_ctx_t *ctx, char *nsname) return xmpp_strdup(ctx, nsname); } +static void _free_parent_stanza(xmpp_stanza_t *stanza) +{ + xmpp_stanza_t *parent; + + for (parent = stanza; parent->parent != NULL; parent = parent->parent) + ; + xmpp_stanza_release(parent); +} + /* free a parser */ void parser_free(parser_t *parser) { if (parser->xmlctx) xmlFreeParserCtxt(parser->xmlctx); if (parser->stanza) - xmpp_stanza_release(parser->stanza); + _free_parent_stanza(parser->stanza); xmpp_free(parser->ctx, parser); } @@ -278,7 +287,7 @@ int parser_reset(parser_t *parser) if (parser->xmlctx) xmlFreeParserCtxt(parser->xmlctx); if (parser->stanza) - xmpp_stanza_release(parser->stanza); + _free_parent_stanza(parser->stanza); parser->stanza = NULL; parser->depth = 0; diff --git a/tests/test_stanza.c b/tests/test_stanza.c index 0b28c5f..14cf8ab 100644 --- a/tests/test_stanza.c +++ b/tests/test_stanza.c @@ -110,6 +110,10 @@ static void test_stanza_from_string(xmpp_ctx_t *ctx) assert(strcmp(buf, str) == 0); xmpp_free(ctx, buf); xmpp_stanza_release(stanza); + + /* Error path. */ + stanza = xmpp_stanza_new_from_string(ctx, "tt"); + assert(stanza == NULL); } int main()