Fix a crash in ptrie if you iterate over the map in the deleted notifier.
Signed-off-by: Angus Salkeld <asalkeld@redhat.com>
This commit is contained in:
parent
84babc25cd
commit
3404b4c8f3
129
0001-Fix-a-crash-in-ptrie-if-you-iterate-over-the-map-in-.patch
Normal file
129
0001-Fix-a-crash-in-ptrie-if-you-iterate-over-the-map-in-.patch
Normal file
@ -0,0 +1,129 @@
|
||||
From bcba4a298372735787b8f1da58a5d397e6e4e21e Mon Sep 17 00:00:00 2001
|
||||
From: Angus Salkeld <asalkeld@redhat.com>
|
||||
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 <asalkeld@redhat.com>
|
||||
---
|
||||
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
|
||||
|
@ -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: <nothing>
|
||||
@ -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 <asalkeld@redhat.com> - 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 <asalkeld@redhat.com> - 0.14.2-1
|
||||
Get libqb building on cygwin.
|
||||
ipc_us: slightly more robust cmsg handling
|
||||
|
Loading…
Reference in New Issue
Block a user