{"thread":{"id":"9859","subject":"[PATCH 1/5] Properly cleanup in http_cleanup so builtin-fetch does not segfault","startedAt":"2007-09-15T07:23:00Z","lastAt":"2007-09-15T07:23:00Z","messageCount":1,"participants":["Shawn O. Pearce"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"53095","messageId":"20070915072300.GA20346@spearce.org","threadId":"9859","inReplyTo":null,"subject":"[PATCH 1/5] Properly cleanup in http_cleanup so builtin-fetch does not segfault","fromName":"Shawn O. Pearce","fromEmail":"spearce@spearce.org","sentAt":"2007-09-15T07:23:00Z","receivedAt":"2007-09-15T07:23:00Z","isPatch":true,"sender":{"key":"spearce@spearce.org","avatar":"https://avatars.githubusercontent.com/u/34844?v=4"},"body":"Junio and I both noticed that the new builtin-fetch was segfaulting\nimmediately on http/https/ftp style URLs (those that went through\nlibcurl and the commit walker).  Although the builtin-fetch changes\nin this area were really just minor refactorings there was one major\nchange made: we invoked http_init(), http_cleanup() then http_init()\nagain in the same process.\n\nWhen we call curl_easy_cleanup() on each active_request_slot we\nare telling libcurl we did not want that buffer to be used again.\nUnfortunately we did not also deallocate the active_request_slot\nitself nor did we NULL out active_queue_head.  This lead us to\nattempt to reuse these cleaned up libcurl handles when we later tried\nto invoke http_init() a second time to reactivate the curl library.\nThe next file get operation then immediately segfaulted on most\nversions of libcurl.\n\nProperly freeing our own buffers and clearing the list causes us to\nreinitialize the curl buffers again if/when we need to use libcurl\nfrom within this same process.\n\nSigned-off-by: Shawn O. Pearce <spearce@spearce.org>\n---\n http.c |    7 +++++--\n 1 files changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/http.c b/http.c\nindex a95483b..87ebf7b 100644\n--- a/http.c\n+++ b/http.c\n@@ -276,6 +276,7 @@ void http_cleanup(void)\n #endif\n \n \twhile (slot != NULL) {\n+\t\tstruct active_request_slot *next = slot->next;\n #ifdef USE_CURL_MULTI\n \t\tif (slot->in_use) {\n \t\t\tcurl_easy_getinfo(slot->curl,\n@@ -287,8 +288,10 @@ void http_cleanup(void)\n #endif\n \t\tif (slot->curl != NULL)\n \t\t\tcurl_easy_cleanup(slot->curl);\n-\t\tslot = slot->next;\n+\t\tfree(slot);\n+\t\tslot = next;\n \t}\n+\tactive_queue_head = NULL;\n \n #ifndef NO_CURL_EASY_DUPHANDLE\n \tcurl_easy_cleanup(curl_default);\n@@ -300,7 +303,7 @@ void http_cleanup(void)\n \tcurl_global_cleanup();\n \n \tcurl_slist_free_all(pragma_header);\n-        pragma_header = NULL;\n+\tpragma_header = NULL;\n }\n \n struct active_request_slot *get_active_slot(void)\n-- \n1.5.3.1.84.gaf82-dirty\n"}]}