git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 0/1] remote-curl: unbreak http.extraHeader with custom allocators

From
Johannes Schindelin via GitGitGadget <gitgitgadget@gmail.com>
Date
Nov 6, 2019, 10:04 UTC
Message-ID
<pull.453.v2.git.1573034695.gitgitgadget@gmail.com>
In-Reply-To
<pull.453.git.1572991158.gitgitgadget@gmail.com>
This is one of those bugs that can cost entire days of work.

The symptom of this bug is that git -c http.extraheader push ... will fail frequently in Git for Windows v2.24.0, but not always. When it fails, though, it will cause a segmentation fault in git remote-https while calling http_cleanup() and leave no visual indication of that problem, the only indication of a problem will be the exit code of the caller (in this instance, git push will fail with exit code 1).

In my tests during the pre-release period, I pushed many a time, it probably failed a lot, in the way indicated above, and due to the absence of any error message, I failed to realize that there was a problem in the first place.

Fun side note: this bug haunted me for the best part of this past Monday, when I tried to get Git for Windows v2.24.0 out the door. Large parts of Git for Windows' release management are scripted, and that script failed, claiming to have been unsuccessful in pushing the tag v2.24.0.windows.1, just after printing a message to the extent that the tag is already up to date (except in the first attempt, when it reported to have been successful in pushing the tag). My attempts to fix the release script were doomed to fail because the root cause was not a bug in the script, but the bug fixed in this patch.

Changes since v1:
 * The patch was completely redone: instead of moving the call to 
   curl_global_init() (which would have broken support for http.sslbackend),
   this iteration instead replaces the usage of cURL's slist in the config
   handling by using Git's own string_list.
Johannes Schindelin (1):
  remote-curl: unbreak http.extraHeader with custom allocators
 http.c | 18 ++++++++----------
 1 file changed, 8 insertions(+), 10 deletions(-)
base-commit: 93b980e58f5624ee4e3b2dc0d0babaa97ef66d19
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-453%2Fdscho%2Ffix-curl-xmalloc-regression-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-453/dscho/fix-curl-xmalloc-regression-v2
Pull-Request: https://github.com/gitgitgadget/git/pull/453
Range-diff vs v1:
 1:  d47a2aa594 ! 1:  3168ba2c9e remote-curl: unbreak http.extraHeader with custom allocators
     @@ -15,8 +15,18 @@
          presence of custom allocators, cURL would attempt to use the wrong
          allocator to release the memory.
      
     -    Let's fix this by moving the initialization _before_ the
     -    `http_options()` function is called.
     +    A naïve attempt at fixing this would move the call to
     +    `curl_global_init()` _before_ the config is parsed (i.e. before that
     +    call to `slist_append()`).
     +
     +    However, that does work, as we _also_ parse the config setting
     +    `http.sslbackend` and if found, call `curl_global_sslset()` which *must*
     +    be called before `curl_global_init()`, for details see:
     +    https://curl.haxx.se/libcurl/c/curl_global_sslset.html
     +
     +    So let's instead make the config parsing entirely independent from
     +    cURL's data structures. Incidentally, this deletes two more lines than
     +    it introduces, which is nice.
      
          Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
      
     @@ -24,22 +34,50 @@
       --- a/http.c
       +++ b/http.c
      @@
     - 	char *normalized_url;
     - 	struct urlmatch_config config = { STRING_LIST_INIT_DUP };
     - 
     -+	if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
     -+		die("curl_global_init failed");
     -+
     - 	config.section = "http";
     - 	config.key = NULL;
     - 	config.collect_fn = http_options;
     + 
     + static struct curl_slist *pragma_header;
     + static struct curl_slist *no_pragma_header;
     +-static struct curl_slist *extra_http_headers;
     ++static struct string_list extra_http_headers = STRING_LIST_INIT_DUP;
     + 
     + static struct active_request_slot *active_queue_head;
     + 
      @@
     + 		if (!value) {
     + 			return config_error_nonbool(var);
     + 		} else if (!*value) {
     +-			curl_slist_free_all(extra_http_headers);
     +-			extra_http_headers = NULL;
     ++			string_list_clear(&extra_http_headers, 0);
     + 		} else {
     +-			extra_http_headers =
     +-				curl_slist_append(extra_http_headers, value);
     ++			string_list_append(&extra_http_headers, value);
     + 		}
     + 		return 0;
       	}
     +@@
       #endif
     + 	curl_global_cleanup();
     + 
     +-	curl_slist_free_all(extra_http_headers);
     +-	extra_http_headers = NULL;
     ++	string_list_clear(&extra_http_headers, 0);
     + 
     + 	curl_slist_free_all(pragma_header);
     + 	pragma_header = NULL;
     +@@
     + 
     + struct curl_slist *http_copy_default_headers(void)
     + {
     +-	struct curl_slist *headers = NULL, *h;
     ++	struct curl_slist *headers = NULL;
     ++	const struct string_list_item *item;
       
     --	if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK)
     --		die("curl_global_init failed");
     --
     - 	http_proactive_auth = proactive_auth;
     +-	for (h = extra_http_headers; h; h = h->next)
     +-		headers = curl_slist_append(headers, h->data);
     ++	for_each_string_list_item(item, &extra_http_headers)
     ++		headers = curl_slist_append(headers, item->string);
       
     - 	if (remote && remote->http_proxy)
     + 	return headers;
     + }
-- 
gitgitgadget
Previous: Johannes SchindelinNext: Johannes Schindelin via GitGitGadget
Message 9 of 17 in “remote-curl: unbreak http.extraHeader with custom allocators”
  1. 0/1 remote-curl: unbreak http.extraHeader with custom allocatorsJohannes Schindelin via GitGitGadget, Nov 5, 2019
  2. 1/1 remote-curl: unbreak http.extraHeader with custom allocatorsJohannes Schindelin via GitGitGadget, Nov 5, 2019
  3. Jeff KingNov 6, 2019
  4. Johannes SchindelinNov 6, 2019
  5. Junio C HamanoNov 6, 2019
  6. Johannes SchindelinNov 6, 2019
  7. Junio C HamanoNov 8, 2019
  8. Johannes SchindelinNov 8, 2019
  9. 0/1 remote-curl: unbreak http.extraHeader with custom allocatorsJohannes Schindelin via GitGitGadget, Nov 6, 2019
  10. 1/1 remote-curl: unbreak http.extraHeader with custom allocatorsJohannes Schindelin via GitGitGadget, Nov 6, 2019
  11. Jeff KingNov 6, 2019
  12. Junio C HamanoNov 6, 2019
  13. Johannes SchindelinNov 6, 2019
  14. Junio C HamanoNov 7, 2019
  15. Johannes SchindelinNov 7, 2019
  16. Junio C HamanoNov 8, 2019
  17. Junio C HamanoNov 6, 2019

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.