From 224cac449a246bd7432fd5fb4e15f942547185d3 Mon Sep 17 00:00:00 2001 Message-Id: <224cac449a246bd7432fd5fb4e15f942547185d3.1715657508.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sat, 9 Jan 2016 01:37:36 +0000 Subject: [PATCH 1/1] disobedience/choose-search.c: Fix segfault when search terms change. Organization: Straylight/Edgeware From: Mark Wooding The observed problem: Sometimes, when typing search terms into the box, DisObedience crashes. This seems to happen more often when the server is slow to respond. Here's what's going on. Suppose that a search finds some results. Then `choose_make_visible' tries to expand the tree to display them. If some of the results aren't populated in the tree yet, then `choose_make_one_visible' arranges to fetch the necessary information from the server and informs its caller, `choose_make_visible', that it'll have to try again later. When this happens, `choose_make_visible' hooks itself onto the `choose-more-tracks' event and waits for the information to arrive. Suppose that, while this is happening, the user edits the search terms; a new search starts, but this one returns no results. Then `choose_search_completed' zaps the `choose_search_results' vector and returns. Now the metadata from the old search arrives from the server; `choose_make_visible' is called back. There are now no search results, so it thinks its work is done and tries to scroll the list widget so that the first result is visible -- but the result vector has been clobbered. Result: misery. To fix this, cancel the `choose-more-tracks' event handler when a new search finishes. Now we can't get into this situation any more. --- disobedience/choose-search.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/disobedience/choose-search.c b/disobedience/choose-search.c index 60df2ec..83d3f74 100644 --- a/disobedience/choose-search.c +++ b/disobedience/choose-search.c @@ -289,6 +289,11 @@ static void choose_search_completed(void attribute((unused)) *v, * left over from the old search. */ choose_auto_collapse(); choose_search_hash = hash_new(1); + /* If we were still setting up the chooser to show previous search results + * then turn that off now. We'll turn it back on again if necessary. */ + event_cancel(choose_inserted_handle); + choose_inserted_handle = 0; + /* Start showing the results of our search. */ if(nvec) { for(int n = 0; n < nvec; ++n) hash_add(choose_search_hash, vec[n], "", HASH_INSERT); -- [mdw]