vector: multiple evaluation of elem in AST_VECTOR_ADD_SORTED.
authorCorey Farrell <git@cfware.com>
Thu, 5 Oct 2017 22:59:06 +0000 (18:59 -0400)
committerCorey Farrell <git@cfware.com>
Fri, 6 Oct 2017 18:38:58 +0000 (14:38 -0400)
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
tests/test_vector.c

index 2de84d2..1e6fe03 100644 (file)
@@ -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; \
index 8e0d121..2dfcc60 100644 (file)
@@ -210,7 +210,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);