diff --git a/0001-Fix-a-crash-in-ptrie-if-you-iterate-over-the-map-in-.patch b/0001-Fix-a-crash-in-ptrie-if-you-iterate-over-the-map-in-.patch new file mode 100644 index 0000000..43f4a8a --- /dev/null +++ b/0001-Fix-a-crash-in-ptrie-if-you-iterate-over-the-map-in-.patch @@ -0,0 +1,129 @@ +From bcba4a298372735787b8f1da58a5d397e6e4e21e Mon Sep 17 00:00:00 2001 +From: Angus Salkeld +Date: Wed, 12 Sep 2012 10:39:17 +1000 +Subject: [PATCH] Fix a crash in ptrie if you iterate over the map in the + deleted notifier. + +Signed-off-by: Angus Salkeld +--- + lib/trie.c | 17 ++++++++++++++--- + tests/check_map.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 61 insertions(+), 3 deletions(-) + +diff --git a/lib/trie.c b/lib/trie.c +index 7a05c68..4dda823 100644 +--- a/lib/trie.c ++++ b/lib/trie.c +@@ -66,6 +66,17 @@ static struct trie_node *trie_new_node(struct trie *t, struct trie_node *parent) + #define TRIE_CHAR2INDEX(ch) (126 - ch) + #define TRIE_INDEX2CHAR(idx) (126 - idx) + ++ ++static int32_t ++trie_node_alive(struct trie_node *node) ++{ ++ if (node->value == NULL || ++ node->refcount <= 0) { ++ return QB_FALSE; ++ } ++ return QB_TRUE; ++} ++ + static struct trie_node * + trie_node_next(struct trie_node *node, struct trie_node *root, int all) + { +@@ -86,7 +97,7 @@ keep_going: + } + } + if (n) { +- if (all || n->value) { ++ if (all || trie_node_alive(n)) { + return n; + } else { + c = n; +@@ -112,7 +123,7 @@ keep_going: + } while (n == NULL && p != root); + + if (n) { +- if (all || n->value) { ++ if (all || trie_node_alive(n)) { + return n; + } + if (n == root) { +@@ -421,7 +432,7 @@ trie_node_ref(struct trie *t, struct trie_node *node) + static void + trie_node_deref(struct trie *t, struct trie_node *node) + { +- if (node->value == NULL) { ++ if (!trie_node_alive(node)) { + return; + } + node->refcount--; +diff --git a/tests/check_map.c b/tests/check_map.c +index df3008f..0f064ac 100644 +--- a/tests/check_map.c ++++ b/tests/check_map.c +@@ -45,6 +45,51 @@ static void *notified_new_value = NULL; + static void *notified_user_data = NULL; + static int32_t notified_event = 0; + static int32_t notified_event_prev = 0; ++static int32_t notified_events = 0; ++ ++static void ++my_map_notification_iter(uint32_t event, ++ char* key, void* old_value, ++ void* value, void* user_data) ++{ ++ const char *p; ++ void *data; ++ qb_map_t *m = (qb_map_t *)user_data; ++ qb_map_iter_t *it = qb_map_iter_create(m); ++ ++ notified_events++; ++ ++ for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) { ++ printf("%s > %s\n", p, (char*) data); ++ } ++ qb_map_iter_free(it); ++} ++ ++/* ++ * create some entries ++ * add a notifier ++ * delete an entry ++ * in the notifier iterate over the map. ++ */ ++static void ++test_map_notifications_iter(qb_map_t *m) ++{ ++ int i; ++ ++ qb_map_put(m, "k1", "one"); ++ qb_map_put(m, "k12", "two"); ++ qb_map_put(m, "k34", "three"); ++ ck_assert_int_eq(qb_map_count_get(m), 3); ++ ++ notified_events = 0; ++ i = qb_map_notify_add(m, NULL, my_map_notification_iter, ++ (QB_MAP_NOTIFY_DELETED | ++ QB_MAP_NOTIFY_RECURSIVE), m); ++ ck_assert_int_eq(i, 0); ++ qb_map_rm(m, "k12"); ++ ck_assert_int_eq(notified_events, 1); ++ ck_assert_int_eq(qb_map_count_get(m), 2); ++} + + static void + test_map_simple(qb_map_t *m, const char *name) +@@ -729,6 +774,8 @@ START_TEST(test_trie_notifications) + test_map_notifications_prefix(m); + m = qb_trie_create(); + test_map_notifications_free(m); ++ m = qb_trie_create(); ++ test_map_notifications_iter(m); + } + END_TEST + +-- +1.7.11.4 + diff --git a/libqb.spec b/libqb.spec index 33086f0..c767e6e 100644 --- a/libqb.spec +++ b/libqb.spec @@ -1,6 +1,6 @@ Name: libqb Version: 0.14.2 -Release: 1%{?dist} +Release: 2%{?dist} Summary: An IPC library for high performance servers Group: System Environment/Libraries @@ -9,6 +9,8 @@ URL: http://www.libqb.org Source0: https://fedorahosted.org/releases/q/u/quarterback/%{name}-%{version}.tar.xz BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) +Patch1: 0001-Fix-a-crash-in-ptrie-if-you-iterate-over-the-map-in-.patch + BuildRequires: libtool doxygen procps check-devel automake #Requires: @@ -20,6 +22,8 @@ Initially these are IPC and poll. %prep %setup -q +%patch1 -p1 + # work-around for broken epoll in rawhide/f17 %build ./autogen.sh @@ -68,6 +72,9 @@ developing applications that use %{name}. %changelog +* Wed Sep 12 2012 Angus Salkeld - 0.14.2-2 +Fix a crash in ptrie if you iterate over the map in the deleted notifier. + * Mon Sep 10 2012 Angus Salkeld - 0.14.2-1 Get libqb building on cygwin. ipc_us: slightly more robust cmsg handling