From e71f6d4dfa7ed4df7d5a47f3eca8a4f896f0cfce Mon Sep 17 00:00:00 2001 From: Corey Farrell Date: Thu, 5 Oct 2017 18:59:06 -0400 Subject: vector: multiple evaluation of elem in AST_VECTOR_ADD_SORTED. Use temporary variable to prevent multiple evaluations of elem argument. This resolves a memory leak in res_pjproject startup. ASTERISK-27317 #close Change-Id: Ib960d7f5576f9e1a3c478ecb48995582a574e06d --- include/asterisk/vector.h | 10 +++++++--- tests/test_vector.c | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/include/asterisk/vector.h b/include/asterisk/vector.h index 2de84d295..1e6fe038c 100644 --- a/include/asterisk/vector.h +++ b/include/asterisk/vector.h @@ -304,27 +304,31 @@ AST_VECTOR(ast_vector_int, int); * \brief Add an element into a sorted vector * * \param vec Sorted vector to add to. - * \param elem Element to insert. + * \param elem Element to insert. Must not be an array type. * \param cmp A strcmp compatible compare function. * * \return 0 on success. * \return Non-zero on failure. * * \warning Use of this macro on an unsorted vector will produce unpredictable results + * \warning 'elem' must not be an array type so passing 'x' where 'x' is defined as + * 'char x[4]' will fail to compile. However casting 'x' as 'char *' does + * result in a value that CAN be used. */ #define AST_VECTOR_ADD_SORTED(vec, elem, cmp) ({ \ int res = 0; \ size_t __idx = (vec)->current; \ + typeof(elem) __elem = (elem); \ do { \ if (__make_room((vec)->current, vec) != 0) { \ res = -1; \ break; \ } \ - while (__idx > 0 && (cmp((vec)->elems[__idx - 1], elem) > 0)) { \ + while (__idx > 0 && (cmp((vec)->elems[__idx - 1], __elem) > 0)) { \ (vec)->elems[__idx] = (vec)->elems[__idx - 1]; \ __idx--; \ } \ - (vec)->elems[__idx] = elem; \ + (vec)->elems[__idx] = __elem; \ (vec)->current++; \ } while (0); \ res; \ diff --git a/tests/test_vector.c b/tests/test_vector.c index 03d092fef..1707ef7dd 100644 --- a/tests/test_vector.c +++ b/tests/test_vector.c @@ -212,7 +212,7 @@ AST_TEST_DEFINE(basic_ops) ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, ZZZ, strcmp) == 0, rc, cleanup); ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, CCC, strcmp) == 0, rc, cleanup); ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, AAA, strcmp) == 0, rc, cleanup); - ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, CCC2, strcmp) == 0, rc, cleanup); + ast_test_validate_cleanup(test, AST_VECTOR_ADD_SORTED(&sv1, (char*)CCC2, strcmp) == 0, rc, cleanup); ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 0) == AAA, rc, cleanup); ast_test_validate_cleanup(test, AST_VECTOR_GET(&sv1, 1) == BBB, rc, cleanup); -- cgit v1.2.3