All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Johannes Schindelin via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Carlo Marcelo Arenas Belón" <carenas@gmail.com>,
	"Johannes Schindelin" <johannes.schindelin@gmx.de>,
	"Junio C Hamano" <gitster@pobox.com>
Subject: [PATCH v2 0/1] remote-curl: unbreak http.extraHeader with custom allocators
Date: Wed, 06 Nov 2019 10:04:54 +0000	[thread overview]
Message-ID: <pull.453.v2.git.1573034695.gitgitgadget@gmail.com> (raw)
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

  parent reply	other threads:[~2019-11-06 10:05 UTC|newest]

Thread overview: 17+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-05 21:59 [PATCH 0/1] remote-curl: unbreak http.extraHeader with custom allocators Johannes Schindelin via GitGitGadget
2019-11-05 21:59 ` [PATCH 1/1] " Johannes Schindelin via GitGitGadget
2019-11-06  4:16   ` Jeff King
2019-11-06  9:14     ` Johannes Schindelin
2019-11-06  9:49       ` Junio C Hamano
2019-11-06 19:38         ` Johannes Schindelin
2019-11-08  8:34           ` Junio C Hamano
2019-11-08 13:44             ` Johannes Schindelin
2019-11-06 10:04 ` Johannes Schindelin via GitGitGadget [this message]
2019-11-06 10:04   ` [PATCH v2 " Johannes Schindelin via GitGitGadget
2019-11-06 11:29     ` Jeff King
2019-11-06 12:12     ` Junio C Hamano
2019-11-06 19:34       ` Johannes Schindelin
2019-11-07  5:39         ` Junio C Hamano
2019-11-07 12:40           ` Johannes Schindelin
2019-11-08  3:03             ` Junio C Hamano
2019-11-06 12:15   ` [PATCH v2 0/1] " Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=pull.453.v2.git.1573034695.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=carenas@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johannes.schindelin@gmx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.