summaryrefslogtreecommitdiffstats
path: root/swaybar
diff options
context:
space:
mode:
authorLibravatar Calvin Lee <cyrus296@gmail.com>2017-10-26 12:27:48 -0600
committerLibravatar Calvin Lee <cyrus296@gmail.com>2017-12-29 12:11:51 -0700
commit5bc46f458c1ac36aa17979af9583fc3060bac094 (patch)
tree53b78de1921813f0587cf90c0628501096efa7d9 /swaybar
parentAllow multiple object paths for each connection (diff)
downloadsway-5bc46f458c1ac36aa17979af9583fc3060bac094.tar.gz
sway-5bc46f458c1ac36aa17979af9583fc3060bac094.tar.zst
sway-5bc46f458c1ac36aa17979af9583fc3060bac094.zip
Prevent segfault in `get_items()`
One segfault resulted from an incorrect dbus call in sni_watcher. The other from duplicate items in the sni host.
Diffstat (limited to 'swaybar')
-rw-r--r--swaybar/tray/sni_watcher.c4
-rw-r--r--swaybar/tray/tray.c44
2 files changed, 30 insertions, 18 deletions
diff --git a/swaybar/tray/sni_watcher.c b/swaybar/tray/sni_watcher.c
index 4c53fb99..b89ac812 100644
--- a/swaybar/tray/sni_watcher.c
+++ b/swaybar/tray/sni_watcher.c
@@ -389,9 +389,9 @@ static void get_property(DBusConnection *connection, DBusMessage *message) {
389 DBUS_TYPE_STRUCT, NULL, &dstruct); 389 DBUS_TYPE_STRUCT, NULL, &dstruct);
390 390
391 dbus_message_iter_append_basic(&dstruct, 391 dbus_message_iter_append_basic(&dstruct,
392 DBUS_TYPE_OBJECT_PATH, item->obj_path); 392 DBUS_TYPE_OBJECT_PATH, &item->obj_path);
393 dbus_message_iter_append_basic(&dstruct, 393 dbus_message_iter_append_basic(&dstruct,
394 DBUS_TYPE_STRING, item->unique_name); 394 DBUS_TYPE_STRING, &item->unique_name);
395 395
396 dbus_message_iter_close_container(&array, &dstruct); 396 dbus_message_iter_close_container(&array, &dstruct);
397 } 397 }
diff --git a/swaybar/tray/tray.c b/swaybar/tray/tray.c
index 5cc7e902..a95b29fd 100644
--- a/swaybar/tray/tray.c
+++ b/swaybar/tray/tray.c
@@ -75,11 +75,6 @@ static void get_items_reply(DBusPendingCall *pending, void *_data) {
75 goto bail; 75 goto bail;
76 } 76 }
77 77
78 // Clear list
79 list_foreach(tray->items, (void (*)(void *))sni_free);
80 list_free(tray->items);
81 tray->items = create_list();
82
83 // O(n) function, could be faster dynamically reading values 78 // O(n) function, could be faster dynamically reading values
84 int len = dbus_message_iter_get_element_count(&variant); 79 int len = dbus_message_iter_get_element_count(&variant);
85 80
@@ -88,12 +83,14 @@ static void get_items_reply(DBusPendingCall *pending, void *_data) {
88 const char *name; 83 const char *name;
89 dbus_message_iter_get_basic(&array, &name); 84 dbus_message_iter_get_basic(&array, &name);
90 85
91 struct StatusNotifierItem *item = sni_create(name); 86 if (list_seq_find(tray->items, sni_str_cmp, name) == -1) {
87 struct StatusNotifierItem *item = sni_create(name);
92 88
93 if (item) { 89 if (item) {
94 sway_log(L_DEBUG, "Item registered with host: %s", name); 90 sway_log(L_DEBUG, "Item registered with host: %s", name);
95 list_add(tray->items, item); 91 list_add(tray->items, item);
96 dirty = true; 92 dirty = true;
93 }
97 } 94 }
98 } 95 }
99 96
@@ -149,15 +146,22 @@ static void get_obj_items_reply(DBusPendingCall *pending, void *_data) {
149 dbus_message_iter_recurse(&array, &dstruct); 146 dbus_message_iter_recurse(&array, &dstruct);
150 147
151 dbus_message_iter_get_basic(&dstruct, &object_path); 148 dbus_message_iter_get_basic(&dstruct, &object_path);
149 dbus_message_iter_next(&dstruct);
152 dbus_message_iter_get_basic(&dstruct, &unique_name); 150 dbus_message_iter_get_basic(&dstruct, &unique_name);
153 151
154 struct StatusNotifierItem *item = 152 struct ObjName obj_name = {
155 sni_create_from_obj_path(unique_name, object_path); 153 object_path,
154 unique_name,
155 };
156 if (list_seq_find(tray->items, sni_obj_name_cmp, &obj_name) == -1) {
157 struct StatusNotifierItem *item =
158 sni_create_from_obj_path(unique_name, object_path);
156 159
157 if (item) { 160 if (item) {
158 sway_log(L_DEBUG, "Item registered with host: %s", unique_name); 161 sway_log(L_DEBUG, "Item registered with host: %s", unique_name);
159 list_add(tray->items, item); 162 list_add(tray->items, item);
160 dirty = true; 163 dirty = true;
164 }
161 } 165 }
162 } 166 }
163 167
@@ -167,6 +171,11 @@ bail:
167} 171}
168 172
169static void get_items() { 173static void get_items() {
174 // Clear list
175 list_foreach(tray->items, (void (*)(void *))sni_free);
176 list_free(tray->items);
177 tray->items = create_list();
178
170 DBusPendingCall *pending; 179 DBusPendingCall *pending;
171 DBusMessage *message = dbus_message_new_method_call( 180 DBusMessage *message = dbus_message_new_method_call(
172 "org.freedesktop.StatusNotifierWatcher", 181 "org.freedesktop.StatusNotifierWatcher",
@@ -352,6 +361,9 @@ static int init_host() {
352 361
353 register_host(name); 362 register_host(name);
354 363
364 // Chances are if an item is already running, we'll get it two times.
365 // Once from this and another time from queued signals. Still we want
366 // to do this to be a complient sni host just in case.
355 get_items(); 367 get_items();
356 368
357 // Perhaps use addmatch helper functions like wlc does? 369 // Perhaps use addmatch helper functions like wlc does?