From 9da3489d247775fb06bee40fe4cf26640681fb93 Mon Sep 17 00:00:00 2001 From: Badalyan Vyacheslav Date: Mon, 10 Oct 2016 11:59:38 -0400 Subject: res_pjsip_config_wizard: Memory leak in module_unload Fixed a memory leak. It removes only the first element. Added a useful feature in vector.h to remove all items under the CMP through a callback function / macro. ASTERISK-26453 #close Change-Id: I84508353463456d2495678f125738e20052da950 --- include/asterisk/vector.h | 48 +++++++++++++++++++++++++++++++++++++++++++ res/res_pjsip_config_wizard.c | 4 ++-- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h index 0a13c560b..ef6104d57 100644 --- a/include/asterisk/vector.h +++ b/include/asterisk/vector.h @@ -353,6 +353,30 @@ #define AST_VECTOR_REMOVE_ORDERED(vec, idx) \ AST_VECTOR_REMOVE(vec, idx, 1) +/*! + * \brief Remove all elements from a vector that matches the given comparison + * + * \param vec Vector to remove from. + * \param value Value to pass into comparator. + * \param cmp Comparator function/macros (called as \c cmp(elem, value)) + * \param cleanup How to cleanup a removed element macro/function. + * + * \return the number of deleted elements. + */ +#define AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(vec, value, cmp, cleanup) ({ \ + int count = 0; \ + size_t idx; \ + typeof(value) __value = (value); \ + for (idx = 0; idx < (vec)->current; ++idx) { \ + if (cmp((vec)->elems[idx], __value)) { \ + cleanup((vec)->elems[idx]); \ + AST_VECTOR_REMOVE_UNORDERED((vec), idx); \ + ++count; \ + } \ + } \ + count; \ +}) + /*! * \brief Remove an element from a vector that matches the given comparison * @@ -379,6 +403,30 @@ res; \ }) +/*! + * \brief Remove all elements from a vector that matches the given comparison while maintaining order + * + * \param vec Vector to remove from. + * \param value Value to pass into comparator. + * \param cmp Comparator function/macros (called as \c cmp(elem, value)) + * \param cleanup How to cleanup a removed element macro/function. + * + * \return the number of deleted elements. + */ +#define AST_VECTOR_REMOVE_ALL_CMP_ORDERED(vec, value, cmp, cleanup) ({ \ + int count = 0; \ + size_t idx; \ + typeof(value) __value = (value); \ + for (idx = 0; idx < (vec)->current; ++idx) { \ + if (cmp((vec)->elems[idx], __value)) { \ + cleanup((vec)->elems[idx]); \ + AST_VECTOR_REMOVE_ORDERED((vec), idx); \ + ++count; \ + } \ + } \ + oount; \ +}) + /*! * \brief Remove an element from a vector that matches the given comparison while maintaining order * diff --git a/res/res_pjsip_config_wizard.c b/res/res_pjsip_config_wizard.c index e263437d7..1967d87ab 100644 --- a/res/res_pjsip_config_wizard.c +++ b/res/res_pjsip_config_wizard.c @@ -989,7 +989,7 @@ static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object rc = handle_registrations(sorcery, otw, wiz, &remote_hosts_vector); } - AST_VECTOR_REMOVE_CMP_UNORDERED(&remote_hosts_vector, NULL, NOT_EQUALS, ast_free); + AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(&remote_hosts_vector, NULL, NOT_EQUALS, ast_free); AST_VECTOR_FREE(&remote_hosts_vector); ast_debug(4, "%s handler complete. rc: %d\n", otw->object_type, rc); @@ -1293,7 +1293,7 @@ static int unload_module(void) { ast_cli_unregister_multiple(config_wizard_cli, ARRAY_LEN(config_wizard_cli)); ast_sorcery_global_observer_remove(&global_observer); - AST_VECTOR_REMOVE_CMP_UNORDERED(&object_type_wizards, NULL, NOT_EQUALS, OTW_DELETE_CB); + AST_VECTOR_REMOVE_ALL_CMP_UNORDERED(&object_type_wizards, NULL, NOT_EQUALS, OTW_DELETE_CB); AST_VECTOR_RW_FREE(&object_type_wizards); return 0; -- cgit v1.2.3