From patchwork Mon May 27 11:45:47 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675086 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C764D152DF2 for ; Mon, 27 May 2024 11:45:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810354; cv=none; b=bNUMcPlLmVCVYBavnMUchiTFtr5Y/Krplpraa6loBbT9sb5M5Z1yr+kTTa27iLs4iyRKrwr9HGSABEzL6r+vUGpvNZ60fk0jJhmrHMZIyjQfQBHv5FT+7Y2mtozTELKcVIhR9Wm+b2CMyvvcCyxKWatBbunrs32cAko7l5h+eUk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810354; c=relaxed/simple; bh=NNVgIlaTST+UkIXQH0002/VI4UYuLq9kSHdTlcUx3NY=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=E0rrRyYBiOpPwj1ydt6v782NwZC+4M24T94M8E0RVxJCbM5LSmecM1vT+Dwy7qRKz5+HZ9S2bcFJGaYws+GYzd176sJ5WIqDPjm8ybXFGAiuTFkh3/rU7mW/pquOsOma40wCutX0e85T/5gv6He9/CPu6jwZj5kD0CWtQ5T6f6M= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=ZZS8F+WL; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=VRqVDjPX; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ZZS8F+WL"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="VRqVDjPX" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailfhigh.west.internal (Postfix) with ESMTP id 9483D18000F6; Mon, 27 May 2024 07:45:51 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 27 May 2024 07:45:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810351; x=1716896751; bh=ZuvaJ3U/gN BRlJZnLvJoFFhifyWy73rkfSO4FRfJBGo=; b=ZZS8F+WL33xtCacRos9XHC6uEU F5hX+OKa6Q5YHIN/bmXqhyxFfA5FdCcbivf4fdsnFdcCPko4NuIzP9zVpEG/B5BT EyynD99UOayqkteoPNkyBpI3LCCngmywn5RnSHXc/49Pgd+3C4yJ9Krp6mOpkCzV +bCMy5QpWfykaO8MpSVA1viqxjZZUle6frZOprOPdaUDvxVXFe+qxNYdWv5t0Du1 TbUj3ZBpqxiB9TK8/POr69G+AEyAW49tZSvmk7B0lgG5TegpSadsgmrzQTkPP0gk 2xsMjB/X4w+uSfGknimDXIWc6bWol8mmqVFBpdt+pdVAMdEef+dDL90RYhnQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810351; x=1716896751; bh=ZuvaJ3U/gNBRlJZnLvJoFFhifyWy 73rkfSO4FRfJBGo=; b=VRqVDjPXl6yldbYm7Hr3k5brJlx0UmH/6i053v/bR4zs +5tLuXh5ZMG4ry+pO84V3PjmQzkxYUcuu6I549zU77e48z9eeg7nK1I22zdmSIK1 oAXs6iifHBnxYIIiNJ+bIq/ECaY+ewYVvWbQ9HF89REFUWPm260vQBpgncTdOOMc zSXv3wp2gNJc9g0PUtkGhe4at6IpjmoybUp+Di0u7aS1pRHr8qrsRYL3+cueYpaF 7pJFwXRpOkNUQKZLJIylQZGXW/N1iu1us7muftQ+sNLIabmhOB3N+E8x6LZmRJPU uVQ0DkaHfycjiXwxjANkiNheQTSGpga4XMtavryoxg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:45:49 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 53ebab43 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:45:39 +0000 (UTC) Date: Mon, 27 May 2024 13:45:47 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 01/21] ci: add missing dependency for TTY prereq Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: In "t/lib-terminal.sh", we declare a lazy prerequisite for tests that require a TTY. The prerequisite uses a Perl script to figure out whether we do have a usable TTY or not and thus implicitly depends on the PERL prerequisite, as well. Furthermore though, the script requires another dependency that is easy to miss, namely on the IO::Pty module. If that module is not installed, then the script will exit early due to an reason unrelated to missing TTYs. This easily leads to missing test coverage. But most importantly, our CI systems are missing this dependency and thus don't execute those tests at all. Fix this. Signed-off-by: Patrick Steinhardt --- ci/install-dependencies.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ci/install-dependencies.sh b/ci/install-dependencies.sh index 2e7688ae8b..6ec0f85972 100755 --- a/ci/install-dependencies.sh +++ b/ci/install-dependencies.sh @@ -27,7 +27,7 @@ alpine-*) apk add --update shadow sudo build-base curl-dev openssl-dev expat-dev gettext \ pcre2-dev python3 musl-libintl perl-utils ncurses \ apache2 apache2-http2 apache2-proxy apache2-ssl apache2-webdav apr-util-dbd_sqlite3 \ - bash cvs gnupg perl-cgi perl-dbd-sqlite >/dev/null + bash cvs gnupg perl-cgi perl-dbd-sqlite perl-io-tty >/dev/null ;; fedora-*) dnf -yq update >/dev/null && @@ -42,7 +42,7 @@ ubuntu-*) language-pack-is libsvn-perl apache2 cvs cvsps git gnupg subversion \ make libssl-dev libcurl4-openssl-dev libexpat-dev wget sudo default-jre \ tcl tk gettext zlib1g-dev perl-modules liberror-perl libauthen-sasl-perl \ - libemail-valid-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \ + libemail-valid-perl libio-pty-perl libio-socket-ssl-perl libnet-smtp-ssl-perl libdbd-sqlite3-perl libcgi-pm-perl \ ${CC_PACKAGE:-${CC:-gcc}} $PYTHON_PACKAGE mkdir --parents "$CUSTOM_PATH" From patchwork Mon May 27 11:45:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675087 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EDA90152DF2 for ; Mon, 27 May 2024 11:45:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810359; cv=none; b=FPeoXnhmxkxyoZHH7/EckwIT2fqNWLyq8ivGxyI0Pe1nhyJaRsTRej/6+wsG2dTBS6G8N2n4P3y+wxO5pGa74LcoyR0hPu1hg2y39snDYX1wTVl1SARbsiZge5htCgSkwfSlROyXcqCHHVD/pk2GdOLOGP/rtrclGkZZTkcUBKw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810359; c=relaxed/simple; bh=G9D0nLm+fc1jJd8rIiTXVfwu6coZ8k23wF1cdh4VT44=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=huV3jZ26xm0wpNntG0pmqnBkPMTGyAXgjwVyH+8n4HADZh5Nli+xtvbBOKpllhTNhXCSJuxWGnX5aJAoLO1w1CpGSmt8keS72hda6zs+fVcwl69FH6lnkYuz+PRWvAIVaJocZOM4zbn8oAnNDDZWeQbnf53oZuN5jDPWZNb3CIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=ANgNbraG; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=A+6J1aVs; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ANgNbraG"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="A+6J1aVs" Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailfout.west.internal (Postfix) with ESMTP id 09D201C000CD; Mon, 27 May 2024 07:45:55 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Mon, 27 May 2024 07:45:56 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810355; x=1716896755; bh=voUQ1pVznG D/RdgjR9VksNdZUXKuJSZCCpe70gSwTdc=; b=ANgNbraGnv1HjV6wgxUGFfqkf/ 4uAwNutjM05dkbqHWRd4OOX8OP0vJ5QPi/UBA0vttEsVA6v70mOwjIxBWjOYnHQP 4rgL1EMabkHltNTP+hW+uRjJtisexBc0JAR5zG24xGi70tV/FQXin5iZA0sUR75H 3szV2vgiVW6GtKmDf9vxOhzyJH1B7rMAVqThxyxlsGvaT/IPwKWCooWweAGWCgua djFgSrkX6swukPvZ/lzbev9Xr6dJRSbNSTkffkgVWcU1sAjv/qMkCDIC8nMmraws TCsz/7IUvsQLG/WbEmum6zlxKIp1ZXzZeWq8pxcWz0LeRmznhRg2L+v+SyDQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810355; x=1716896755; bh=voUQ1pVznGD/RdgjR9VksNdZUXKu JSZCCpe70gSwTdc=; b=A+6J1aVsOXew2rKvsRcGTgDGayJe4hQVyAKq5/hfjehs Xl9n9ZGLCJ4rqrVqbTbySb9mnP2FFpWINhENaJNr+3x0anYqxUU4w/nTN+Z0iekU v+4zjq37UIespt7CzljwSE2uRfHLhPYDtXawqBXqGf3qqOmPNVQmA3esBY5yvIJG hHeiURUlxtegdmdyl0lu6kVCpTqYXQWg3gC3xOe6BjTz9CHzwNNdPbZDBXI+TC8d uwsG+QG1CXsOWqmaV9FrMRy6TetdeXoHuCW42uHG+BrtstndkxO4mwvJGvs49uqH DTAza1uhgPISBN0iaOiKEkdknLKjNTL2ilkUevQh0w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggedvucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepfeehieduieeigfffheeggfegiedtudfgkeeutdetheeuudevffeggfelgedtveel necuffhomhgrihhnpeegtddrihhtnecuvehluhhsthgvrhfuihiivgeptdenucfrrghrrg hmpehmrghilhhfrhhomhepphhssehpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:45:54 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 4b408a09 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:45:44 +0000 (UTC) Date: Mon, 27 May 2024 13:45:52 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 02/21] t: mark a bunch of tests as leak-free Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: There are a bunch of tests which do not have any leaks: - t0411: Introduced via 5c5a4a1c05 (t0411: add tests for cloning from partial repo, 2024-01-28), passes since its inception. - t0610: Introduced via 57db2a094d (refs: introduce reftable backend, 2024-02-07), passes since its inception. - t2405: Passes since 6741e917de (repository: avoid leaking `fsmonitor` data, 2024-04-12). - t7423: Introduced via b20c10fd9b (t7423: add tests for symlinked submodule directories, 2024-01-28), passes since e8d0608944 (submodule: require the submodule path to contain directories only, 2024-03-26). The fix is not obviously related, but probably works because we now die early in many code paths. - t9xxx: All of these are exercising CVS-related tooling and pass since at least Git v2.40. It's likely that these pass for a long time already, but nobody ever noticed because Git developers do not tend to have CVS on their machines. Mark all of these tests as passing. Signed-off-by: Patrick Steinhardt --- t/t0411-clone-from-partial.sh | 1 + t/t0610-reftable-basics.sh | 1 + t/t2405-worktree-submodule.sh | 1 + t/t7423-submodule-symlinks.sh | 1 + t/t9200-git-cvsexportcommit.sh | 1 + t/t9401-git-cvsserver-crlf.sh | 1 + t/t9600-cvsimport.sh | 1 + t/t9601-cvsimport-vendor-branch.sh | 1 + t/t9602-cvsimport-branches-tags.sh | 1 + t/t9603-cvsimport-patchsets.sh | 2 ++ t/t9604-cvsimport-timestamps.sh | 2 ++ 11 files changed, 13 insertions(+) diff --git a/t/t0411-clone-from-partial.sh b/t/t0411-clone-from-partial.sh index c98d501869..932bf2067d 100755 --- a/t/t0411-clone-from-partial.sh +++ b/t/t0411-clone-from-partial.sh @@ -2,6 +2,7 @@ test_description='check that local clone does not fetch from promisor remotes' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create evil repo' ' diff --git a/t/t0610-reftable-basics.sh b/t/t0610-reftable-basics.sh index cc5bbfd732..b06c46999d 100755 --- a/t/t0610-reftable-basics.sh +++ b/t/t0610-reftable-basics.sh @@ -10,6 +10,7 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME GIT_TEST_DEFAULT_REF_FORMAT=reftable export GIT_TEST_DEFAULT_REF_FORMAT +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh INVALID_OID=$(test_oid 001) diff --git a/t/t2405-worktree-submodule.sh b/t/t2405-worktree-submodule.sh index 11018f37c7..1d7f605633 100755 --- a/t/t2405-worktree-submodule.sh +++ b/t/t2405-worktree-submodule.sh @@ -5,6 +5,7 @@ test_description='Combination of submodules and multiple worktrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh base_path=$(pwd -P) diff --git a/t/t7423-submodule-symlinks.sh b/t/t7423-submodule-symlinks.sh index 3d3c7af3ce..f45d806201 100755 --- a/t/t7423-submodule-symlinks.sh +++ b/t/t7423-submodule-symlinks.sh @@ -2,6 +2,7 @@ test_description='check that submodule operations do not follow symlinks' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare' ' diff --git a/t/t9200-git-cvsexportcommit.sh b/t/t9200-git-cvsexportcommit.sh index a44eabf0d8..3d4842164c 100755 --- a/t/t9200-git-cvsexportcommit.sh +++ b/t/t9200-git-cvsexportcommit.sh @@ -4,6 +4,7 @@ # test_description='Test export of commits to CVS' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if ! test_have_prereq PERL; then diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index a34805acdc..a67e6abd49 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -12,6 +12,7 @@ repository using cvs CLI client via git-cvsserver server' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh marked_as () { diff --git a/t/t9600-cvsimport.sh b/t/t9600-cvsimport.sh index 5680849218..41fcf3606b 100755 --- a/t/t9600-cvsimport.sh +++ b/t/t9600-cvsimport.sh @@ -4,6 +4,7 @@ test_description='git cvsimport basic tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh if ! test_have_prereq NOT_ROOT; then diff --git a/t/t9601-cvsimport-vendor-branch.sh b/t/t9601-cvsimport-vendor-branch.sh index 116cddba3a..e007669495 100755 --- a/t/t9601-cvsimport-vendor-branch.sh +++ b/t/t9601-cvsimport-vendor-branch.sh @@ -35,6 +35,7 @@ test_description='git cvsimport handling of vendor branches' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh setup_cvs_test_repository t9601 diff --git a/t/t9602-cvsimport-branches-tags.sh b/t/t9602-cvsimport-branches-tags.sh index e5266c9a87..3768e3bd8c 100755 --- a/t/t9602-cvsimport-branches-tags.sh +++ b/t/t9602-cvsimport-branches-tags.sh @@ -7,6 +7,7 @@ test_description='git cvsimport handling of branches and tags' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh setup_cvs_test_repository t9602 diff --git a/t/t9603-cvsimport-patchsets.sh b/t/t9603-cvsimport-patchsets.sh index 19f38f78f2..2a387fdbaa 100755 --- a/t/t9603-cvsimport-patchsets.sh +++ b/t/t9603-cvsimport-patchsets.sh @@ -12,6 +12,8 @@ # bug. test_description='git cvsimport testing for correct patchset estimation' + +TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh setup_cvs_test_repository t9603 diff --git a/t/t9604-cvsimport-timestamps.sh b/t/t9604-cvsimport-timestamps.sh index 2d03259729..9cf0685d56 100755 --- a/t/t9604-cvsimport-timestamps.sh +++ b/t/t9604-cvsimport-timestamps.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git cvsimport timestamps' + +TEST_PASSES_SANITIZE_LEAK=true . ./lib-cvs.sh test_lazy_prereq POSIX_TIMEZONE ' From patchwork Mon May 27 11:45:56 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675088 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 747E7152DF2 for ; Mon, 27 May 2024 11:46:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810364; cv=none; b=fjtl9PuI2O+azKvaKXU3LbtlZBTenguaXgvQkP/tMz4t/imIyPCkl+kG1sb0gkfo5rbiigXXnNJfXuM+b7ihLx2P1EDDgOS5CxKdUnYikzfer3/jHwlLaXR2MFRiyja4zT1WAKncxMWAS5uA7Y+x87tb3np6qtMT6q2AxZNFjN4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810364; c=relaxed/simple; bh=PmyQFv/TA1mIzP0GLz7tP7re9l2ZlyJ2J5sDFruJmV0=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=oHLNUHS44EbtLblSiqFrk4qQr5ZpC24e1Yf87aAmzWyf2KSB/5PMc3CUnfpsJucvcpTGmBFbM9+4Qy8CtVt7rAo4MWYmNWhOCDSYXRHFPWCboghdbSZMIU13yUibkY65S7EWkcziSVi+gOdhBEx2+bmyvNnjba/oOXRs0T4uQ/E= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=IyjqJ/Nv; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=h93VJq8A; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="IyjqJ/Nv"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="h93VJq8A" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailfout.west.internal (Postfix) with ESMTP id 5A61E1C000C8; Mon, 27 May 2024 07:46:00 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 27 May 2024 07:46:00 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810360; x=1716896760; bh=w6y/BuqqxK i+ulIjm2SveuxIS4ECvdUGD8zIqJqhU4w=; b=IyjqJ/Nv7OEjHhlsifwFWP2Y6M k+Ac8jEmWWiiq/+7gAZJHWxOnzZsFLL+104abZx0MUwFrAiEdiJMYsPRtU4N+v8d RlUdaRnjBNp625tRpyIL0Kq9REtM0ydXjaSoO3NJ5g5nBOMXZHk1Fx+A50CkPKyF D0QBNcUHan/i9lOPTiO4mREGQ8ifP7v9D4puVn5n6xfnSJxR9fz9NpbzvRZ1yMKn 3csVKpxGPmBLNXYHweU/zxNDEWlLzwn8ROVAT4Rp2dtjt3jdbor20IW+0xi9zTS5 9L5xFoFPB5tk7HsDJHCrH2YTIzoZXbkoesWU7lzoDLQcv4X1Onxek4SXHW9w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810360; x=1716896760; bh=w6y/BuqqxKi+ulIjm2SveuxIS4EC vdUGD8zIqJqhU4w=; b=h93VJq8Ah+e+fJRl9+5+CveA5X6YEBZ8acE+vzRzgzuu x6dEsg8qItukRTdKDWDWOMfmQnMRaRQqGuQkhfLBbhiwaMAgp4pBNU5VBB//+WNj SzypF8WFkd+nBQDyltlhs9gGaELU7jczyoHCl6C/CiUZJzL+cSbsd/GYVphxbhBw gKYHJuib8ZwLvNzQTeGRe5HSPneorDLE95cX0d5dS1HYym91WbXzJ4Vmb62cWdIk 76YeRJmpy+8gxaCwCY9XOfnwHMy0yw5sSJ22tq6PldTaTzeT4lFVoQ8ep1YpDko8 whd3jeGiEU3MoTjoLAXvGZWPRlkrVgehQmjTJEluyQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhephfekheevlefhteetheelveeujeejhedtueduvddutdehheefheetvdfhudeviedt necuffhomhgrihhnpehhthhtphgurdhshhdphhhtthhpqdgruhhthhdrshhhpdhhthhtph dqphhrohighidrshhhpdhhthhtphdqtghurhhlqdhvvghrsghoshgvrdhshhdpthgvshht qdhlihgsrdhshhenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgrihhlfh hrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:45:58 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id b1fdd625 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:45:48 +0000 (UTC) Date: Mon, 27 May 2024 13:45:56 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 03/21] transport-helper: fix leaking helper name Message-ID: <9e946c1a835bbdc23fbc6773b714eb2175ae33f8.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: When initializing the transport helper in `transport_get()`, we allocate the name of the helper. We neither end up transferring ownership of the name, nor do we free it. The associated memory thus leaks. Fix this memory leak by freeing the string at the calling side in `transport_get()`. `transport_helper_init()` now creates its own copy of the string and thus can free it as required. An alterantive way to fix this would be to transfer ownership of the string passed into `transport_helper_init()`, which would avoid the call to xstrdup(1). But it does make for a more surprising calling convention as we do not typically transfer ownership of strings like this. Mark now-passing tests as leak free. Signed-off-by: Patrick Steinhardt --- t/t0611-reftable-httpd.sh | 1 + t/t5563-simple-http-auth.sh | 1 + t/t5564-http-proxy.sh | 1 + t/t5581-http-curl-verbose.sh | 1 + transport-helper.c | 6 ++++-- transport.c | 1 + 6 files changed, 9 insertions(+), 2 deletions(-) diff --git a/t/t0611-reftable-httpd.sh b/t/t0611-reftable-httpd.sh index 5e05b9c1f2..2805995cc8 100755 --- a/t/t0611-reftable-httpd.sh +++ b/t/t0611-reftable-httpd.sh @@ -2,6 +2,7 @@ test_description='reftable HTTPD tests' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5563-simple-http-auth.sh b/t/t5563-simple-http-auth.sh index 5d5caa3f58..4af796de67 100755 --- a/t/t5563-simple-http-auth.sh +++ b/t/t5563-simple-http-auth.sh @@ -2,6 +2,7 @@ test_description='test http auth header and credential helper interop' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5564-http-proxy.sh b/t/t5564-http-proxy.sh index 9da5134614..bb35b87071 100755 --- a/t/t5564-http-proxy.sh +++ b/t/t5564-http-proxy.sh @@ -2,6 +2,7 @@ test_description="test fetching through http proxy" +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh diff --git a/t/t5581-http-curl-verbose.sh b/t/t5581-http-curl-verbose.sh index cded79c16b..724f610054 100755 --- a/t/t5581-http-curl-verbose.sh +++ b/t/t5581-http-curl-verbose.sh @@ -4,6 +4,7 @@ test_description='test GIT_CURL_VERBOSE' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-httpd.sh start_httpd diff --git a/transport-helper.c b/transport-helper.c index 780fcaf529..9820947ab2 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -22,7 +22,7 @@ static int debug; struct helper_data { - const char *name; + char *name; struct child_process *helper; FILE *out; unsigned fetch : 1, @@ -111,6 +111,7 @@ static void do_take_over(struct transport *transport) data = (struct helper_data *)transport->data; transport_take_over(transport, data->helper); fclose(data->out); + free(data->name); free(data); } @@ -253,6 +254,7 @@ static int disconnect_helper(struct transport *transport) close(data->helper->out); fclose(data->out); res = finish_command(data->helper); + FREE_AND_NULL(data->name); FREE_AND_NULL(data->helper); } return res; @@ -1297,7 +1299,7 @@ static struct transport_vtable vtable = { int transport_helper_init(struct transport *transport, const char *name) { struct helper_data *data = xcalloc(1, sizeof(*data)); - data->name = name; + data->name = xstrdup(name); transport_check_allowed(name); diff --git a/transport.c b/transport.c index 0ad04b77fd..83ddea8fbc 100644 --- a/transport.c +++ b/transport.c @@ -1176,6 +1176,7 @@ struct transport *transport_get(struct remote *remote, const char *url) int len = external_specification_len(url); char *handler = xmemdupz(url, len); transport_helper_init(ret, handler); + free(handler); } if (ret->smart_options) { From patchwork Mon May 27 11:46:01 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675089 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id D7370152DF2 for ; Mon, 27 May 2024 11:46:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810368; cv=none; b=kxRN+lDNq6enA0mD9ZMsVcZaohUbEmTyrksASxnq3unVgGea8Ob8WW/LhlPqwXrUBRFs7ZOKzsvOInGplTeKjqAOBOUtjXyad6XBiruQGEKxCcBqFrOm9x/Jjb2jcDMndu6WO9mKhgIVGB5xLB8s5uGQBP7aJzuznXE8Zspu1VM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810368; c=relaxed/simple; bh=ca1hJXB2ytmAL1QAfXwBxrCQphzR6V01eZAOycE2B1c=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=ejqcaBPIPTOIa+3Cs3xRCl+XnTmLFEgR30Z3UxjwgEa+HVRs/zhT47BrvchFBY5hHw5mWYUI+GDpDQSJ3Bv3t7l3uhdkmjvEm+KJdZLhBGBwKHL2lLFLBWdD6oCHR82DPCSzbiD/f5WsLtBHKl8DQ5uDrzBUuK9pK6DsxAANnq8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=AvptjSvy; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=hilLIKQQ; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="AvptjSvy"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="hilLIKQQ" Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfout.west.internal (Postfix) with ESMTP id CBC2A1C000F6; Mon, 27 May 2024 07:46:05 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Mon, 27 May 2024 07:46:06 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810365; x=1716896765; bh=wZeeX/YAiP 3l9QhDTeD8RtsE5qYhF1DpuSrS0IyEoRM=; b=AvptjSvyvBOZwpCJToLkgtU/3B /vmrn6oj4ljBG8MZzJ4grPuY+xijSGMHWZYMXK0F8ye+/EItL4AS0KTKgdpsMFj4 ScxsxmspREHHtixtdkAimSKTSg1LTKT6eFjrSCFukZBatxHFcFG8ueOzSiDACU4o v//qeAtg3nwX02KTo0IPQWWWUaGmskU8w+Rx1kIZ+13Njk770OQboFFtMqZdrgUi Jc3SI6NekcN/wR/pjqZOHtmlbN8RPpnudVuSl4j42k2z23V4nlK4qr7RPmsNVcWw QEthRVDT7z/yspujQGd95Dr0grwVPl4WLtVHXZSuFboeGHM8heJ/nqbutJKw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810365; x=1716896765; bh=wZeeX/YAiP3l9QhDTeD8RtsE5qYh F1DpuSrS0IyEoRM=; b=hilLIKQQo18XlWAZP0HSFilaaRzQGzAMQViM9JPP6kmF Ame1VzrDFrJzdMBzzkTw75BK27CUEMczTQ6LnF1l5QOnpLyqmNE0OL23Mz7658Cj sVj0y1IuDrlnwDBwD8KcdC0beOVPQbP0gdgnXuhhEELCcA24rQRs2/0QAfLtZ80w zxrS2uVcOrwBlbrXzkU3dn6QLFUemtzJ0W83vNMX6nuR2tQmEnRMGjhRp3RY8PVa Mfead9AaoCi8K8WqioJUKCO7Lb9UHEsnh/qeQRJkMBQMzxEU7TMjc82AAvn6bcxb DUcCag844GhQRHfP2feQqUU2+yp6VwueBDHg5Me3Dw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:03 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 41344458 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:45:53 +0000 (UTC) Date: Mon, 27 May 2024 13:46:01 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 04/21] strbuf: fix leak when `appendwholeline()` fails with EOF Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: In `strbuf_appendwholeline()` we call `strbuf_getwholeline()` with a temporary buffer. In case the call returns an error we indicate this by returning EOF, but never release the temporary buffer. This can cause a leak though because `strbuf_getwholeline()` calls getline(3). Quoting its documentation: If *lineptr was set to NULL before the call, then the buffer should be freed by the user program even on failure. Consequently, the temporary buffer may hold allocated memory even when the call to `strbuf_getwholeline()` fails. Fix this by releasing the temporary buffer on error. Signed-off-by: Patrick Steinhardt --- strbuf.c | 4 +++- t/t1400-update-ref.sh | 2 ++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/strbuf.c b/strbuf.c index 0d929e4e19..e1076c9891 100644 --- a/strbuf.c +++ b/strbuf.c @@ -691,8 +691,10 @@ int strbuf_getwholeline(struct strbuf *sb, FILE *fp, int term) int strbuf_appendwholeline(struct strbuf *sb, FILE *fp, int term) { struct strbuf line = STRBUF_INIT; - if (strbuf_getwholeline(&line, fp, term)) + if (strbuf_getwholeline(&line, fp, term)) { + strbuf_release(&line); return EOF; + } strbuf_addbuf(sb, &line); strbuf_release(&line); return 0; diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index ec3443cc87..bbee2783ab 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -4,6 +4,8 @@ # test_description='Test git update-ref and basic ref logging' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh Z=$ZERO_OID From patchwork Mon May 27 11:46:06 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675090 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4357613A3EF for ; Mon, 27 May 2024 11:46:10 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810373; cv=none; b=sElE4bZU6ZyvHYraHs93MwnQ/pTYPlY34zU+fdhkb9bLmgV2WE46pDEzhKpWSWR01oblsPL6nFGdvw88cckVPFJfT3x68b/uH+lt2NWAomusxmHEykY9+zZhbxf4sZETf4o5zFN6SzpXKM2ckY+lW3Zc7wD9xOiGNJy1zB7Pn6I= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810373; c=relaxed/simple; bh=RiQTuGf9xVzgk0s4QjTeB4LHU1rdVNECkB+/+SkDC9U=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=fRzWM7SwFjtzb5XWwrEsqbWUAX0OqW9cbs102+7V41+50xkYtiu1DyOSukiMER0qqh7liPTgZdMpbzfUa+fC0qYhqfKFgqzHlAETgf7rjf0X3w5rInBQ1V1Z95Vwif4OAy4WA6rhKfCz6dBEwm97d/AT5b56gaNaZinshs1HhmM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=CTRaJ9xM; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=N+xbdFXF; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="CTRaJ9xM"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="N+xbdFXF" Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailfhigh.west.internal (Postfix) with ESMTP id 3190F18000D3; Mon, 27 May 2024 07:46:10 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Mon, 27 May 2024 07:46:10 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810369; x=1716896769; bh=C5QpoMcPLD JzUz+I3bRVsQt8z0kl/5bZsext74e9Pp4=; b=CTRaJ9xMY+nuMo4L2j5usoLmez Q+NTp7F94NNLPBxIFPiPMsH/6UdFsj+7bukpOxcMQ0tIlT1qpIBYh9gEp4st0HVu q7pivNgLjtDpTJwKXH/HXayb9XRZ1awPUW7kWHhHPFRNwShWjXwOyXWVsOZHDcQ3 TilnitBDXY/OrkS6QFkJFd/jlCCNztgp7LbYXPfhhm0cHqVbCxlCF2ZOTWtJP7ue hq+aH7VN89xDnQMW4bY8f9hj4cha/15jxHxSHBbnfyx4KrOiS/uoe++iVxbu2lb7 qbat9by8Nn6jwQT1MU5vpYGyfgVtfIkF2uJ5hu9VQyGlgK3Grur8S/TD1J5w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810369; x=1716896769; bh=C5QpoMcPLDJzUz+I3bRVsQt8z0kl /5bZsext74e9Pp4=; b=N+xbdFXFw1eJ/2B6r5LfqkWBFU/ICZrxERBFIKRhsFZC ZIyVSJqSw7AFBt6TPPeWv1nRbDyt5pti5q5e+aEgKMxxo9fwAZkRpWD1lWrAH+wd nTOkENeOagM1bS5a5I+F1gwUxS7+UQ9+VRqO4pa38uCd5/f4qMgcgw8rc3eHRMhq hdpckZRdOMq8nPkGHRBhHuuoQHyBIZrM30WIB6A0KOyqPi9gvl3KWheHn9r/HuoB sxyQo4DPO9yee8ZvKu6DI83kh+H7/GZwu9oCgiHH+kCkPQqnrXk6frmuiNwjK3xM WIamMqUQ8lSMG7PkEIk65juqn7kFzLV2dKHmWzJp6w== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:08 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id ad109430 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:45:58 +0000 (UTC) Date: Mon, 27 May 2024 13:46:06 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 05/21] checkout: clarify memory ownership in `unique_tracking_name()` Message-ID: <4a6dd9b6a85d99fb0e3ba2ef3af4c0f2846560cb.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The function `unique_tracking_name()` returns an allocated string, but does not clearly indicate this because its return type is `const char *` instead of `char *`. This has led to various callsites where we never free its returned memory at all, which causes memory leaks. Plug those leaks and mark now-passing tests as leak free. Signed-off-by: Patrick Steinhardt --- builtin/checkout.c | 14 +++++++------ builtin/worktree.c | 20 ++++++++++--------- checkout.c | 4 ++-- checkout.h | 6 +++--- t/t2024-checkout-dwim.sh | 1 + t/t2060-switch.sh | 1 + t/t3426-rebase-submodule.sh | 1 + t/t3512-cherry-pick-submodule.sh | 1 + t/t3513-revert-submodule.sh | 1 + t/t3600-rm.sh | 1 + t/t3906-stash-submodule.sh | 1 + t/t4137-apply-submodule.sh | 1 + t/t6041-bisect-submodule.sh | 1 + t/t6438-submodule-directory-file-conflicts.sh | 1 + 14 files changed, 34 insertions(+), 20 deletions(-) diff --git a/builtin/checkout.c b/builtin/checkout.c index f90a4ca4b7..3cf44b4683 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -1275,12 +1275,12 @@ static void setup_new_branch_info_and_source_tree( } } -static const char *parse_remote_branch(const char *arg, - struct object_id *rev, - int could_be_checkout_paths) +static char *parse_remote_branch(const char *arg, + struct object_id *rev, + int could_be_checkout_paths) { int num_matches = 0; - const char *remote = unique_tracking_name(arg, rev, &num_matches); + char *remote = unique_tracking_name(arg, rev, &num_matches); if (remote && could_be_checkout_paths) { die(_("'%s' could be both a local file and a tracking branch.\n" @@ -1316,6 +1316,7 @@ static int parse_branchname_arg(int argc, const char **argv, const char **new_branch = &opts->new_branch; int argcount = 0; const char *arg; + char *remote = NULL; int dash_dash_pos; int has_dash_dash = 0; int i; @@ -1416,8 +1417,8 @@ static int parse_branchname_arg(int argc, const char **argv, recover_with_dwim = 0; if (recover_with_dwim) { - const char *remote = parse_remote_branch(arg, rev, - could_be_checkout_paths); + remote = parse_remote_branch(arg, rev, + could_be_checkout_paths); if (remote) { *new_branch = arg; arg = remote; @@ -1459,6 +1460,7 @@ static int parse_branchname_arg(int argc, const char **argv, argc--; } + free(remote); return argcount; } diff --git a/builtin/worktree.c b/builtin/worktree.c index 7e0868df72..937da6c0ee 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -736,16 +736,14 @@ static int dwim_orphan(const struct add_opts *opts, int opt_track, int remote) return 1; } -static const char *dwim_branch(const char *path, const char **new_branch) +static char *dwim_branch(const char *path, char **new_branch) { int n; int branch_exists; const char *s = worktree_basename(path, &n); - const char *branchname = xstrndup(s, n); + char *branchname = xstrndup(s, n); struct strbuf ref = STRBUF_INIT; - UNLEAK(branchname); - branch_exists = !strbuf_check_branch_ref(&ref, branchname) && refs_ref_exists(get_main_ref_store(the_repository), ref.buf); @@ -756,8 +754,7 @@ static const char *dwim_branch(const char *path, const char **new_branch) *new_branch = branchname; if (guess_remote) { struct object_id oid; - const char *remote = - unique_tracking_name(*new_branch, &oid, NULL); + char *remote = unique_tracking_name(*new_branch, &oid, NULL); return remote; } return NULL; @@ -769,6 +766,8 @@ static int add(int ac, const char **av, const char *prefix) const char *new_branch_force = NULL; char *path; const char *branch; + char *branch_to_free = NULL; + char *new_branch_to_free = NULL; const char *new_branch = NULL; const char *opt_track = NULL; const char *lock_reason = NULL; @@ -859,16 +858,17 @@ static int add(int ac, const char **av, const char *prefix) opts.orphan = dwim_orphan(&opts, !!opt_track, 0); } else if (ac < 2) { /* DWIM: Guess branch name from path. */ - const char *s = dwim_branch(path, &new_branch); + char *s = dwim_branch(path, &new_branch_to_free); if (s) - branch = s; + branch = branch_to_free = s; + new_branch = new_branch_to_free; /* DWIM: Infer --orphan when repo has no refs. */ opts.orphan = (!s) && dwim_orphan(&opts, !!opt_track, 1); } else if (ac == 2) { struct object_id oid; struct commit *commit; - const char *remote; + char *remote; commit = lookup_commit_reference_by_name(branch); if (!commit) { @@ -923,6 +923,8 @@ static int add(int ac, const char **av, const char *prefix) ret = add_worktree(path, branch, &opts); free(path); + free(branch_to_free); + free(new_branch_to_free); return ret; } diff --git a/checkout.c b/checkout.c index 4256e71a7c..cfaea4bd10 100644 --- a/checkout.c +++ b/checkout.c @@ -45,8 +45,8 @@ static int check_tracking_name(struct remote *remote, void *cb_data) return 0; } -const char *unique_tracking_name(const char *name, struct object_id *oid, - int *dwim_remotes_matched) +char *unique_tracking_name(const char *name, struct object_id *oid, + int *dwim_remotes_matched) { struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT; const char *default_remote = NULL; diff --git a/checkout.h b/checkout.h index 3c514a5ab4..ba15a13fb3 100644 --- a/checkout.h +++ b/checkout.h @@ -8,8 +8,8 @@ * tracking branch. Return the name of the remote if such a branch * exists, NULL otherwise. */ -const char *unique_tracking_name(const char *name, - struct object_id *oid, - int *dwim_remotes_matched); +char *unique_tracking_name(const char *name, + struct object_id *oid, + int *dwim_remotes_matched); #endif /* CHECKOUT_H */ diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh index a3b1449ef1..2caada3d83 100755 --- a/t/t2024-checkout-dwim.sh +++ b/t/t2024-checkout-dwim.sh @@ -4,6 +4,7 @@ test_description='checkout Ensures that checkout on an unborn branch does what the user expects' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Is the current branch "refs/heads/$1"? diff --git a/t/t2060-switch.sh b/t/t2060-switch.sh index c91c4db936..77b2346291 100755 --- a/t/t2060-switch.sh +++ b/t/t2060-switch.sh @@ -5,6 +5,7 @@ test_description='switch basic functionality' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t3426-rebase-submodule.sh b/t/t3426-rebase-submodule.sh index ba069dccbd..94ea88e384 100755 --- a/t/t3426-rebase-submodule.sh +++ b/t/t3426-rebase-submodule.sh @@ -2,6 +2,7 @@ test_description='rebase can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t3512-cherry-pick-submodule.sh b/t/t3512-cherry-pick-submodule.sh index f22d1ddead..9387a22a9e 100755 --- a/t/t3512-cherry-pick-submodule.sh +++ b/t/t3512-cherry-pick-submodule.sh @@ -5,6 +5,7 @@ test_description='cherry-pick can handle submodules' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t3513-revert-submodule.sh b/t/t3513-revert-submodule.sh index 8bfe3ed246..e178968b40 100755 --- a/t/t3513-revert-submodule.sh +++ b/t/t3513-revert-submodule.sh @@ -2,6 +2,7 @@ test_description='revert can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 98259e2ada..31ac31d4bc 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -8,6 +8,7 @@ test_description='Test of the various options to git rm.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Setup some files to be removed, some with funny characters diff --git a/t/t3906-stash-submodule.sh b/t/t3906-stash-submodule.sh index 0f7348ec21..0f61f01ef4 100755 --- a/t/t3906-stash-submodule.sh +++ b/t/t3906-stash-submodule.sh @@ -2,6 +2,7 @@ test_description='stash can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t4137-apply-submodule.sh b/t/t4137-apply-submodule.sh index 07d5262537..ebd0d4ad17 100755 --- a/t/t4137-apply-submodule.sh +++ b/t/t4137-apply-submodule.sh @@ -2,6 +2,7 @@ test_description='git apply handling submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t6041-bisect-submodule.sh b/t/t6041-bisect-submodule.sh index 82013fc903..3946e18089 100755 --- a/t/t6041-bisect-submodule.sh +++ b/t/t6041-bisect-submodule.sh @@ -2,6 +2,7 @@ test_description='bisect can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t6438-submodule-directory-file-conflicts.sh b/t/t6438-submodule-directory-file-conflicts.sh index 8df67a0ef9..3594190af8 100755 --- a/t/t6438-submodule-directory-file-conflicts.sh +++ b/t/t6438-submodule-directory-file-conflicts.sh @@ -2,6 +2,7 @@ test_description='merge can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh From patchwork Mon May 27 11:46:10 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675091 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8888713A3EF for ; Mon, 27 May 2024 11:46:15 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810377; cv=none; b=lM59pPKZ3zJKQw4DxTZlbcwvOhenv9kM+O9PUd1kAjryYw9rOOoG9WXm9CXNqTkwaxJDtfiL4gKr1KuIMlvCWhdcC4nziy5wheIkskW0MjaRzn1q1SZCcvQoD3q5bVuqdt1brtztJEhcy6oTUeshqkCZC7p13LNRUPKwp6bQDSQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810377; c=relaxed/simple; bh=U0Yq52foY48be+fBFT7baqopcx2545LLpwhy5dtwMRk=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=rk6E0uDXh3DJfevbXvGN/brL4JR+h2qKvnAME6PWbEphUpUoWpmfQzu+4pWYaLMyvKmYfK54P8Tpcl/g/CXakErJ/BTpjCaCzqcG8N6pqXH+s7J54JlfJfIBq23sDajKjfEHMgP8AFpe5yR7KMeyqzWOXWfdmWnvA9bWSgaf7xI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=bLoGbyxe; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=gRbOc/U/; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="bLoGbyxe"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="gRbOc/U/" Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfout.west.internal (Postfix) with ESMTP id 904AF1C000F6; Mon, 27 May 2024 07:46:14 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Mon, 27 May 2024 07:46:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810374; x=1716896774; bh=UWjcAxfkht tcxfGYVLFLS2IFnWFXcetmGCVj1Cy1ZAk=; b=bLoGbyxeGMOo7eeWhXsdryqyMC Cu4u4U5Afsg/xCPESyleWuYJwjc5YuyJL9B3ed7kq//5c/3VhapBXYSB6sm7tCHk zL9NOUE7fug6ztOBbQNNv1hY6IQSdAifRpy2fU/SCiRri2+6ggIzWhcidsPja+pp A+TkV34pEZv+d9uFoiylpdlQHyyuj8nYS02aTe/29Uo70+TbvXcqrC6lPkZLtsaD h3vimjBbMEa2WVftc8lJdWHxBZ8cmpSErsnjwB/PM9+zVVdlPVQgzkRSI3NEfOdZ +xFyx6wpVdwaAMbxdk3bekx+ZcpnimJDps7o5h0oRN5pV7vijPVdnClQuDaA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810374; x=1716896774; bh=UWjcAxfkhttcxfGYVLFLS2IFnWFX cetmGCVj1Cy1ZAk=; b=gRbOc/U/ATT+vjAop0la8vMP0vRwjY2VwTtWxOY5jXVM PdlRhwmnraLlDUCpXoIo7hY4jtZ6bAV7ezjxTl4Q+Da/aEGzldun//9KQLiLDB/f slccYiViAt1/ilWwn0yrH5DhyLEjKHlH1FBIPFF4K1AZaC0H1wIAqNN1SN2Fs4Iy XYFS7/2F7+ctbNGiAe0OS6SV6KebUR9J9jaaXhTplp5KU1S8rNFcEeQZ/5H8Wgk1 iunP87phklzVBirn5zhwyf/L9LOwNqsf6fPz8XHqxEY0l0fKHRmqj0aT8At4zJJ3 zR69Oea+zupeTR66mJ07eXbyO75C8RjtFQ9NLDZH0Q== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:12 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 5c610e96 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:03 +0000 (UTC) Date: Mon, 27 May 2024 13:46:10 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 06/21] http: refactor code to clarify memory ownership Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: There are various variables assigned via `git_config_string()` and `git_config_pathname()` which are never free'd. This bug is relatable because the out parameter of those functions are a `const char **`, even though memory ownership is transferred to the caller. We're about to adapt the functions to instead use `char **`. Prepare the code accordingly. Note that the `(const char **)` casts will go away once we have adapted the functions. Signed-off-by: Patrick Steinhardt --- http.c | 62 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 32 insertions(+), 30 deletions(-) diff --git a/http.c b/http.c index 752c879c1f..db2e2f1d39 100644 --- a/http.c +++ b/http.c @@ -39,8 +39,8 @@ char curl_errorstr[CURL_ERROR_SIZE]; static int curl_ssl_verify = -1; static int curl_ssl_try; static const char *curl_http_version = NULL; -static const char *ssl_cert; -static const char *ssl_cert_type; +static char *ssl_cert; +static char *ssl_cert_type; static const char *ssl_cipherlist; static const char *ssl_version; static struct { @@ -59,23 +59,23 @@ static struct { { "tlsv1.3", CURL_SSLVERSION_TLSv1_3 }, #endif }; -static const char *ssl_key; -static const char *ssl_key_type; -static const char *ssl_capath; -static const char *curl_no_proxy; +static char *ssl_key; +static char *ssl_key_type; +static char *ssl_capath; +static char *curl_no_proxy; #ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY static const char *ssl_pinnedkey; #endif -static const char *ssl_cainfo; +static char *ssl_cainfo; static long curl_low_speed_limit = -1; static long curl_low_speed_time = -1; static int curl_ftp_no_epsv; -static const char *curl_http_proxy; -static const char *http_proxy_authmethod; +static char *curl_http_proxy; +static char *http_proxy_authmethod; -static const char *http_proxy_ssl_cert; -static const char *http_proxy_ssl_key; -static const char *http_proxy_ssl_ca_info; +static char *http_proxy_ssl_cert; +static char *http_proxy_ssl_key; +static char *http_proxy_ssl_ca_info; static struct credential proxy_cert_auth = CREDENTIAL_INIT; static int proxy_ssl_cert_password_required; @@ -112,7 +112,7 @@ static const char *curl_cookie_file; static int curl_save_cookies; struct credential http_auth = CREDENTIAL_INIT; static int http_proactive_auth; -static const char *user_agent; +static char *user_agent; static int curl_empty_auth = -1; enum http_follow_config http_follow_config = HTTP_FOLLOW_INITIAL; @@ -381,17 +381,17 @@ static int http_options(const char *var, const char *value, if (!strcmp("http.sslversion", var)) return git_config_string(&ssl_version, var, value); if (!strcmp("http.sslcert", var)) - return git_config_pathname(&ssl_cert, var, value); + return git_config_pathname((const char **)&ssl_cert, var, value); if (!strcmp("http.sslcerttype", var)) - return git_config_string(&ssl_cert_type, var, value); + return git_config_string((const char **)&ssl_cert_type, var, value); if (!strcmp("http.sslkey", var)) - return git_config_pathname(&ssl_key, var, value); + return git_config_pathname((const char **)&ssl_key, var, value); if (!strcmp("http.sslkeytype", var)) - return git_config_string(&ssl_key_type, var, value); + return git_config_string((const char **)&ssl_key_type, var, value); if (!strcmp("http.sslcapath", var)) - return git_config_pathname(&ssl_capath, var, value); + return git_config_pathname((const char **)&ssl_capath, var, value); if (!strcmp("http.sslcainfo", var)) - return git_config_pathname(&ssl_cainfo, var, value); + return git_config_pathname((const char **)&ssl_cainfo, var, value); if (!strcmp("http.sslcertpasswordprotected", var)) { ssl_cert_password_required = git_config_bool(var, value); return 0; @@ -440,19 +440,19 @@ static int http_options(const char *var, const char *value, return 0; } if (!strcmp("http.proxy", var)) - return git_config_string(&curl_http_proxy, var, value); + return git_config_string((const char **)&curl_http_proxy, var, value); if (!strcmp("http.proxyauthmethod", var)) - return git_config_string(&http_proxy_authmethod, var, value); + return git_config_string((const char **)&http_proxy_authmethod, var, value); if (!strcmp("http.proxysslcert", var)) - return git_config_string(&http_proxy_ssl_cert, var, value); + return git_config_string((const char **)&http_proxy_ssl_cert, var, value); if (!strcmp("http.proxysslkey", var)) - return git_config_string(&http_proxy_ssl_key, var, value); + return git_config_string((const char **)&http_proxy_ssl_key, var, value); if (!strcmp("http.proxysslcainfo", var)) - return git_config_string(&http_proxy_ssl_ca_info, var, value); + return git_config_string((const char **)&http_proxy_ssl_ca_info, var, value); if (!strcmp("http.proxysslcertpasswordprotected", var)) { proxy_ssl_cert_password_required = git_config_bool(var, value); @@ -476,7 +476,7 @@ static int http_options(const char *var, const char *value, } if (!strcmp("http.useragent", var)) - return git_config_string(&user_agent, var, value); + return git_config_string((const char **)&user_agent, var, value); if (!strcmp("http.emptyauth", var)) { if (value && !strcmp("auto", value)) @@ -592,10 +592,10 @@ static void init_curl_http_auth(CURL *result) } /* *var must be free-able */ -static void var_override(const char **var, char *value) +static void var_override(char **var, char *value) { if (value) { - free((void *)*var); + free(*var); *var = xstrdup(value); } } @@ -1233,11 +1233,13 @@ static CURL *get_curl_handle(void) return result; } -static void set_from_env(const char **var, const char *envname) +static void set_from_env(char **var, const char *envname) { const char *val = getenv(envname); - if (val) - *var = val; + if (val) { + FREE_AND_NULL(*var); + *var = xstrdup(val); + } } void http_init(struct remote *remote, const char *url, int proactive_auth) From patchwork Mon May 27 11:46:15 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675092 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B91B513A3EF for ; Mon, 27 May 2024 11:46:20 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810382; cv=none; b=WmK0tf4ZbaSul4fM0YxtpS39ev2dqfLaNGiDAug6VgkGka+1+s4EP0vtmdrg5t/0ZehEwPQGv8RSSZg/d9bYJKXZIe0wXdwfIRKPCR1sLpccX2w7BtyPcS1dfxnWgNpK2rFzpUG0lvKG2OS+EcWeYcndc9/hAyt7QZQgvpV1D+o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810382; c=relaxed/simple; bh=N7mQrh2GDTnojOv8dRlNZl2zglzZHNw1ajotz4u/xEs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=RFyj1RnFdLWPcdfseoCHgkzEqXWK2xk3uQyh6Rx0doOY6zZJ2UAIpFjB0nqF0a+17xMsiURuKO/yMlT+dxlIeeFzAl038JPEVcub6843MgZPjq7UO5td9Wz4ii9Nhg1IgG5iA1YplnmIqbm4299/itX7krvCLusQCL2AMvLvGR4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=GQ5iLPFg; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=ILLbs033; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="GQ5iLPFg"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="ILLbs033" Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfout.west.internal (Postfix) with ESMTP id F3BC31C000AF; Mon, 27 May 2024 07:46:19 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Mon, 27 May 2024 07:46:20 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810379; x=1716896779; bh=y1WzbNbcYH 6PRL9S9XdWubUQUcA8vn28Qm3cf+8cnJ0=; b=GQ5iLPFgsVmx8N/GdPZtkXjaAm JkjDZmYploMCw9J68ePR6wt11XzS9Ibfa+B9wFUgRjkFWi0u0joHaKXtciy1Iaee N4+JbkDgDMHoZ6UK/uBXpVoHiYzR4UqDPix8VS3JxUuLFB5cnErICDaeGMHEtOVm +3OfvETPn+Jmfhf2yVkEqWK7qvyPNaZ7VW3ZZBxH8XvCmGSvO0O6z94J37fon/Hz 801TUH6YR21hWTIT7bLAGW/CYySqMFmSrJKzglptgr2YkEos+AaYTZPloR4Dlzci b001ihKJPKTwQaVa0PICfB4diblCAZ6X1TEBSsViPLHNqaz4HXTsUWlyNrOA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810379; x=1716896779; bh=y1WzbNbcYH6PRL9S9XdWubUQUcA8 vn28Qm3cf+8cnJ0=; b=ILLbs03352qepx1cdSViIxkjePUTV+e+ASlLDBLsZtp9 0HN9F9vgmRGQaBcTuXng4sYkcNXujVvTz72qKKbf2ADKkJ9RxKh3+pH7jCOxVwe5 hgHiGL8rCgF+X5O1C2TroqJjPooKuBATjMIAxcDDbvJgCH/cNK1UDOajyfCKG8rj q3t5K9cbmJTJdwUMcatG27jrUFB3l9HMRZOkuykbIKoSB09QtJ+bWbwa3MpHvkEe jWCgvIcGVR42Ge0HnfTOW5Oh0HSuV0trItMFZGGdwTYz5cQ+UCGfIEqgv8oqnAb2 /PUkV5Tob8Wv4PqWqRYiNWxtBzAMGo0NutBnjxosiA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepvdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:18 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id e1fbce4e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:07 +0000 (UTC) Date: Mon, 27 May 2024 13:46:15 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 07/21] config: clarify memory ownership in `git_config_pathname()` Message-ID: <88babf1abf93dd589fb1bc311483f4c6852b125b.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The out parameter of `git_config_pathname()` is a `const char **` even though we transfer ownership of memory to the caller. This is quite misleading and has led to many memory leaks all over the place. Adapt the parameter to instead be `char **`. Signed-off-by: Patrick Steinhardt --- builtin/blame.c | 2 +- builtin/commit.c | 2 +- builtin/config.c | 2 +- builtin/log.c | 2 +- builtin/receive-pack.c | 4 ++-- config.c | 10 +++++----- config.h | 8 ++++---- diff.c | 2 +- environment.c | 6 +++--- environment.h | 6 +++--- fetch-pack.c | 4 ++-- fsck.c | 4 ++-- fsmonitor-settings.c | 5 ++++- gpg-interface.c | 4 +++- http.c | 12 ++++++------ mailmap.c | 2 +- mailmap.h | 2 +- setup.c | 6 +++--- 18 files changed, 44 insertions(+), 39 deletions(-) diff --git a/builtin/blame.c b/builtin/blame.c index 6bc7aa6085..838cd476be 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -718,7 +718,7 @@ static int git_blame_config(const char *var, const char *value, return 0; } if (!strcmp(var, "blame.ignorerevsfile")) { - const char *str; + char *str; int ret; ret = git_config_pathname(&str, var, value); diff --git a/builtin/commit.c b/builtin/commit.c index 78bfae2164..1cc88e92bf 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -107,7 +107,7 @@ static enum { } commit_style; static const char *logfile, *force_author; -static const char *template_file; +static char *template_file; /* * The _message variables are commit names from which to take * the commit message and/or authorship. diff --git a/builtin/config.c b/builtin/config.c index 80aa9d8a66..cc343f55ca 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -277,7 +277,7 @@ static int format_config(struct strbuf *buf, const char *key_, else strbuf_addstr(buf, v ? "true" : "false"); } else if (type == TYPE_PATH) { - const char *v; + char *v; if (git_config_pathname(&v, key_, value_) < 0) return -1; strbuf_addstr(buf, v); diff --git a/builtin/log.c b/builtin/log.c index b17dd8b40a..a2f5845556 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -957,7 +957,7 @@ static int do_signoff; static enum auto_base_setting auto_base; static char *from; static const char *signature = git_version_string; -static const char *signature_file; +static char *signature_file; static enum cover_setting config_cover_letter; static const char *config_output_directory; static enum cover_from_description cover_from_description_mode = COVER_FROM_MESSAGE; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index be8969a84a..56228ad314 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -168,13 +168,13 @@ static int receive_pack_config(const char *var, const char *value, } if (strcmp(var, "receive.fsck.skiplist") == 0) { - const char *path; + char *path; if (git_config_pathname(&path, var, value)) return 1; strbuf_addf(&fsck_msg_types, "%cskiplist=%s", fsck_msg_types.len ? ',' : '=', path); - free((char *)path); + free(path); return 0; } diff --git a/config.c b/config.c index d57996240b..fb56e11276 100644 --- a/config.c +++ b/config.c @@ -1346,7 +1346,7 @@ int git_config_string(const char **dest, const char *var, const char *value) return 0; } -int git_config_pathname(const char **dest, const char *var, const char *value) +int git_config_pathname(char **dest, const char *var, const char *value) { if (!value) return config_error_nonbool(var); @@ -1597,7 +1597,7 @@ static int git_default_core_config(const char *var, const char *value, return git_config_string(&askpass_program, var, value); if (!strcmp(var, "core.excludesfile")) { - free((char *)excludes_file); + free(excludes_file); return git_config_pathname(&excludes_file, var, value); } @@ -2494,7 +2494,7 @@ int git_configset_get_maybe_bool(struct config_set *set, const char *key, int *d return 1; } -int git_configset_get_pathname(struct config_set *set, const char *key, const char **dest) +int git_configset_get_pathname(struct config_set *set, const char *key, char **dest) { const char *value; if (!git_configset_get_value(set, key, &value, NULL)) @@ -2639,7 +2639,7 @@ int repo_config_get_maybe_bool(struct repository *repo, } int repo_config_get_pathname(struct repository *repo, - const char *key, const char **dest) + const char *key, char **dest) { int ret; git_config_check_init(repo); @@ -2738,7 +2738,7 @@ int git_config_get_maybe_bool(const char *key, int *dest) return repo_config_get_maybe_bool(the_repository, key, dest); } -int git_config_get_pathname(const char *key, const char **dest) +int git_config_get_pathname(const char *key, char **dest) { return repo_config_get_pathname(the_repository, key, dest); } diff --git a/config.h b/config.h index db8b608064..b3103bba94 100644 --- a/config.h +++ b/config.h @@ -286,7 +286,7 @@ int git_config_string(const char **, const char *, const char *); * Similar to `git_config_string`, but expands `~` or `~user` into the * user's home directory when found at the beginning of the path. */ -int git_config_pathname(const char **, const char *, const char *); +int git_config_pathname(char **, const char *, const char *); int git_config_expiry_date(timestamp_t *, const char *, const char *); int git_config_color(char *, const char *, const char *); @@ -541,7 +541,7 @@ int git_configset_get_ulong(struct config_set *cs, const char *key, unsigned lon int git_configset_get_bool(struct config_set *cs, const char *key, int *dest); int git_configset_get_bool_or_int(struct config_set *cs, const char *key, int *is_bool, int *dest); int git_configset_get_maybe_bool(struct config_set *cs, const char *key, int *dest); -int git_configset_get_pathname(struct config_set *cs, const char *key, const char **dest); +int git_configset_get_pathname(struct config_set *cs, const char *key, char **dest); /* Functions for reading a repository's config */ struct repository; @@ -577,7 +577,7 @@ int repo_config_get_bool_or_int(struct repository *repo, int repo_config_get_maybe_bool(struct repository *repo, const char *key, int *dest); int repo_config_get_pathname(struct repository *repo, - const char *key, const char **dest); + const char *key, char **dest); /* * Functions for reading protected config. By definition, protected @@ -687,7 +687,7 @@ int git_config_get_maybe_bool(const char *key, int *dest); * Similar to `git_config_get_string`, but expands `~` or `~user` into * the user's home directory when found at the beginning of the path. */ -int git_config_get_pathname(const char *key, const char **dest); +int git_config_get_pathname(const char *key, char **dest); int git_config_get_index_threads(int *dest); int git_config_get_split_index(void); diff --git a/diff.c b/diff.c index ded9ac70df..902df9286a 100644 --- a/diff.c +++ b/diff.c @@ -58,7 +58,7 @@ static int diff_context_default = 3; static int diff_interhunk_context_default; static const char *diff_word_regex_cfg; static const char *external_diff_cmd_cfg; -static const char *diff_order_file_cfg; +static char *diff_order_file_cfg; int diff_auto_refresh_index = 1; static int diff_mnemonic_prefix; static int diff_no_prefix; diff --git a/environment.c b/environment.c index a73ba9c12c..279ea3fd5e 100644 --- a/environment.c +++ b/environment.c @@ -46,8 +46,8 @@ const char *git_commit_encoding; const char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; -const char *git_attributes_file; -const char *git_hooks_path; +char *git_attributes_file; +char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int pack_compression_level = Z_DEFAULT_COMPRESSION; int fsync_object_files = -1; @@ -60,7 +60,7 @@ size_t delta_base_cache_limit = 96 * 1024 * 1024; unsigned long big_file_threshold = 512 * 1024 * 1024; const char *editor_program; const char *askpass_program; -const char *excludes_file; +char *excludes_file; enum auto_crlf auto_crlf = AUTO_CRLF_FALSE; enum eol core_eol = EOL_UNSET; int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; diff --git a/environment.h b/environment.h index 0b2d457f07..be1b88ad6f 100644 --- a/environment.h +++ b/environment.h @@ -131,8 +131,8 @@ extern int warn_ambiguous_refs; extern int warn_on_object_refname_ambiguity; extern char *apply_default_whitespace; extern char *apply_default_ignorewhitespace; -extern const char *git_attributes_file; -extern const char *git_hooks_path; +extern char *git_attributes_file; +extern char *git_hooks_path; extern int zlib_compression_level; extern int pack_compression_level; extern size_t packed_git_window_size; @@ -229,7 +229,7 @@ extern const char *git_log_output_encoding; extern const char *editor_program; extern const char *askpass_program; -extern const char *excludes_file; +extern char *excludes_file; /* * Should we print an ellipsis after an abbreviated SHA-1 value diff --git a/fetch-pack.c b/fetch-pack.c index 8e8f3bba32..d80e9c92dd 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -1865,13 +1865,13 @@ static int fetch_pack_config_cb(const char *var, const char *value, const char *msg_id; if (strcmp(var, "fetch.fsck.skiplist") == 0) { - const char *path; + char *path ; if (git_config_pathname(&path, var, value)) return 1; strbuf_addf(&fsck_msg_types, "%cskiplist=%s", fsck_msg_types.len ? ',' : '=', path); - free((char *)path); + free(path); return 0; } diff --git a/fsck.c b/fsck.c index 8ef962199f..7dff41413e 100644 --- a/fsck.c +++ b/fsck.c @@ -1330,13 +1330,13 @@ int git_fsck_config(const char *var, const char *value, const char *msg_id; if (strcmp(var, "fsck.skiplist") == 0) { - const char *path; + char *path; struct strbuf sb = STRBUF_INIT; if (git_config_pathname(&path, var, value)) return 1; strbuf_addf(&sb, "skiplist=%s", path); - free((char *)path); + free(path); fsck_set_msg_types(options, sb.buf); strbuf_release(&sb); return 0; diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index a6a9e6bc19..e818583420 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -103,6 +103,7 @@ static struct fsmonitor_settings *alloc_settings(void) static void lookup_fsmonitor_settings(struct repository *r) { const char *const_str; + char *to_free = NULL; int bool_value; if (r->settings.fsmonitor) @@ -129,8 +130,9 @@ static void lookup_fsmonitor_settings(struct repository *r) break; case -1: /* config value set to an arbitrary string */ - if (repo_config_get_pathname(r, "core.fsmonitor", &const_str)) + if (repo_config_get_pathname(r, "core.fsmonitor", &to_free)) return; /* should not happen */ + const_str = to_free; break; default: /* should not happen */ @@ -141,6 +143,7 @@ static void lookup_fsmonitor_settings(struct repository *r) fsm_settings__set_hook(r, const_str); else fsm_settings__set_disabled(r); + free(to_free); } enum fsmonitor_mode fsm_settings__get_mode(struct repository *r) diff --git a/gpg-interface.c b/gpg-interface.c index 1ff94266d2..2b50ed0fa0 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -27,7 +27,9 @@ static void gpg_interface_lazy_init(void) } static char *configured_signing_key; -static const char *ssh_default_key_command, *ssh_allowed_signers, *ssh_revocation_file; +static const char *ssh_default_key_command; +static char *ssh_allowed_signers; +static char *ssh_revocation_file; static enum signature_trust_level configured_min_trust_level = TRUST_UNDEFINED; struct gpg_format { diff --git a/http.c b/http.c index db2e2f1d39..fa3ea87451 100644 --- a/http.c +++ b/http.c @@ -64,7 +64,7 @@ static char *ssl_key_type; static char *ssl_capath; static char *curl_no_proxy; #ifdef GIT_CURL_HAVE_CURLOPT_PINNEDPUBLICKEY -static const char *ssl_pinnedkey; +static char *ssl_pinnedkey; #endif static char *ssl_cainfo; static long curl_low_speed_limit = -1; @@ -108,7 +108,7 @@ static struct { static struct credential proxy_auth = CREDENTIAL_INIT; static const char *curl_proxyuserpwd; -static const char *curl_cookie_file; +static char *curl_cookie_file; static int curl_save_cookies; struct credential http_auth = CREDENTIAL_INIT; static int http_proactive_auth; @@ -381,17 +381,17 @@ static int http_options(const char *var, const char *value, if (!strcmp("http.sslversion", var)) return git_config_string(&ssl_version, var, value); if (!strcmp("http.sslcert", var)) - return git_config_pathname((const char **)&ssl_cert, var, value); + return git_config_pathname(&ssl_cert, var, value); if (!strcmp("http.sslcerttype", var)) return git_config_string((const char **)&ssl_cert_type, var, value); if (!strcmp("http.sslkey", var)) - return git_config_pathname((const char **)&ssl_key, var, value); + return git_config_pathname(&ssl_key, var, value); if (!strcmp("http.sslkeytype", var)) return git_config_string((const char **)&ssl_key_type, var, value); if (!strcmp("http.sslcapath", var)) - return git_config_pathname((const char **)&ssl_capath, var, value); + return git_config_pathname(&ssl_capath, var, value); if (!strcmp("http.sslcainfo", var)) - return git_config_pathname((const char **)&ssl_cainfo, var, value); + return git_config_pathname(&ssl_cainfo, var, value); if (!strcmp("http.sslcertpasswordprotected", var)) { ssl_cert_password_required = git_config_bool(var, value); return 0; diff --git a/mailmap.c b/mailmap.c index 3d6a5e9400..044466b043 100644 --- a/mailmap.c +++ b/mailmap.c @@ -6,7 +6,7 @@ #include "object-store-ll.h" #include "setup.h" -const char *git_mailmap_file; +char *git_mailmap_file; const char *git_mailmap_blob; struct mailmap_info { diff --git a/mailmap.h b/mailmap.h index 0f8fd2c586..429a760945 100644 --- a/mailmap.h +++ b/mailmap.h @@ -3,7 +3,7 @@ struct string_list; -extern const char *git_mailmap_file; +extern char *git_mailmap_file; extern const char *git_mailmap_blob; int read_mailmap(struct string_list *map); diff --git a/setup.c b/setup.c index 9247cded6a..59ff3a19eb 100644 --- a/setup.c +++ b/setup.c @@ -1177,13 +1177,13 @@ static int safe_directory_cb(const char *key, const char *value, } else if (!strcmp(value, "*")) { data->is_safe = 1; } else { - const char *interpolated = NULL; + char *interpolated = NULL; if (!git_config_pathname(&interpolated, key, value) && !fspathcmp(data->path, interpolated ? interpolated : value)) data->is_safe = 1; - free((char *)interpolated); + free(interpolated); } return 0; @@ -1822,7 +1822,7 @@ static int template_dir_cb(const char *key, const char *value, char *path = NULL; FREE_AND_NULL(data->path); - if (!git_config_pathname((const char **)&path, key, value)) + if (!git_config_pathname(&path, key, value)) data->path = path ? path : xstrdup(value); } From patchwork Mon May 27 11:46:20 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675093 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 40A5813A3EF for ; Mon, 27 May 2024 11:46:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810386; cv=none; b=pmyyBDo+CrJufiNC51Pigns2997+L/kzpCMq1F5qCxs9EailqWzhd9kYlKb9AB59tzA+ir7+hVa4Di9kfWKfhEwmZM+kMa+H1X5DdcKwwa8bD4tjTu26DwVlEw4XpDOQIS2WIY/ew1byabYGfSX68Syu6unVb8EnuS0JVl5Tq3Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810386; c=relaxed/simple; bh=IPKzTR3RZuOFOq1tOt6lH3EazSlyNP2lidJIBoRVG6c=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=EOPxUc5mBsjMTa3oaJxaidKA52awg6NxxfbWVDQ/R3E80we52ouQPSVDQr0wBz8AfhYEXcda+voSNjqbY2RNtUqxOfKAwc5AUNsFazK5GpauxuCmd6Jl3PvUWh4IYJNQMhoPLpJpivip2dVpPApzEMCzszaXz9isdOQ34ct9EbU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=DS7f1xwC; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=g1AvKg+7; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="DS7f1xwC"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="g1AvKg+7" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfout.west.internal (Postfix) with ESMTP id 5FDFB1C000F5; Mon, 27 May 2024 07:46:24 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 27 May 2024 07:46:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810384; x=1716896784; bh=yixZoB7gM6 J56z3hBunB92hAaEqzE2n0rF+bucD87Zc=; b=DS7f1xwC1vgdKG8CPILesIfQL1 sLiDNgMYino0XCVV9SjeHnXIiJ80Fi5UNDPDKgbphdXlhLLplFVjSwfQAlOBk00P PpyPqCuNqM9EQUTNxxzEpjOFRtnMg0ICda7IXsEX4ec2vG0HlkOZdPXpva37dETP NskD5lQ5AI8FU9xXjtxg2aADBVUqn5JMywbd4cSlIJRoy5E1iNsrlCAj91l5M6bo 4/Jm1PbvwbWr9yIK72wQWJMEHw5EhmPDPTF8Gm4PV+bXwZlGHYNTiBje6dkPkoF1 vXav8NN+MdoRP4Z9a0XdjslZJi3U2vavfampCosLp6pxvrpXgXlOVKvaRbLg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810384; x=1716896784; bh=yixZoB7gM6J56z3hBunB92hAaEqz E2n0rF+bucD87Zc=; b=g1AvKg+7jCbkaW3QW4/S105rzdFaotbOasr3Vi1T9VgX sVZtQGC5crdF18H9b+eT/k6RYetIfSCuWk1NL7blWqHQUXoIcwBy1MS5ruMOKehN sRXN+2dxkWBzM3mzk9LkqopxLlpiON/j0/wfNg0njQRaLUCmFEHUecO31oVvz2fr uYlvCXzhwRzKFCnKVAdawKrwZJGHR38ogIvISX93zgDZpLJ6HLYUYHUd+lsjqI8Y ye2WSsacMZp/uccG2RVVtq2nKGYZEmE4qcNwYAqMgMsKULXhGDdza+styI+4Lv2w fhfmkQhtLM4D6mUYU9396HkEiayp1Dvri3QCKpAwRw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:22 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 19659ec5 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:12 +0000 (UTC) Date: Mon, 27 May 2024 13:46:20 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 08/21] diff: refactor code to clarify memory ownership of prefixes Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The source and destination prefixes are tracked in a `const char *` array, but may at times contain allocated strings. The result is that those strings may be leaking because we never free them. Refactor the code to always store allocated strings in those variables, freeing them as required. This requires us to handle the default values a bit different compared to before. But given that there is only a single callsite where we use the variables to `struct diff_options` it's easy to handle the defaults there. Signed-off-by: Patrick Steinhardt --- diff.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/diff.c b/diff.c index 902df9286a..679ef472f4 100644 --- a/diff.c +++ b/diff.c @@ -62,8 +62,8 @@ static char *diff_order_file_cfg; int diff_auto_refresh_index = 1; static int diff_mnemonic_prefix; static int diff_no_prefix; -static const char *diff_src_prefix = "a/"; -static const char *diff_dst_prefix = "b/"; +static char *diff_src_prefix; +static char *diff_dst_prefix; static int diff_relative; static int diff_stat_name_width; static int diff_stat_graph_width; @@ -411,10 +411,12 @@ int git_diff_ui_config(const char *var, const char *value, return 0; } if (!strcmp(var, "diff.srcprefix")) { - return git_config_string(&diff_src_prefix, var, value); + FREE_AND_NULL(diff_src_prefix); + return git_config_string((const char **) &diff_src_prefix, var, value); } if (!strcmp(var, "diff.dstprefix")) { - return git_config_string(&diff_dst_prefix, var, value); + FREE_AND_NULL(diff_dst_prefix); + return git_config_string((const char **) &diff_dst_prefix, var, value); } if (!strcmp(var, "diff.relative")) { diff_relative = git_config_bool(var, value); @@ -3433,8 +3435,8 @@ void diff_set_noprefix(struct diff_options *options) void diff_set_default_prefix(struct diff_options *options) { - options->a_prefix = diff_src_prefix; - options->b_prefix = diff_dst_prefix; + options->a_prefix = diff_src_prefix ? diff_src_prefix : "a/"; + options->b_prefix = diff_dst_prefix ? diff_dst_prefix : "b/"; } struct userdiff_driver *get_textconv(struct repository *r, @@ -5371,8 +5373,8 @@ static int diff_opt_default_prefix(const struct option *opt, BUG_ON_OPT_NEG(unset); BUG_ON_OPT_ARG(optarg); - diff_src_prefix = "a/"; - diff_dst_prefix = "b/"; + FREE_AND_NULL(diff_src_prefix); + FREE_AND_NULL(diff_dst_prefix); diff_set_default_prefix(options); return 0; } From patchwork Mon May 27 11:46:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675094 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9554C13A3EF for ; Mon, 27 May 2024 11:46:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810393; cv=none; b=VnU3vzD07m/uj6AoQLPhKGxh50AtbEpV73KZf6zeTD5enjAU5q72Qshc25y1HFkuAQNYSWK18pdhcIAzNp64G+qhGjKSM8QdCL5UciKQjdxOmfvSK+Ach9d8uJnod/AoNJcIa4MBqMzbzwJkJEZyJMBz1PXRCbVGOxTMH5b206Q= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810393; c=relaxed/simple; bh=b2gqpt5ZZPejjF47esf1R7c4o9/NG2olCfvAr/79PC4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=NoVmVRJv2CPWAV+Hpv2zF+jInnjqwZA4YJzln9CIrilwi26eli3+8KK3OPJnZx794Pe9z2IcEcZ24mnmNKwFI+9cEdEUZmWeNce50GTeenytPmFHtpqsnLVFNtoVUvPuhh3pPTZUxsfPFMsszcG3miqYF6+N/ZMGJkmQhgZV+Lo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=ppp5OmQa; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=T7VA2Svl; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="ppp5OmQa"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="T7VA2Svl" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfhigh.west.internal (Postfix) with ESMTP id C44601800097; Mon, 27 May 2024 07:46:29 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 27 May 2024 07:46:30 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810389; x=1716896789; bh=7FvUCN62jL DPa60g9XvJcmpiTH53FRhB3035OxJsbmE=; b=ppp5OmQaYH9fIfeRTGgoF96iv6 t0kNpvlsFR6JU78ClDFsZ1TR1rGLq9AD+9JJPAemu54P2H7V0tR6zg0eyFu+pZNF S4zqu0RWz24UlYQi0IC6H4de8SW7AqwU92QtiLc9zpACtdoSYE7tt1jeUz9QeEWk pfZmlEPJRXQP/l6qg/Bs5wTZoloZf/+bPgdC3keyA+er9+xw5j35Dt4sTcJOXvS3 2NqlQNS0Engh+X40HEBPkWFbnx6bS8eSpHanlF87SVnjGxvi8G3hdeCgAKYFxyVB aaxGNca700Z31B7VU9ettmvXjyxY/f4XWaR/JSSQprtKPAJHAcujH6SXA/SQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810389; x=1716896789; bh=7FvUCN62jLDPa60g9XvJcmpiTH53 FRhB3035OxJsbmE=; b=T7VA2SvlFqbUt5wC13MY1iZWAtrY0uQr3AFc2J6E52HQ zSFxwOGsx4XqCSPIDqU7bbsWovydiPXCF6d3KVyXFov3KBUk9k0/l5RSJlpj5RB2 /D5srF1yYkxjsVs7pSc5wQVOcLxN36UvY2v3vNchdMuEXhb6OihuT4E0jnXxofXE lXwjmUkDC44NCq0ADwHVccaUx1gdeJVPIFWhp9WQ02SAQ76dZO1ko4cJvNSd3Op0 HPReO2ORXiHylyRG9LRWUsQ1wi62LXsrBxfQMGq98bPrxYxQliMAUIAe07QslmRR XFSreNDZfUggzLZNUVATh0QvyeYGH6SsVd4MM+A2JA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:28 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 2c440a8b (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:17 +0000 (UTC) Date: Mon, 27 May 2024 13:46:25 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 09/21] convert: refactor code to clarify ownership of check_roundtrip_encoding Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The `check_roundtrip_encoding` variable is tracked in a `const char *` even though it may contain allocated strings at times. The result is that those strings may be leaking because we never free them. Refactor the code to always store allocated strings in this variable. The default value is handled in `check_roundtrip()` now, which is the only user of the variable. Signed-off-by: Patrick Steinhardt --- config.c | 6 ++++-- convert.c | 24 +++++++++++++----------- convert.h | 2 +- environment.c | 2 +- 4 files changed, 19 insertions(+), 15 deletions(-) diff --git a/config.c b/config.c index fb56e11276..f9101045ee 100644 --- a/config.c +++ b/config.c @@ -1564,8 +1564,10 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.checkroundtripencoding")) - return git_config_string(&check_roundtrip_encoding, var, value); + if (!strcmp(var, "core.checkroundtripencoding")) { + FREE_AND_NULL(check_roundtrip_encoding); + return git_config_string((const char **) &check_roundtrip_encoding, var, value); + } if (!strcmp(var, "core.notesref")) { if (!value) diff --git a/convert.c b/convert.c index 35b25eb3cb..03c3c528f9 100644 --- a/convert.c +++ b/convert.c @@ -345,30 +345,32 @@ static int check_roundtrip(const char *enc_name) * space separated encodings (eg. "UTF-16, ASCII, CP1125"). * Search for the given encoding in that string. */ - const char *found = strcasestr(check_roundtrip_encoding, enc_name); + const char *encoding = check_roundtrip_encoding ? + check_roundtrip_encoding : "SHIFT-JIS"; + const char *found = strcasestr(encoding, enc_name); const char *next; int len; if (!found) return 0; next = found + strlen(enc_name); - len = strlen(check_roundtrip_encoding); + len = strlen(encoding); return (found && ( /* - * check that the found encoding is at the - * beginning of check_roundtrip_encoding or - * that it is prefixed with a space or comma + * Check that the found encoding is at the beginning of + * encoding or that it is prefixed with a space or + * comma. */ - found == check_roundtrip_encoding || ( + found == encoding || ( (isspace(found[-1]) || found[-1] == ',') ) ) && ( /* - * check that the found encoding is at the - * end of check_roundtrip_encoding or - * that it is suffixed with a space or comma + * Check that the found encoding is at the end of + * encoding or that it is suffixed with a space + * or comma. */ - next == check_roundtrip_encoding + len || ( - next < check_roundtrip_encoding + len && + next == encoding + len || ( + next < encoding + len && (isspace(next[0]) || next[0] == ',') ) )); diff --git a/convert.h b/convert.h index ab8b4fa68d..d925589444 100644 --- a/convert.h +++ b/convert.h @@ -92,7 +92,7 @@ void convert_attrs(struct index_state *istate, struct conv_attrs *ca, const char *path); extern enum eol core_eol; -extern const char *check_roundtrip_encoding; +extern char *check_roundtrip_encoding; const char *get_cached_convert_stats_ascii(struct index_state *istate, const char *path); const char *get_wt_convert_stats_ascii(const char *path); diff --git a/environment.c b/environment.c index 279ea3fd5e..ab6956559e 100644 --- a/environment.c +++ b/environment.c @@ -64,7 +64,7 @@ char *excludes_file; enum auto_crlf auto_crlf = AUTO_CRLF_FALSE; enum eol core_eol = EOL_UNSET; int global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; -const char *check_roundtrip_encoding = "SHIFT-JIS"; +char *check_roundtrip_encoding; enum branch_track git_branch_track = BRANCH_TRACK_REMOTE; enum rebase_setup_type autorebase = AUTOREBASE_NEVER; enum push_default_type push_default = PUSH_DEFAULT_UNSPECIFIED; From patchwork Mon May 27 11:46:30 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675095 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 3759213A3EF for ; Mon, 27 May 2024 11:46:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810397; cv=none; b=AwXkoA9ddtL7e/Eba+2bkJ6Cvb974MfJoSM3ziBXEIC2hmsVbYzbUJe9RKGvJdeTn5VoAvxc2gBSWcl/O3pnOWK717VxYLlIMcM3SzTMHsx8e4EBdIN7vEUOoii631h37grmLJvDiR9aLKioM84yjZfqV6vBPdc6Omho0xvfnQc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810397; c=relaxed/simple; bh=MtZKOeSfkkqE5jzMTA8+tF8XYVrsnPa2CPsvJQ6HAbg=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=j27RXhKsxZ8z/usF283d8ottY8PRNaXeCBpAoDqk5PETFuHM3NxyM3ImxU1TSjG/6ZMvImHc4l86nB7bNP9h32jd6KLNU/7XwpcOFv54n8BM6K4BnZiL/NvVd/zOrpKvJkMLAFKHfjlkL7PSBJPmi2V7cl1/mgKINyloTzJgeNA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=POHwmE0Z; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=HwIsh4vK; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="POHwmE0Z"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="HwIsh4vK" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfout.west.internal (Postfix) with ESMTP id 294E21C000C8; Mon, 27 May 2024 07:46:34 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 27 May 2024 07:46:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810393; x=1716896793; bh=k/86WhTu5g fAP6H7qFZ5Xj2k2SawwpsUnWSX85669AA=; b=POHwmE0Zpdc1tcru39JKj0h5KG xQvm4kB6K1iIfjcbextl51S2wuuOsegdgBjfGP0IWXtmvr+iRM7uDsNhDB0c+QaV vSpbniySNfAoWqIIhrrxpXrjp6jSaNMWVYJq90uUR0NclGPOV0BDjs27yfbbiocw /50DAfF0v4Ny84dSvTstNsI1on7sx+RANEgQgufTxLKd0op2qM5D9lu2cBLFpxWo v8saU0Ftqo7tEXLSH6KyfB92k0a56W0beDlZYzksK//VgMbA0Gg/QwP9en58L1f8 jYWP5qvZ6HFSf+nt09jdScMbkHJEf4n2OJ6rE6s/KO+zsd92syRwfRXdnWxQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810393; x=1716896793; bh=k/86WhTu5gfAP6H7qFZ5Xj2k2Saw wpsUnWSX85669AA=; b=HwIsh4vKZ1fGjyckVbHiQVUT6yowS1myGMkJ1qdGjtjY wR+upXLdW3tTjYaHd2/z+pIsrLFuBPQ3IHbO3TBnYZPgniktdkRO7pe59Qxo0ThM Ls8OYr2pT2mJ09mNqrGNFY65PbWBI79x3gZAjK2qN6M1g7U8MX+uXgB54DFJ7VGU h0MF4Or8VxZKF2B91+rGWdBRFB9Q7PUgApuUd9Oi2kCd9kODhh8A6iZEQlm+Wv+h tFsic+1bOCCH+me9qNlRRcaWjIXgeOsr382PcFkUDRxFaA0/2pxyiAoUMKPcVBT2 TIjHc1iGtna2g6eRB1QLlmpxlbF4nqR2Sc+9Vmxjlg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepteelteekleeitdevffdvgfffffekueektedutdffleetvdegteffgeeuhfeivddv necuffhomhgrihhnpeguihhffhhophhtrdhnohdpphgvnhguihhnghdrnhhrnecuvehluh hsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhssehpkhhsrdhi mh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:32 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 8ec29b34 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:22 +0000 (UTC) Date: Mon, 27 May 2024 13:46:30 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 10/21] builtin/log: stop using globals for log config Message-ID: <02c5be27be7d6d88bc35970ab1dd80eb9f172c26.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We're using global variables to store the log configuration. Many of these can be set both via the command line and via the config, and depending on how they are being set, they may contain allocated strings. This leads to hard-to-track memory ownership and memory leaks. Refactor the code to instead use a `struct log_config` that is being allocated on the stack. This allows us to more clearly scope the variables, track memory ownership and ultimately release the memory. This also prepares us for a change to `git_config_string()`, which will be adapted to have a `char **` out parameter instead of `const char **`. Signed-off-by: Patrick Steinhardt --- builtin/log.c | 259 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 156 insertions(+), 103 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index a2f5845556..f5da29ee2a 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -48,22 +48,8 @@ #define COVER_FROM_AUTO_MAX_SUBJECT_LEN 100 #define FORMAT_PATCH_NAME_MAX_DEFAULT 64 -/* Set a default date-time format for git log ("log.date" config variable) */ -static const char *default_date_mode = NULL; - -static int default_abbrev_commit; -static int default_show_root = 1; -static int default_follow; -static int default_show_signature; -static int default_encode_email_headers = 1; -static int decoration_style; -static int decoration_given; -static int use_mailmap_config = 1; static unsigned int force_in_body_from; static int stdout_mboxrd; -static const char *fmt_patch_subject_prefix = "PATCH"; -static int fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT; -static const char *fmt_pretty; static int format_no_prefix; static const char * const builtin_log_usage[] = { @@ -111,6 +97,39 @@ static int parse_decoration_style(const char *value) return -1; } +struct log_config { + int default_abbrev_commit; + int default_show_root; + int default_follow; + int default_show_signature; + int default_encode_email_headers; + int decoration_style; + int decoration_given; + int use_mailmap_config; + char *fmt_patch_subject_prefix; + int fmt_patch_name_max; + char *fmt_pretty; + char *default_date_mode; +}; + +static void log_config_init(struct log_config *cfg) +{ + memset(cfg, 0, sizeof(*cfg)); + cfg->default_show_root = 1; + cfg->default_encode_email_headers = 1; + cfg->use_mailmap_config = 1; + cfg->fmt_patch_subject_prefix = xstrdup("PATCH"); + cfg->fmt_patch_name_max = FORMAT_PATCH_NAME_MAX_DEFAULT; + cfg->decoration_style = auto_decoration_style(); +} + +static void log_config_release(struct log_config *cfg) +{ + free(cfg->default_date_mode); + free(cfg->fmt_pretty); + free(cfg->fmt_patch_subject_prefix); +} + static int use_default_decoration_filter = 1; static struct string_list decorate_refs_exclude = STRING_LIST_INIT_NODUP; static struct string_list decorate_refs_exclude_config = STRING_LIST_INIT_NODUP; @@ -127,20 +146,22 @@ static int clear_decorations_callback(const struct option *opt UNUSED, return 0; } -static int decorate_callback(const struct option *opt UNUSED, const char *arg, +static int decorate_callback(const struct option *opt, const char *arg, int unset) { + struct log_config *cfg = opt->value; + if (unset) - decoration_style = 0; + cfg->decoration_style = 0; else if (arg) - decoration_style = parse_decoration_style(arg); + cfg->decoration_style = parse_decoration_style(arg); else - decoration_style = DECORATE_SHORT_REFS; + cfg->decoration_style = DECORATE_SHORT_REFS; - if (decoration_style < 0) + if (cfg->decoration_style < 0) die(_("invalid --decorate option: %s"), arg); - decoration_given = 1; + cfg->decoration_given = 1; return 0; } @@ -160,32 +181,26 @@ static int log_line_range_callback(const struct option *option, const char *arg, return 0; } -static void init_log_defaults(void) +static void cmd_log_init_defaults(struct rev_info *rev, + struct log_config *cfg) { - init_diff_ui_defaults(); - - decoration_style = auto_decoration_style(); -} - -static void cmd_log_init_defaults(struct rev_info *rev) -{ - if (fmt_pretty) - get_commit_format(fmt_pretty, rev); - if (default_follow) + if (cfg->fmt_pretty) + get_commit_format(cfg->fmt_pretty, rev); + if (cfg->default_follow) rev->diffopt.flags.default_follow_renames = 1; rev->verbose_header = 1; init_diffstat_widths(&rev->diffopt); rev->diffopt.flags.recursive = 1; rev->diffopt.flags.allow_textconv = 1; - rev->abbrev_commit = default_abbrev_commit; - rev->show_root_diff = default_show_root; - rev->subject_prefix = fmt_patch_subject_prefix; - rev->patch_name_max = fmt_patch_name_max; - rev->show_signature = default_show_signature; - rev->encode_email_headers = default_encode_email_headers; + rev->abbrev_commit = cfg->default_abbrev_commit; + rev->show_root_diff = cfg->default_show_root; + rev->subject_prefix = cfg->fmt_patch_subject_prefix; + rev->patch_name_max = cfg->fmt_patch_name_max; + rev->show_signature = cfg->default_show_signature; + rev->encode_email_headers = cfg->default_encode_email_headers; - if (default_date_mode) - parse_date_format(default_date_mode, &rev->date_mode); + if (cfg->default_date_mode) + parse_date_format(cfg->default_date_mode, &rev->date_mode); } static void set_default_decoration_filter(struct decoration_filter *decoration_filter) @@ -233,7 +248,8 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f } static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, - struct rev_info *rev, struct setup_revision_opt *opt) + struct rev_info *rev, struct setup_revision_opt *opt, + struct log_config *cfg) { struct userformat_want w; int quiet = 0, source = 0, mailmap; @@ -258,7 +274,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, N_("pattern"), N_("only decorate refs that match ")), OPT_STRING_LIST(0, "decorate-refs-exclude", &decorate_refs_exclude, N_("pattern"), N_("do not decorate refs that match ")), - OPT_CALLBACK_F(0, "decorate", NULL, NULL, N_("decorate options"), + OPT_CALLBACK_F(0, "decorate", cfg, NULL, N_("decorate options"), PARSE_OPT_OPTARG, decorate_callback), OPT_CALLBACK('L', NULL, &line_cb, "range:file", N_("trace the evolution of line range , or function : in "), @@ -269,7 +285,7 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, line_cb.rev = rev; line_cb.prefix = prefix; - mailmap = use_mailmap_config; + mailmap = cfg->use_mailmap_config; argc = parse_options(argc, argv, prefix, builtin_log_options, builtin_log_usage, PARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN_OPT | @@ -314,8 +330,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, * "log --pretty=raw" is special; ignore UI oriented * configuration variables such as decoration. */ - if (!decoration_given) - decoration_style = 0; + if (!cfg->decoration_given) + cfg->decoration_style = 0; if (!rev->abbrev_commit_given) rev->abbrev_commit = 0; } @@ -326,24 +342,24 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, * Disable decoration loading if the format will not * show them anyway. */ - decoration_style = 0; - } else if (!decoration_style) { + cfg->decoration_style = 0; + } else if (!cfg->decoration_style) { /* * If we are going to show them, make sure we do load * them here, but taking care not to override a * specific style set by config or --decorate. */ - decoration_style = DECORATE_SHORT_REFS; + cfg->decoration_style = DECORATE_SHORT_REFS; } } - if (decoration_style || rev->simplify_by_decoration) { + if (cfg->decoration_style || rev->simplify_by_decoration) { set_default_decoration_filter(&decoration_filter); - if (decoration_style) + if (cfg->decoration_style) rev->show_decorations = 1; - load_ref_decorations(&decoration_filter, decoration_style); + load_ref_decorations(&decoration_filter, cfg->decoration_style); } if (rev->line_level_traverse) @@ -353,16 +369,11 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, } static void cmd_log_init(int argc, const char **argv, const char *prefix, - struct rev_info *rev, struct setup_revision_opt *opt) + struct rev_info *rev, struct setup_revision_opt *opt, + struct log_config *cfg) { - cmd_log_init_defaults(rev); - cmd_log_init_finish(argc, argv, prefix, rev, opt); -} - -static int cmd_log_deinit(int ret, struct rev_info *rev) -{ - release_revisions(rev); - return ret; + cmd_log_init_defaults(rev, cfg); + cmd_log_init_finish(argc, argv, prefix, rev, opt, cfg); } /* @@ -566,30 +577,37 @@ static int cmd_log_walk(struct rev_info *rev) static int git_log_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { + struct log_config *cfg = cb; const char *slot_name; - if (!strcmp(var, "format.pretty")) - return git_config_string(&fmt_pretty, var, value); - if (!strcmp(var, "format.subjectprefix")) - return git_config_string(&fmt_patch_subject_prefix, var, value); + if (!strcmp(var, "format.pretty")) { + FREE_AND_NULL(cfg->fmt_pretty); + return git_config_string((const char **) &cfg->fmt_pretty, var, value); + } + if (!strcmp(var, "format.subjectprefix")) { + FREE_AND_NULL(cfg->fmt_patch_subject_prefix); + return git_config_string((const char **) &cfg->fmt_patch_subject_prefix, var, value); + } if (!strcmp(var, "format.filenamemaxlength")) { - fmt_patch_name_max = git_config_int(var, value, ctx->kvi); + cfg->fmt_patch_name_max = git_config_int(var, value, ctx->kvi); return 0; } if (!strcmp(var, "format.encodeemailheaders")) { - default_encode_email_headers = git_config_bool(var, value); + cfg->default_encode_email_headers = git_config_bool(var, value); return 0; } if (!strcmp(var, "log.abbrevcommit")) { - default_abbrev_commit = git_config_bool(var, value); + cfg->default_abbrev_commit = git_config_bool(var, value); return 0; } - if (!strcmp(var, "log.date")) - return git_config_string(&default_date_mode, var, value); + if (!strcmp(var, "log.date")) { + FREE_AND_NULL(cfg->default_date_mode); + return git_config_string((const char **) &cfg->default_date_mode, var, value); + } if (!strcmp(var, "log.decorate")) { - decoration_style = parse_decoration_style(value); - if (decoration_style < 0) - decoration_style = 0; /* maybe warn? */ + cfg->decoration_style = parse_decoration_style(value); + if (cfg->decoration_style < 0) + cfg->decoration_style = 0; /* maybe warn? */ return 0; } if (!strcmp(var, "log.diffmerges")) { @@ -598,21 +616,21 @@ static int git_log_config(const char *var, const char *value, return diff_merges_config(value); } if (!strcmp(var, "log.showroot")) { - default_show_root = git_config_bool(var, value); + cfg->default_show_root = git_config_bool(var, value); return 0; } if (!strcmp(var, "log.follow")) { - default_follow = git_config_bool(var, value); + cfg->default_follow = git_config_bool(var, value); return 0; } if (skip_prefix(var, "color.decorate.", &slot_name)) return parse_decorate_color_config(var, slot_name, value); if (!strcmp(var, "log.mailmap")) { - use_mailmap_config = git_config_bool(var, value); + cfg->use_mailmap_config = git_config_bool(var, value); return 0; } if (!strcmp(var, "log.showsignature")) { - default_show_signature = git_config_bool(var, value); + cfg->default_show_signature = git_config_bool(var, value); return 0; } @@ -621,11 +639,14 @@ static int git_log_config(const char *var, const char *value, int cmd_whatchanged(int argc, const char **argv, const char *prefix) { + struct log_config cfg; struct rev_info rev; struct setup_revision_opt opt; + int ret; - init_log_defaults(); - git_config(git_log_config, NULL); + log_config_init(&cfg); + init_diff_ui_defaults(); + git_config(git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); git_config(grep_config, &rev.grep_filter); @@ -635,10 +656,15 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) memset(&opt, 0, sizeof(opt)); opt.def = "HEAD"; opt.revarg_opt = REVARG_COMMITTISH; - cmd_log_init(argc, argv, prefix, &rev, &opt); + cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; - return cmd_log_deinit(cmd_log_walk(&rev), &rev); + + ret = cmd_log_walk(&rev); + + release_revisions(&rev); + log_config_release(&cfg); + return ret; } static void show_tagger(const char *buf, struct rev_info *rev) @@ -733,14 +759,16 @@ static void show_setup_revisions_tweak(struct rev_info *rev) int cmd_show(int argc, const char **argv, const char *prefix) { + struct log_config cfg; struct rev_info rev; unsigned int i; struct setup_revision_opt opt; struct pathspec match_all; int ret = 0; - init_log_defaults(); - git_config(git_log_config, NULL); + log_config_init(&cfg); + init_diff_ui_defaults(); + git_config(git_log_config, &cfg); if (the_repository->gitdir) { prepare_repo_settings(the_repository); @@ -759,10 +787,14 @@ int cmd_show(int argc, const char **argv, const char *prefix) memset(&opt, 0, sizeof(opt)); opt.def = "HEAD"; opt.tweak = show_setup_revisions_tweak; - cmd_log_init(argc, argv, prefix, &rev, &opt); + cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); - if (!rev.no_walk) - return cmd_log_deinit(cmd_log_walk(&rev), &rev); + if (!rev.no_walk) { + ret = cmd_log_walk(&rev); + release_revisions(&rev); + log_config_release(&cfg); + return ret; + } rev.diffopt.no_free = 1; for (i = 0; i < rev.pending.nr && !ret; i++) { @@ -832,8 +864,10 @@ int cmd_show(int argc, const char **argv, const char *prefix) rev.diffopt.no_free = 0; diff_free(&rev.diffopt); + release_revisions(&rev); + log_config_release(&cfg); - return cmd_log_deinit(ret, &rev); + return ret; } /* @@ -841,11 +875,14 @@ int cmd_show(int argc, const char **argv, const char *prefix) */ int cmd_log_reflog(int argc, const char **argv, const char *prefix) { + struct log_config cfg; struct rev_info rev; struct setup_revision_opt opt; + int ret; - init_log_defaults(); - git_config(git_log_config, NULL); + log_config_init(&cfg); + init_diff_ui_defaults(); + git_config(git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); init_reflog_walk(&rev.reflog_info); @@ -854,14 +891,18 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) rev.verbose_header = 1; memset(&opt, 0, sizeof(opt)); opt.def = "HEAD"; - cmd_log_init_defaults(&rev); + cmd_log_init_defaults(&rev, &cfg); rev.abbrev_commit = 1; rev.commit_format = CMIT_FMT_ONELINE; rev.use_terminator = 1; rev.always_show_header = 1; - cmd_log_init_finish(argc, argv, prefix, &rev, &opt); + cmd_log_init_finish(argc, argv, prefix, &rev, &opt, &cfg); + + ret = cmd_log_walk(&rev); - return cmd_log_deinit(cmd_log_walk(&rev), &rev); + release_revisions(&rev); + log_config_release(&cfg); + return ret; } static void log_setup_revisions_tweak(struct rev_info *rev) @@ -876,11 +917,14 @@ static void log_setup_revisions_tweak(struct rev_info *rev) int cmd_log(int argc, const char **argv, const char *prefix) { + struct log_config cfg; struct rev_info rev; struct setup_revision_opt opt; + int ret; - init_log_defaults(); - git_config(git_log_config, NULL); + log_config_init(&cfg); + init_diff_ui_defaults(); + git_config(git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); git_config(grep_config, &rev.grep_filter); @@ -890,8 +934,13 @@ int cmd_log(int argc, const char **argv, const char *prefix) opt.def = "HEAD"; opt.revarg_opt = REVARG_COMMITTISH; opt.tweak = log_setup_revisions_tweak; - cmd_log_init(argc, argv, prefix, &rev, &opt); - return cmd_log_deinit(cmd_log_walk(&rev), &rev); + cmd_log_init(argc, argv, prefix, &rev, &opt, &cfg); + + ret = cmd_log_walk(&rev); + + release_revisions(&rev); + log_config_release(&cfg); + return ret; } /* format-patch */ @@ -1884,6 +1933,7 @@ static void infer_range_diff_ranges(struct strbuf *r1, int cmd_format_patch(int argc, const char **argv, const char *prefix) { + struct log_config cfg; struct commit *commit; struct commit **list = NULL; struct rev_info rev; @@ -1943,7 +1993,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("start numbering patches at instead of 1")), OPT_STRING('v', "reroll-count", &reroll_count, N_("reroll-count"), N_("mark the series as Nth re-roll")), - OPT_INTEGER(0, "filename-max-length", &fmt_patch_name_max, + OPT_INTEGER(0, "filename-max-length", &cfg.fmt_patch_name_max, N_("max length of output filename")), OPT_CALLBACK_F(0, "rfc", &rfc, N_("rfc"), N_("add (default 'RFC') before 'PATCH'"), @@ -2017,16 +2067,17 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) extra_to.strdup_strings = 1; extra_cc.strdup_strings = 1; - init_log_defaults(); + log_config_init(&cfg); + init_diff_ui_defaults(); init_display_notes(¬es_opt); - git_config(git_format_config, NULL); + git_config(git_format_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); git_config(grep_config, &rev.grep_filter); rev.show_notes = show_notes; memcpy(&rev.notes_opt, ¬es_opt, sizeof(notes_opt)); rev.commit_format = CMIT_FMT_EMAIL; - rev.encode_email_headers = default_encode_email_headers; + rev.encode_email_headers = cfg.default_encode_email_headers; rev.expand_tabs_in_log_default = 0; rev.verbose_header = 1; rev.diff = 1; @@ -2037,7 +2088,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) s_r_opt.def = "HEAD"; s_r_opt.revarg_opt = REVARG_COMMITTISH; - strbuf_addstr(&sprefix, fmt_patch_subject_prefix); + strbuf_addstr(&sprefix, cfg.fmt_patch_subject_prefix); if (format_no_prefix) diff_set_noprefix(&rev.diffopt); @@ -2059,8 +2110,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.force_in_body_from = force_in_body_from; /* Make sure "0000-$sub.patch" gives non-negative length for $sub */ - if (fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix)) - fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix); + if (cfg.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix)) + cfg.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix); if (cover_from_description_arg) cover_from_description_mode = parse_cover_from_description(cover_from_description_arg); @@ -2156,7 +2207,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.always_show_header = 1; rev.zero_commit = zero_commit; - rev.patch_name_max = fmt_patch_name_max; + rev.patch_name_max = cfg.fmt_patch_name_max; if (!rev.diffopt.flags.text && !no_binary_diff) rev.diffopt.flags.binary = 1; @@ -2450,7 +2501,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (rev.ref_message_ids) string_list_clear(rev.ref_message_ids, 0); free(rev.ref_message_ids); - return cmd_log_deinit(0, &rev); + release_revisions(&rev); + log_config_release(&cfg); + return 0; } static int add_pending_commit(const char *arg, struct rev_info *revs, int flags) From patchwork Mon May 27 11:46:34 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675096 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C4BAF15DBCB for ; Mon, 27 May 2024 11:46:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810403; cv=none; b=MKsEQnGI3bR+QSR9P0k9B3acSABAYlAHyYTIuJSWchTLP1eTx0q7VSCHzcPYeKtfC1AaaFBnQEU2dkRCim8q6X3jecrKVWGtiZfcNhUL97Exucvfr2tHwotbW515ndfn2qkQsj2KhMcj7VHl6KJAoY5LkLRfmkCCqxh5v0I0ovQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810403; c=relaxed/simple; bh=+/ecPN7RySnlxogbxaYeLPM67IVKX6UP7jlRL3n/tII=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=r1+P15nkVrDKlbu052eP6tgP6SQE2kmW6jxmsSh2kQ8YmUiXcvscBfUyP7G0VYB+BjNRDwNX7tZF0wddd4WWSRSQPBlQrRiaUSBnO6QCqD7kEMyNq3s0MxVlj4FKIaGdPcM5SI5Wl10caT/APxk5Z+wKMQtoUjOn+HZle9D6q/U= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=AJwJNjXI; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=hJKJnqet; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="AJwJNjXI"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="hJKJnqet" Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfhigh.west.internal (Postfix) with ESMTP id A616E18000B6; Mon, 27 May 2024 07:46:39 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Mon, 27 May 2024 07:46:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810399; x=1716896799; bh=HlAb04M8S6 5okCCk6ktoQU7j9vaWH11VO9R/5jiU66E=; b=AJwJNjXIYv5V4nZ8TIsVA8soLh EfS0GIWYI3jP6hI3tbdCFeFJv8uCg2Q2Aj2ltmP+bNCcZVYPqMgA27pNvYr0KdzN 2UQF96NPM+0nElXYNQVwImmM3zYMA/ST8ptUH9QDTnD0mkLxzjmly24bn2NqPq0S xnbCJRrzZrBvbIlmP58W3KCymIJ6vrwTRmvC9qefUXkO37mMVzyJ7ocIULn0F2nQ L6w2INexknoEsxCe+IxE2xLzDUpgRhg2X43Mr0FnSgv3vlMrTfFfPvpvGbwozUl1 lskfEsUyxsxeia2qA9wZTMZ/14mnFpV7eIP3JT/9uPSXOLYfPTIm9P6hm71Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810399; x=1716896799; bh=HlAb04M8S65okCCk6ktoQU7j9vaW H11VO9R/5jiU66E=; b=hJKJnqetVkUDmBhuMCXW7+uUgypW5svgQ9Cc2VM/JgF2 CtB4dNvyopf9b+eO/btxn56ciEEJO1bM7FAHYoK28dMJ5OTd1Ln+FhoP+Yqtc4WD tgLf+pSeUGoUFmRiYCHDqieIyrAMx/uR2jcg/eJao7dyoehmXHHgQp/MuWSHpndK 7O98e2sOJpJHI1/7aGzC9G+siigiqTDKAjIgrE3lsdC7AZhfhTAVwLmJFJFHmvad +ZmpItecfl6O+SZPPux9pVZEfXu0SXoIB4xEU3iQ+giAVdgRL4ukOEkizDYFSMQm pUIK+qoDM9J9TF3mr50ilDhdflbzjoa66xjKL5UcBw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueegheeuheejuefgjeejfffgkeeugffgudfhudejkeevjefhkeefueeggfegueet necuffhomhgrihhnpegvgihtrhgrpghhughrrdhnrhdpvgigthhrrggpthhordhnrhdpvg igthhrrggptggtrdhnrhenucevlhhushhtvghrufhiiigvpedtnecurfgrrhgrmhepmhgr ihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:37 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id efe6760d (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:27 +0000 (UTC) Date: Mon, 27 May 2024 13:46:34 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 11/21] builtin/log: stop using globals for format config Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: This commit does the exact same as the preceding commit, only for the format configuration instead of the log configuration. Signed-off-by: Patrick Steinhardt --- builtin/log.c | 467 ++++++++++++++++++++++++++++---------------------- 1 file changed, 265 insertions(+), 202 deletions(-) diff --git a/builtin/log.c b/builtin/log.c index f5da29ee2a..890bf0c425 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -945,36 +945,6 @@ int cmd_log(int argc, const char **argv, const char *prefix) /* format-patch */ -static const char *fmt_patch_suffix = ".patch"; -static int numbered = 0; -static int auto_number = 1; - -static char *default_attach = NULL; - -static struct string_list extra_hdr = STRING_LIST_INIT_NODUP; -static struct string_list extra_to = STRING_LIST_INIT_NODUP; -static struct string_list extra_cc = STRING_LIST_INIT_NODUP; - -static void add_header(const char *value) -{ - struct string_list_item *item; - int len = strlen(value); - while (len && value[len - 1] == '\n') - len--; - - if (!strncasecmp(value, "to: ", 4)) { - item = string_list_append(&extra_to, value + 4); - len -= 4; - } else if (!strncasecmp(value, "cc: ", 4)) { - item = string_list_append(&extra_cc, value + 4); - len -= 4; - } else { - item = string_list_append(&extra_hdr, value); - } - - item->string[len] = '\0'; -} - enum cover_setting { COVER_UNSET, COVER_OFF, @@ -1001,17 +971,61 @@ enum auto_base_setting { AUTO_BASE_WHEN_ABLE }; -static enum thread_level thread; -static int do_signoff; -static enum auto_base_setting auto_base; -static char *from; -static const char *signature = git_version_string; -static char *signature_file; -static enum cover_setting config_cover_letter; -static const char *config_output_directory; -static enum cover_from_description cover_from_description_mode = COVER_FROM_MESSAGE; -static int show_notes; -static struct display_notes_opt notes_opt; +struct format_config { + struct log_config log; + enum thread_level thread; + int do_signoff; + enum auto_base_setting auto_base; + char *base_commit; + char *from; + char *signature; + char *signature_file; + enum cover_setting config_cover_letter; + char *config_output_directory; + enum cover_from_description cover_from_description_mode; + int show_notes; + struct display_notes_opt notes_opt; + int numbered_cmdline_opt; + int numbered; + int auto_number; + char *default_attach; + struct string_list extra_hdr; + struct string_list extra_to; + struct string_list extra_cc; + int keep_subject; + int subject_prefix; + struct strbuf sprefix; + char *fmt_patch_suffix; +}; + +static void format_config_init(struct format_config *cfg) +{ + memset(cfg, 0, sizeof(*cfg)); + log_config_init(&cfg->log); + cfg->cover_from_description_mode = COVER_FROM_MESSAGE; + cfg->auto_number = 1; + string_list_init_dup(&cfg->extra_hdr); + string_list_init_dup(&cfg->extra_to); + string_list_init_dup(&cfg->extra_cc); + strbuf_init(&cfg->sprefix, 0); + cfg->fmt_patch_suffix = xstrdup(".patch"); +} + +static void format_config_release(struct format_config *cfg) +{ + log_config_release(&cfg->log); + free(cfg->base_commit); + free(cfg->from); + free(cfg->signature); + free(cfg->signature_file); + free(cfg->config_output_directory); + free(cfg->default_attach); + string_list_clear(&cfg->extra_hdr, 0); + string_list_clear(&cfg->extra_to, 0); + string_list_clear(&cfg->extra_cc, 0); + strbuf_release(&cfg->sprefix); + free(cfg->fmt_patch_suffix); +} static enum cover_from_description parse_cover_from_description(const char *arg) { @@ -1029,27 +1043,51 @@ static enum cover_from_description parse_cover_from_description(const char *arg) die(_("%s: invalid cover from description mode"), arg); } +static void add_header(struct format_config *cfg, const char *value) +{ + struct string_list_item *item; + int len = strlen(value); + while (len && value[len - 1] == '\n') + len--; + + if (!strncasecmp(value, "to: ", 4)) { + item = string_list_append(&cfg->extra_to, value + 4); + len -= 4; + } else if (!strncasecmp(value, "cc: ", 4)) { + item = string_list_append(&cfg->extra_cc, value + 4); + len -= 4; + } else { + item = string_list_append(&cfg->extra_hdr, value); + } + + item->string[len] = '\0'; +} + static int git_format_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { + struct format_config *cfg = cb; + if (!strcmp(var, "format.headers")) { if (!value) die(_("format.headers without value")); - add_header(value); + add_header(cfg, value); return 0; } - if (!strcmp(var, "format.suffix")) - return git_config_string(&fmt_patch_suffix, var, value); + if (!strcmp(var, "format.suffix")) { + FREE_AND_NULL(cfg->fmt_patch_suffix); + return git_config_string((const char **) &cfg->fmt_patch_suffix, var, value); + } if (!strcmp(var, "format.to")) { if (!value) return config_error_nonbool(var); - string_list_append(&extra_to, value); + string_list_append(&cfg->extra_to, value); return 0; } if (!strcmp(var, "format.cc")) { if (!value) return config_error_nonbool(var); - string_list_append(&extra_cc, value); + string_list_append(&cfg->extra_cc, value); return 0; } if (!strcmp(var, "diff.color") || !strcmp(var, "color.diff") || @@ -1058,69 +1096,76 @@ static int git_format_config(const char *var, const char *value, } if (!strcmp(var, "format.numbered")) { if (value && !strcasecmp(value, "auto")) { - auto_number = 1; + cfg->auto_number = 1; return 0; } - numbered = git_config_bool(var, value); - auto_number = auto_number && numbered; + cfg->numbered = git_config_bool(var, value); + cfg->auto_number = cfg->auto_number && cfg->numbered; return 0; } if (!strcmp(var, "format.attach")) { - if (value && *value) - default_attach = xstrdup(value); - else if (value && !*value) - FREE_AND_NULL(default_attach); - else - default_attach = xstrdup(git_version_string); + if (value && *value) { + FREE_AND_NULL(cfg->default_attach); + cfg->default_attach = xstrdup(value); + } else if (value && !*value) { + FREE_AND_NULL(cfg->default_attach); + } else { + FREE_AND_NULL(cfg->default_attach); + cfg->default_attach = xstrdup(git_version_string); + } return 0; } if (!strcmp(var, "format.thread")) { if (value && !strcasecmp(value, "deep")) { - thread = THREAD_DEEP; + cfg->thread = THREAD_DEEP; return 0; } if (value && !strcasecmp(value, "shallow")) { - thread = THREAD_SHALLOW; + cfg->thread = THREAD_SHALLOW; return 0; } - thread = git_config_bool(var, value) ? THREAD_SHALLOW : THREAD_UNSET; + cfg->thread = git_config_bool(var, value) ? THREAD_SHALLOW : THREAD_UNSET; return 0; } if (!strcmp(var, "format.signoff")) { - do_signoff = git_config_bool(var, value); + cfg->do_signoff = git_config_bool(var, value); return 0; } - if (!strcmp(var, "format.signature")) - return git_config_string(&signature, var, value); - if (!strcmp(var, "format.signaturefile")) - return git_config_pathname(&signature_file, var, value); + if (!strcmp(var, "format.signature")) { + FREE_AND_NULL(cfg->signature); + return git_config_string((const char **) &cfg->signature, var, value); + } + if (!strcmp(var, "format.signaturefile")) { + FREE_AND_NULL(cfg->signature_file); + return git_config_pathname(&cfg->signature_file, var, value); + } if (!strcmp(var, "format.coverletter")) { if (value && !strcasecmp(value, "auto")) { - config_cover_letter = COVER_AUTO; + cfg->config_cover_letter = COVER_AUTO; return 0; } - config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF; + cfg->config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF; return 0; } - if (!strcmp(var, "format.outputdirectory")) - return git_config_string(&config_output_directory, var, value); + if (!strcmp(var, "format.outputdirectory")) { + FREE_AND_NULL(cfg->config_output_directory); + return git_config_string((const char **) &cfg->config_output_directory, var, value); + } if (!strcmp(var, "format.useautobase")) { if (value && !strcasecmp(value, "whenAble")) { - auto_base = AUTO_BASE_WHEN_ABLE; + cfg->auto_base = AUTO_BASE_WHEN_ABLE; return 0; } - auto_base = git_config_bool(var, value) ? AUTO_BASE_ALWAYS : AUTO_BASE_NEVER; + cfg->auto_base = git_config_bool(var, value) ? AUTO_BASE_ALWAYS : AUTO_BASE_NEVER; return 0; } if (!strcmp(var, "format.from")) { int b = git_parse_maybe_bool(value); - free(from); + FREE_AND_NULL(cfg->from); if (b < 0) - from = xstrdup(value); + cfg->from = xstrdup(value); else if (b) - from = xstrdup(git_committer_info(IDENT_NO_DATE)); - else - from = NULL; + cfg->from = xstrdup(git_committer_info(IDENT_NO_DATE)); return 0; } if (!strcmp(var, "format.forceinbodyfrom")) { @@ -1130,15 +1175,15 @@ static int git_format_config(const char *var, const char *value, if (!strcmp(var, "format.notes")) { int b = git_parse_maybe_bool(value); if (b < 0) - enable_ref_display_notes(¬es_opt, &show_notes, value); + enable_ref_display_notes(&cfg->notes_opt, &cfg->show_notes, value); else if (b) - enable_default_display_notes(¬es_opt, &show_notes); + enable_default_display_notes(&cfg->notes_opt, &cfg->show_notes); else - disable_display_notes(¬es_opt, &show_notes); + disable_display_notes(&cfg->notes_opt, &cfg->show_notes); return 0; } if (!strcmp(var, "format.coverfromdescription")) { - cover_from_description_mode = parse_cover_from_description(value); + cfg->cover_from_description_mode = parse_cover_from_description(value); return 0; } if (!strcmp(var, "format.mboxrd")) { @@ -1159,7 +1204,7 @@ static int git_format_config(const char *var, const char *value, if (!strcmp(var, "diff.noprefix")) return 0; - return git_log_config(var, value, ctx, cb); + return git_log_config(var, value, ctx, &cfg->log); } static const char *output_directory = NULL; @@ -1247,7 +1292,7 @@ static void gen_message_id(struct rev_info *info, char *base) info->message_id = strbuf_detach(&buf, NULL); } -static void print_signature(FILE *file) +static void print_signature(const char *signature, FILE *file) { if (!signature || !*signature) return; @@ -1317,14 +1362,15 @@ static void prepare_cover_text(struct pretty_print_context *pp, const char *branch_name, struct strbuf *sb, const char *encoding, - int need_8bit_cte) + int need_8bit_cte, + const struct format_config *cfg) { const char *subject = "*** SUBJECT HERE ***"; const char *body = "*** BLURB HERE ***"; struct strbuf description_sb = STRBUF_INIT; struct strbuf subject_sb = STRBUF_INIT; - if (cover_from_description_mode == COVER_FROM_NONE) + if (cfg->cover_from_description_mode == COVER_FROM_NONE) goto do_pp; if (description_file && *description_file) @@ -1334,13 +1380,13 @@ static void prepare_cover_text(struct pretty_print_context *pp, if (!description_sb.len) goto do_pp; - if (cover_from_description_mode == COVER_FROM_SUBJECT || - cover_from_description_mode == COVER_FROM_AUTO) + if (cfg->cover_from_description_mode == COVER_FROM_SUBJECT || + cfg->cover_from_description_mode == COVER_FROM_AUTO) body = format_subject(&subject_sb, description_sb.buf, " "); - if (cover_from_description_mode == COVER_FROM_MESSAGE || - (cover_from_description_mode == COVER_FROM_AUTO && - subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN)) + if (cfg->cover_from_description_mode == COVER_FROM_MESSAGE || + (cfg->cover_from_description_mode == COVER_FROM_AUTO && + subject_sb.len > COVER_FROM_AUTO_MAX_SUBJECT_LEN)) body = description_sb.buf; else subject = subject_sb.buf; @@ -1377,7 +1423,8 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file, int nr, struct commit **list, const char *description_file, const char *branch_name, - int quiet) + int quiet, + const struct format_config *cfg) { const char *committer; struct shortlog log; @@ -1416,7 +1463,7 @@ static void make_cover_letter(struct rev_info *rev, int use_separate_file, pp.encode_email_headers = rev->encode_email_headers; pp_user_info(&pp, NULL, &sb, committer, encoding); prepare_cover_text(&pp, description_file, branch_name, &sb, - encoding, need_8bit_cte); + encoding, need_8bit_cte, cfg); fprintf(rev->diffopt.file, "%s\n", sb.buf); free(pp.after_subject); @@ -1517,29 +1564,30 @@ static const char * const builtin_format_patch_usage[] = { NULL }; -static int keep_subject = 0; +struct keep_callback_data { + struct format_config *cfg; + struct rev_info *revs; +}; static int keep_callback(const struct option *opt, const char *arg, int unset) { + struct keep_callback_data *data = opt->value; BUG_ON_OPT_NEG(unset); BUG_ON_OPT_ARG(arg); - ((struct rev_info *)opt->value)->total = -1; - keep_subject = 1; + data->revs->total = -1; + data->cfg->keep_subject = 1; return 0; } -static int subject_prefix = 0; - static int subject_prefix_callback(const struct option *opt, const char *arg, int unset) { - struct strbuf *sprefix; + struct format_config *cfg = opt->value; BUG_ON_OPT_NEG(unset); - sprefix = opt->value; - subject_prefix = 1; - strbuf_reset(sprefix); - strbuf_addstr(sprefix, arg); + cfg->subject_prefix = 1; + strbuf_reset(&cfg->sprefix); + strbuf_addstr(&cfg->sprefix, arg); return 0; } @@ -1556,15 +1604,14 @@ static int rfc_callback(const struct option *opt, const char *arg, return 0; } -static int numbered_cmdline_opt = 0; - static int numbered_callback(const struct option *opt, const char *arg, int unset) { + struct format_config *cfg = opt->value; BUG_ON_OPT_ARG(arg); - *(int *)opt->value = numbered_cmdline_opt = unset ? 0 : 1; + cfg->numbered = cfg->numbered_cmdline_opt = unset ? 0 : 1; if (unset) - auto_number = 0; + cfg->auto_number = 0; return 0; } @@ -1588,13 +1635,14 @@ static int output_directory_callback(const struct option *opt, const char *arg, static int thread_callback(const struct option *opt, const char *arg, int unset) { - enum thread_level *thread = (enum thread_level *)opt->value; + struct format_config *cfg = opt->value; + if (unset) - *thread = THREAD_UNSET; + cfg->thread = THREAD_UNSET; else if (!arg || !strcmp(arg, "shallow")) - *thread = THREAD_SHALLOW; + cfg->thread = THREAD_SHALLOW; else if (!strcmp(arg, "deep")) - *thread = THREAD_DEEP; + cfg->thread = THREAD_DEEP; /* * Please update _git_formatpatch() in git-completion.bash * when you add new options. @@ -1630,15 +1678,17 @@ static int inline_callback(const struct option *opt, const char *arg, int unset) return 0; } -static int header_callback(const struct option *opt UNUSED, const char *arg, +static int header_callback(const struct option *opt, const char *arg, int unset) { + struct format_config *cfg = opt->value; + if (unset) { - string_list_clear(&extra_hdr, 0); - string_list_clear(&extra_to, 0); - string_list_clear(&extra_cc, 0); + string_list_clear(&cfg->extra_hdr, 0); + string_list_clear(&cfg->extra_to, 0); + string_list_clear(&cfg->extra_cc, 0); } else { - add_header(arg); + add_header(cfg, arg); } return 0; } @@ -1660,17 +1710,17 @@ static int from_callback(const struct option *opt, const char *arg, int unset) static int base_callback(const struct option *opt, const char *arg, int unset) { - const char **base_commit = opt->value; + struct format_config *cfg = opt->value; if (unset) { - auto_base = AUTO_BASE_NEVER; - *base_commit = NULL; + cfg->auto_base = AUTO_BASE_NEVER; + FREE_AND_NULL(cfg->base_commit); } else if (!strcmp(arg, "auto")) { - auto_base = AUTO_BASE_ALWAYS; - *base_commit = NULL; + cfg->auto_base = AUTO_BASE_ALWAYS; + FREE_AND_NULL(cfg->base_commit); } else { - auto_base = AUTO_BASE_NEVER; - *base_commit = arg; + cfg->auto_base = AUTO_BASE_NEVER; + cfg->base_commit = xstrdup(arg); } return 0; } @@ -1681,7 +1731,7 @@ struct base_tree_info { struct object_id *patch_id; }; -static struct commit *get_base_commit(const char *base_commit, +static struct commit *get_base_commit(const struct format_config *cfg, struct commit **list, int total) { @@ -1689,9 +1739,9 @@ static struct commit *get_base_commit(const char *base_commit, struct commit **rev; int i = 0, rev_nr = 0, auto_select, die_on_failure, ret; - switch (auto_base) { + switch (cfg->auto_base) { case AUTO_BASE_NEVER: - if (base_commit) { + if (cfg->base_commit) { auto_select = 0; die_on_failure = 1; } else { @@ -1701,11 +1751,11 @@ static struct commit *get_base_commit(const char *base_commit, break; case AUTO_BASE_ALWAYS: case AUTO_BASE_WHEN_ABLE: - if (base_commit) { + if (cfg->base_commit) { BUG("requested automatic base selection but a commit was provided"); } else { auto_select = 1; - die_on_failure = auto_base == AUTO_BASE_ALWAYS; + die_on_failure = cfg->auto_base == AUTO_BASE_ALWAYS; } break; default: @@ -1713,9 +1763,9 @@ static struct commit *get_base_commit(const char *base_commit, } if (!auto_select) { - base = lookup_commit_reference_by_name(base_commit); + base = lookup_commit_reference_by_name(cfg->base_commit); if (!base) - die(_("unknown commit %s"), base_commit); + die(_("unknown commit %s"), cfg->base_commit); } else { struct branch *curr_branch = branch_get(NULL); const char *upstream = branch_get_upstream(curr_branch, NULL); @@ -1933,7 +1983,7 @@ static void infer_range_diff_ranges(struct strbuf *r1, int cmd_format_patch(int argc, const char **argv, const char *prefix) { - struct log_config cfg; + struct format_config cfg; struct commit *commit; struct commit **list = NULL; struct rev_info rev; @@ -1958,7 +2008,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) char *cover_from_description_arg = NULL; char *description_file = NULL; char *branch_name = NULL; - char *base_commit = NULL; struct base_tree_info bases; struct commit *base; int show_progress = 0; @@ -1969,18 +2018,24 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) struct strbuf rdiff1 = STRBUF_INIT; struct strbuf rdiff2 = STRBUF_INIT; struct strbuf rdiff_title = STRBUF_INIT; - struct strbuf sprefix = STRBUF_INIT; const char *rfc = NULL; int creation_factor = -1; + const char *signature = git_version_string; + const char *signature_file_arg = NULL; + struct keep_callback_data keep_callback_data = { + .cfg = &cfg, + .revs = &rev, + }; + const char *fmt_patch_suffix = NULL; const struct option builtin_format_patch_options[] = { - OPT_CALLBACK_F('n', "numbered", &numbered, NULL, + OPT_CALLBACK_F('n', "numbered", &cfg, NULL, N_("use [PATCH n/m] even with a single patch"), PARSE_OPT_NOARG, numbered_callback), - OPT_CALLBACK_F('N', "no-numbered", &numbered, NULL, + OPT_CALLBACK_F('N', "no-numbered", &cfg, NULL, N_("use [PATCH] even with multiple patches"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, no_numbered_callback), - OPT_BOOL('s', "signoff", &do_signoff, N_("add a Signed-off-by trailer")), + OPT_BOOL('s', "signoff", &cfg.do_signoff, N_("add a Signed-off-by trailer")), OPT_BOOL(0, "stdout", &use_stdout, N_("print patches to standard out")), OPT_BOOL(0, "cover-letter", &cover_letter, @@ -1993,7 +2048,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("start numbering patches at instead of 1")), OPT_STRING('v', "reroll-count", &reroll_count, N_("reroll-count"), N_("mark the series as Nth re-roll")), - OPT_INTEGER(0, "filename-max-length", &cfg.fmt_patch_name_max, + OPT_INTEGER(0, "filename-max-length", &cfg.log.fmt_patch_name_max, N_("max length of output filename")), OPT_CALLBACK_F(0, "rfc", &rfc, N_("rfc"), N_("add (default 'RFC') before 'PATCH'"), @@ -2003,13 +2058,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("generate parts of a cover letter based on a branch's description")), OPT_FILENAME(0, "description-file", &description_file, N_("use branch description from file")), - OPT_CALLBACK_F(0, "subject-prefix", &sprefix, N_("prefix"), + OPT_CALLBACK_F(0, "subject-prefix", &cfg, N_("prefix"), N_("use [] instead of [PATCH]"), PARSE_OPT_NONEG, subject_prefix_callback), OPT_CALLBACK_F('o', "output-directory", &output_directory, N_("dir"), N_("store resulting files in "), PARSE_OPT_NONEG, output_directory_callback), - OPT_CALLBACK_F('k', "keep-subject", &rev, NULL, + OPT_CALLBACK_F('k', "keep-subject", &keep_callback_data, NULL, N_("don't strip/add [PATCH]"), PARSE_OPT_NOARG | PARSE_OPT_NONEG, keep_callback), OPT_BOOL(0, "no-binary", &no_binary_diff, @@ -2022,11 +2077,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("show patch format instead of default (patch + stat)"), 1, PARSE_OPT_NONEG), OPT_GROUP(N_("Messaging")), - OPT_CALLBACK(0, "add-header", NULL, N_("header"), + OPT_CALLBACK(0, "add-header", &cfg, N_("header"), N_("add email header"), header_callback), - OPT_STRING_LIST(0, "to", &extra_to, N_("email"), N_("add To: header")), - OPT_STRING_LIST(0, "cc", &extra_cc, N_("email"), N_("add Cc: header")), - OPT_CALLBACK_F(0, "from", &from, N_("ident"), + OPT_STRING_LIST(0, "to", &cfg.extra_to, N_("email"), N_("add To: header")), + OPT_STRING_LIST(0, "cc", &cfg.extra_cc, N_("email"), N_("add Cc: header")), + OPT_CALLBACK_F(0, "from", &cfg.from, N_("ident"), N_("set From address to (or committer ident if absent)"), PARSE_OPT_OPTARG, from_callback), OPT_STRING(0, "in-reply-to", &in_reply_to, N_("message-id"), @@ -2038,15 +2093,15 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) N_("inline the patch"), PARSE_OPT_OPTARG | PARSE_OPT_NONEG, inline_callback), - OPT_CALLBACK_F(0, "thread", &thread, N_("style"), + OPT_CALLBACK_F(0, "thread", &cfg, N_("style"), N_("enable message threading, styles: shallow, deep"), PARSE_OPT_OPTARG, thread_callback), OPT_STRING(0, "signature", &signature, N_("signature"), N_("add a signature")), - OPT_CALLBACK_F(0, "base", &base_commit, N_("base-commit"), + OPT_CALLBACK_F(0, "base", &cfg, N_("base-commit"), N_("add prerequisite tree info to the patch series"), 0, base_callback), - OPT_FILENAME(0, "signature-file", &signature_file, + OPT_FILENAME(0, "signature-file", &signature_file_arg, N_("add a signature from a file")), OPT__QUIET(&quiet, N_("don't print the patch filenames")), OPT_BOOL(0, "progress", &show_progress, @@ -2063,21 +2118,17 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) OPT_END() }; - extra_hdr.strdup_strings = 1; - extra_to.strdup_strings = 1; - extra_cc.strdup_strings = 1; - - log_config_init(&cfg); + format_config_init(&cfg); init_diff_ui_defaults(); - init_display_notes(¬es_opt); + init_display_notes(&cfg.notes_opt); git_config(git_format_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); git_config(grep_config, &rev.grep_filter); - rev.show_notes = show_notes; - memcpy(&rev.notes_opt, ¬es_opt, sizeof(notes_opt)); + rev.show_notes = cfg.show_notes; + memcpy(&rev.notes_opt, &cfg.notes_opt, sizeof(cfg.notes_opt)); rev.commit_format = CMIT_FMT_EMAIL; - rev.encode_email_headers = cfg.default_encode_email_headers; + rev.encode_email_headers = cfg.log.default_encode_email_headers; rev.expand_tabs_in_log_default = 0; rev.verbose_header = 1; rev.diff = 1; @@ -2088,12 +2139,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) s_r_opt.def = "HEAD"; s_r_opt.revarg_opt = REVARG_COMMITTISH; - strbuf_addstr(&sprefix, cfg.fmt_patch_subject_prefix); + strbuf_addstr(&cfg.sprefix, cfg.log.fmt_patch_subject_prefix); if (format_no_prefix) diff_set_noprefix(&rev.diffopt); - if (default_attach) { - rev.mime_boundary = default_attach; + if (cfg.default_attach) { + rev.mime_boundary = cfg.default_attach; rev.no_inline = 1; } @@ -2109,60 +2160,63 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.force_in_body_from = force_in_body_from; + if (!fmt_patch_suffix) + fmt_patch_suffix = cfg.fmt_patch_suffix; + /* Make sure "0000-$sub.patch" gives non-negative length for $sub */ - if (cfg.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix)) - cfg.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix); + if (cfg.log.fmt_patch_name_max <= strlen("0000-") + strlen(fmt_patch_suffix)) + cfg.log.fmt_patch_name_max = strlen("0000-") + strlen(fmt_patch_suffix); if (cover_from_description_arg) - cover_from_description_mode = parse_cover_from_description(cover_from_description_arg); + cfg.cover_from_description_mode = parse_cover_from_description(cover_from_description_arg); if (rfc && rfc[0]) { - subject_prefix = 1; + cfg.subject_prefix = 1; if (rfc[0] == '-') - strbuf_addf(&sprefix, " %s", rfc + 1); + strbuf_addf(&cfg.sprefix, " %s", rfc + 1); else - strbuf_insertf(&sprefix, 0, "%s ", rfc); + strbuf_insertf(&cfg.sprefix, 0, "%s ", rfc); } if (reroll_count) { - strbuf_addf(&sprefix, " v%s", reroll_count); + strbuf_addf(&cfg.sprefix, " v%s", reroll_count); rev.reroll_count = reroll_count; } - rev.subject_prefix = sprefix.buf; + rev.subject_prefix = cfg.sprefix.buf; - for (i = 0; i < extra_hdr.nr; i++) { - strbuf_addstr(&buf, extra_hdr.items[i].string); + for (i = 0; i < cfg.extra_hdr.nr; i++) { + strbuf_addstr(&buf, cfg.extra_hdr.items[i].string); strbuf_addch(&buf, '\n'); } - if (extra_to.nr) + if (cfg.extra_to.nr) strbuf_addstr(&buf, "To: "); - for (i = 0; i < extra_to.nr; i++) { + for (i = 0; i < cfg.extra_to.nr; i++) { if (i) strbuf_addstr(&buf, " "); - strbuf_addstr(&buf, extra_to.items[i].string); - if (i + 1 < extra_to.nr) + strbuf_addstr(&buf, cfg.extra_to.items[i].string); + if (i + 1 < cfg.extra_to.nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } - if (extra_cc.nr) + if (cfg.extra_cc.nr) strbuf_addstr(&buf, "Cc: "); - for (i = 0; i < extra_cc.nr; i++) { + for (i = 0; i < cfg.extra_cc.nr; i++) { if (i) strbuf_addstr(&buf, " "); - strbuf_addstr(&buf, extra_cc.items[i].string); - if (i + 1 < extra_cc.nr) + strbuf_addstr(&buf, cfg.extra_cc.items[i].string); + if (i + 1 < cfg.extra_cc.nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } rev.extra_headers = to_free = strbuf_detach(&buf, NULL); - if (from) { - if (split_ident_line(&rev.from_ident, from, strlen(from))) - die(_("invalid ident line: %s"), from); + if (cfg.from) { + if (split_ident_line(&rev.from_ident, cfg.from, strlen(cfg.from))) + die(_("invalid ident line: %s"), cfg.from); } if (start_number < 0) @@ -2173,14 +2227,14 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) * and it would conflict with --keep-subject (-k) from the * command line, reset "numbered". */ - if (numbered && keep_subject && !numbered_cmdline_opt) - numbered = 0; + if (cfg.numbered && cfg.keep_subject && !cfg.numbered_cmdline_opt) + cfg.numbered = 0; - if (numbered && keep_subject) + if (cfg.numbered && cfg.keep_subject) die(_("options '%s' and '%s' cannot be used together"), "-n", "-k"); - if (keep_subject && subject_prefix) + if (cfg.keep_subject && cfg.subject_prefix) die(_("options '%s' and '%s' cannot be used together"), "--subject-prefix/--rfc", "-k"); - rev.preserve_subject = keep_subject; + rev.preserve_subject = cfg.keep_subject; argc = setup_revisions(argc, argv, &rev, &s_r_opt); if (argc > 1) @@ -2207,7 +2261,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.always_show_header = 1; rev.zero_commit = zero_commit; - rev.patch_name_max = cfg.fmt_patch_name_max; + rev.patch_name_max = cfg.log.fmt_patch_name_max; if (!rev.diffopt.flags.text && !no_binary_diff) rev.diffopt.flags.binary = 1; @@ -2228,7 +2282,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) int saved; if (!output_directory) - output_directory = config_output_directory; + output_directory = cfg.config_output_directory; output_directory = set_outdir(prefix, output_directory); if (rev.diffopt.use_color != GIT_COLOR_ALWAYS) @@ -2326,14 +2380,14 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) goto done; total = nr; if (cover_letter == -1) { - if (config_cover_letter == COVER_AUTO) + if (cfg.config_cover_letter == COVER_AUTO) cover_letter = (total > 1); else - cover_letter = (config_cover_letter == COVER_ON); + cover_letter = (cfg.config_cover_letter == COVER_ON); } - if (!keep_subject && auto_number && (total > 1 || cover_letter)) - numbered = 1; - if (numbered) + if (!cfg.keep_subject && cfg.auto_number && (total > 1 || cover_letter)) + cfg.numbered = 1; + if (cfg.numbered) rev.total = total + start_number - 1; if (idiff_prev.nr) { @@ -2365,27 +2419,40 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) _("Range-diff against v%d:")); } + /* + * The order of precedence is: + * + * 1. The `--signature` and `--no-signature` options. + * 2. The `--signature-file` option. + * 3. The `format.signature` config. + * 4. The `format.signatureFile` config. + * 5. Default `git_version_string`. + */ if (!signature) { ; /* --no-signature inhibits all signatures */ } else if (signature && signature != git_version_string) { ; /* non-default signature already set */ - } else if (signature_file) { + } else if (signature_file_arg || (cfg.signature_file && !cfg.signature)) { struct strbuf buf = STRBUF_INIT; + const char *signature_file = signature_file_arg ? + signature_file_arg : cfg.signature_file; if (strbuf_read_file(&buf, signature_file, 128) < 0) die_errno(_("unable to read signature file '%s'"), signature_file); signature = strbuf_detach(&buf, NULL); + } else if (cfg.signature) { + signature = cfg.signature; } memset(&bases, 0, sizeof(bases)); - base = get_base_commit(base_commit, list, nr); + base = get_base_commit(&cfg, list, nr); if (base) { reset_revision_walk(); clear_object_flags(UNINTERESTING); prepare_bases(&bases, base, list, nr); } - if (in_reply_to || thread || cover_letter) { + if (in_reply_to || cfg.thread || cover_letter) { rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids)); string_list_init_dup(rev.ref_message_ids); } @@ -2396,19 +2463,19 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.numbered_files = just_numbers; rev.patch_suffix = fmt_patch_suffix; if (cover_letter) { - if (thread) + if (cfg.thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, !!output_directory, - origin, nr, list, description_file, branch_name, quiet); + origin, nr, list, description_file, branch_name, quiet, &cfg); print_bases(&bases, rev.diffopt.file); - print_signature(rev.diffopt.file); + print_signature(signature, rev.diffopt.file); total++; start_number--; /* interdiff/range-diff in cover-letter; omit from patches */ rev.idiff_oid1 = NULL; rev.rdiff1 = NULL; } - rev.add_signoff = do_signoff; + rev.add_signoff = cfg.do_signoff; if (show_progress) progress = start_delayed_progress(_("Generating patches"), total); @@ -2418,7 +2485,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) commit = list[nr]; rev.nr = total - nr + (start_number - 1); /* Make the second and subsequent mails replies to the first */ - if (thread) { + if (cfg.thread) { /* Have we already had a message ID? */ if (rev.message_id) { /* @@ -2442,7 +2509,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) * letter is a reply to the * --in-reply-to, if specified. */ - if (thread == THREAD_SHALLOW + if (cfg.thread == THREAD_SHALLOW && rev.ref_message_ids->nr > 0 && (!cover_letter || rev.nr > 1)) free(rev.message_id); @@ -2475,7 +2542,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) mime_boundary_leader, rev.mime_boundary); else - print_signature(rev.diffopt.file); + print_signature(signature, rev.diffopt.file); } if (output_directory) fclose(rev.diffopt.file); @@ -2483,9 +2550,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) stop_progress(&progress); free(list); free(branch_name); - string_list_clear(&extra_to, 0); - string_list_clear(&extra_cc, 0); - string_list_clear(&extra_hdr, 0); if (ignore_if_in_upstream) free_patch_ids(&ids); @@ -2495,14 +2559,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) strbuf_release(&rdiff1); strbuf_release(&rdiff2); strbuf_release(&rdiff_title); - strbuf_release(&sprefix); free(to_free); free(rev.message_id); if (rev.ref_message_ids) string_list_clear(rev.ref_message_ids, 0); free(rev.ref_message_ids); release_revisions(&rev); - log_config_release(&cfg); + format_config_release(&cfg); return 0; } From patchwork Mon May 27 11:46:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675097 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 10ADF15DBCB for ; Mon, 27 May 2024 11:46:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810407; cv=none; b=XrfLUmo80ik4Tu9LXk006wrS7WOpqBQhObu/kq0258T2Gajb07BgZPg7U+J+55GC+T4x5rzJK7D2UzXxMxuCaE9jUmlFVPtYn9Mi00MhqWP9x6t679+QwmjiLlL9HRqMkux158wZglxdHsNdfBv4wAM/46/4nw6pk9lcgY1q4IQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810407; c=relaxed/simple; bh=WwQz07zx1Qtl2kiuURV0LlgoS8US266hd0W5hBJ1TNg=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=qFWLREbFCgmT/arq01umWsBu06zZjdvAMf74UNU1nte6iO3KQ4LhMFkgH/+aEKUPQpskkdM5DLltrMLQfcJlpMiLaVgrzlsyLtdNSUS0cQ9rRlRcX6x7Z2kBbZ+eSmVvNTkSZaaw23VkSTfmBRX82znlvQA9Iik0Qqyzw3HClp4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=MM/yAhu/; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=mkqaLeOR; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="MM/yAhu/"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="mkqaLeOR" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfhigh.west.internal (Postfix) with ESMTP id 2FC941800097; Mon, 27 May 2024 07:46:44 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 27 May 2024 07:46:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810403; x=1716896803; bh=+qQkvmM450 708MpCJq8AWHQ93g9mnCfRqe3J46gzhhc=; b=MM/yAhu/zyslvTHHViSZ1sGEQj qOWQR2mhhdtOmwwA42yxL7gWPVdBQjyBBOopYBAJJ3p8+ENkipqX0+fIQOjOzrKz mt4oAQaSH9/3DZ/Z8AM6sFJ6HibGw7iiL1Qxz0ZpWrFiF62ot1ZfefG7Efq4XDpo mOj+gaYLxo5VGGUcDmHk8Jd0VN4n91LcDz90NK8sd3HP4ObeExrQTUnflUMj71ib /Rshwp4FadrT3dDkFj5gyfgYYB14S2oj4m/xpmO/Oyo2R/WD7UApyMDquO9PbETm Q4kmw53ulR8KoCS7olvXHaPVA9zoAtRGWQlGWDmbkwFCJdQxmp/HRJ/IIZLg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810403; x=1716896803; bh=+qQkvmM450708MpCJq8AWHQ93g9m nCfRqe3J46gzhhc=; b=mkqaLeORAxTKGpbgCJZEFQexXHDsVp8O4pz8cy30P+al 8v9pyhVgZJ+HbBbyLwqy/CkTSsPwrpG8xQ3rzI6RndTD8edbtG5WwczJI+ez3TTi 55vxsGaYF+qSanubvzGNhkF/1RHgyI9KUp5s6bkyDgDE6yZFNfawdwu14V6ANJEC 5RNqKVMUg0ahv96DNvUWeHKMN2gMRVfT9Fccb/vaYD0EmzGhVaLf9+IWrq1obhNC Wlc81DoZ4XE5ZYLrD5R/KKDSvUvRvnhuzMQv23YTYgLAPoTVtVMkT9C+fM7avrXJ YDJ3ZNjQiFXTx39E/yyzPssFY14gtONfij/x5PcMkw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepvdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:42 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 62681b38 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:32 +0000 (UTC) Date: Mon, 27 May 2024 13:46:39 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 12/21] config: clarify memory ownership in `git_config_string()` Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The out parameter of `git_config_string()` is a `const char **` even though we transfer ownership of memory to the caller. This is quite misleading and has led to many memory leaks all over the place. Adapt the parameter to instead be `char **`. Signed-off-by: Patrick Steinhardt --- alias.c | 2 +- attr.c | 2 +- attr.h | 2 +- builtin/commit.c | 2 +- builtin/log.c | 12 ++++++------ builtin/merge.c | 4 ++-- builtin/rebase.c | 2 +- builtin/receive-pack.c | 2 +- builtin/repack.c | 8 ++++---- config.c | 6 +++--- config.h | 2 +- convert.c | 6 +++--- delta-islands.c | 2 +- diff.c | 8 ++++---- environment.c | 8 ++++---- environment.h | 8 ++++---- gpg-interface.c | 4 ++-- http.c | 24 ++++++++++++------------ imap-send.c | 12 ++++++------ mailmap.c | 2 +- mailmap.h | 2 +- merge-ll.c | 6 +++--- pager.c | 2 +- pretty.c | 14 +++++++++----- promisor-remote.h | 2 +- remote.c | 20 ++++++++++---------- remote.h | 8 ++++---- sequencer.c | 2 +- upload-pack.c | 2 +- userdiff.h | 12 ++++++------ 30 files changed, 96 insertions(+), 92 deletions(-) diff --git a/alias.c b/alias.c index 5a238f2e30..269892c356 100644 --- a/alias.c +++ b/alias.c @@ -22,7 +22,7 @@ static int config_alias_cb(const char *key, const char *value, if (data->alias) { if (!strcasecmp(p, data->alias)) - return git_config_string((const char **)&data->v, + return git_config_string(&data->v, key, value); } else if (data->list) { string_list_append(data->list, p); diff --git a/attr.c b/attr.c index 33473bdce0..5607db2bbe 100644 --- a/attr.c +++ b/attr.c @@ -25,7 +25,7 @@ #include "tree-walk.h" #include "object-name.h" -const char *git_attr_tree; +char *git_attr_tree; const char git_attr__true[] = "(builtin)true"; const char git_attr__false[] = "\0(builtin)false"; diff --git a/attr.h b/attr.h index 127998ae01..e7cc318b0c 100644 --- a/attr.h +++ b/attr.h @@ -236,6 +236,6 @@ const char *git_attr_global_file(void); /* Return whether the system gitattributes file is enabled and should be used. */ int git_attr_system_is_enabled(void); -extern const char *git_attr_tree; +extern char *git_attr_tree; #endif /* ATTR_H */ diff --git a/builtin/commit.c b/builtin/commit.c index 1cc88e92bf..f53e7e86ff 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -133,7 +133,7 @@ static struct strvec trailer_args = STRVEC_INIT; * is specified explicitly. */ static enum commit_msg_cleanup_mode cleanup_mode; -static const char *cleanup_arg; +static char *cleanup_arg; static enum commit_whence whence; static int use_editor = 1, include_status = 1; diff --git a/builtin/log.c b/builtin/log.c index 890bf0c425..517d7982f1 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -582,11 +582,11 @@ static int git_log_config(const char *var, const char *value, if (!strcmp(var, "format.pretty")) { FREE_AND_NULL(cfg->fmt_pretty); - return git_config_string((const char **) &cfg->fmt_pretty, var, value); + return git_config_string(&cfg->fmt_pretty, var, value); } if (!strcmp(var, "format.subjectprefix")) { FREE_AND_NULL(cfg->fmt_patch_subject_prefix); - return git_config_string((const char **) &cfg->fmt_patch_subject_prefix, var, value); + return git_config_string(&cfg->fmt_patch_subject_prefix, var, value); } if (!strcmp(var, "format.filenamemaxlength")) { cfg->fmt_patch_name_max = git_config_int(var, value, ctx->kvi); @@ -602,7 +602,7 @@ static int git_log_config(const char *var, const char *value, } if (!strcmp(var, "log.date")) { FREE_AND_NULL(cfg->default_date_mode); - return git_config_string((const char **) &cfg->default_date_mode, var, value); + return git_config_string(&cfg->default_date_mode, var, value); } if (!strcmp(var, "log.decorate")) { cfg->decoration_style = parse_decoration_style(value); @@ -1076,7 +1076,7 @@ static int git_format_config(const char *var, const char *value, } if (!strcmp(var, "format.suffix")) { FREE_AND_NULL(cfg->fmt_patch_suffix); - return git_config_string((const char **) &cfg->fmt_patch_suffix, var, value); + return git_config_string(&cfg->fmt_patch_suffix, var, value); } if (!strcmp(var, "format.to")) { if (!value) @@ -1133,7 +1133,7 @@ static int git_format_config(const char *var, const char *value, } if (!strcmp(var, "format.signature")) { FREE_AND_NULL(cfg->signature); - return git_config_string((const char **) &cfg->signature, var, value); + return git_config_string(&cfg->signature, var, value); } if (!strcmp(var, "format.signaturefile")) { FREE_AND_NULL(cfg->signature_file); @@ -1149,7 +1149,7 @@ static int git_format_config(const char *var, const char *value, } if (!strcmp(var, "format.outputdirectory")) { FREE_AND_NULL(cfg->config_output_directory); - return git_config_string((const char **) &cfg->config_output_directory, var, value); + return git_config_string(&cfg->config_output_directory, var, value); } if (!strcmp(var, "format.useautobase")) { if (value && !strcasecmp(value, "whenAble")) { diff --git a/builtin/merge.c b/builtin/merge.c index e4bd65eeba..daed2d4e1e 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -100,7 +100,7 @@ static struct strategy all_strategy[] = { { "subtree", NO_FAST_FORWARD | NO_TRIVIAL }, }; -static const char *pull_twohead, *pull_octopus; +static char *pull_twohead, *pull_octopus; enum ff_type { FF_NO, @@ -110,7 +110,7 @@ enum ff_type { static enum ff_type fast_forward = FF_ALLOW; -static const char *cleanup_arg; +static char *cleanup_arg; static enum commit_msg_cleanup_mode cleanup_mode; static int option_parse_message(const struct option *opt, diff --git a/builtin/rebase.c b/builtin/rebase.c index 0466d9414a..14d4f0a5e6 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -83,7 +83,7 @@ static const char *action_names[] = { struct rebase_options { enum rebase_type type; enum empty_type empty; - const char *default_backend; + char *default_backend; const char *state_dir; struct commit *upstream; const char *upstream_name; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 56228ad314..01c1f04ece 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -88,7 +88,7 @@ static struct strbuf push_cert = STRBUF_INIT; static struct object_id push_cert_oid; static struct signature_check sigcheck; static const char *push_cert_nonce; -static const char *cert_nonce_seed; +static char *cert_nonce_seed; static struct strvec hidden_refs = STRVEC_INIT; static const char *NONCE_UNSOLICITED = "UNSOLICITED"; diff --git a/builtin/repack.c b/builtin/repack.c index 43491a4cbf..e40dceaada 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -48,10 +48,10 @@ static const char incremental_bitmap_conflict_error[] = N_( ); struct pack_objects_args { - const char *window; - const char *window_memory; - const char *depth; - const char *threads; + char *window; + char *window_memory; + char *depth; + char *threads; unsigned long max_pack_size; int no_reuse_delta; int no_reuse_object; diff --git a/config.c b/config.c index f9101045ee..da52a7f8a1 100644 --- a/config.c +++ b/config.c @@ -1338,7 +1338,7 @@ int git_config_bool(const char *name, const char *value) return v; } -int git_config_string(const char **dest, const char *var, const char *value) +int git_config_string(char **dest, const char *var, const char *value) { if (!value) return config_error_nonbool(var); @@ -1566,7 +1566,7 @@ static int git_default_core_config(const char *var, const char *value, if (!strcmp(var, "core.checkroundtripencoding")) { FREE_AND_NULL(check_roundtrip_encoding); - return git_config_string((const char **) &check_roundtrip_encoding, var, value); + return git_config_string(&check_roundtrip_encoding, var, value); } if (!strcmp(var, "core.notesref")) { @@ -2418,7 +2418,7 @@ int git_configset_get_string(struct config_set *set, const char *key, char **des { const char *value; if (!git_configset_get_value(set, key, &value, NULL)) - return git_config_string((const char **)dest, key, value); + return git_config_string(dest, key, value); else return 1; } diff --git a/config.h b/config.h index b3103bba94..2d2e22ed64 100644 --- a/config.h +++ b/config.h @@ -280,7 +280,7 @@ int git_config_bool(const char *, const char *); * Allocates and copies the value string into the `dest` parameter; if no * string is given, prints an error message and returns -1. */ -int git_config_string(const char **, const char *, const char *); +int git_config_string(char **, const char *, const char *); /** * Similar to `git_config_string`, but expands `~` or `~user` into the diff --git a/convert.c b/convert.c index 03c3c528f9..f2b9f01354 100644 --- a/convert.c +++ b/convert.c @@ -981,9 +981,9 @@ int async_query_available_blobs(const char *cmd, struct string_list *available_p static struct convert_driver { const char *name; struct convert_driver *next; - const char *smudge; - const char *clean; - const char *process; + char *smudge; + char *clean; + char *process; int required; } *user_convert, **user_convert_tail; diff --git a/delta-islands.c b/delta-islands.c index 4ac3c10551..89d51b72e3 100644 --- a/delta-islands.c +++ b/delta-islands.c @@ -313,7 +313,7 @@ struct island_load_data { size_t nr; size_t alloc; }; -static const char *core_island_name; +static char *core_island_name; static void free_config_regexes(struct island_load_data *ild) { diff --git a/diff.c b/diff.c index 679ef472f4..e70301df76 100644 --- a/diff.c +++ b/diff.c @@ -56,8 +56,8 @@ static int diff_color_moved_default; static int diff_color_moved_ws_default; static int diff_context_default = 3; static int diff_interhunk_context_default; -static const char *diff_word_regex_cfg; -static const char *external_diff_cmd_cfg; +static char *diff_word_regex_cfg; +static char *external_diff_cmd_cfg; static char *diff_order_file_cfg; int diff_auto_refresh_index = 1; static int diff_mnemonic_prefix; @@ -412,11 +412,11 @@ int git_diff_ui_config(const char *var, const char *value, } if (!strcmp(var, "diff.srcprefix")) { FREE_AND_NULL(diff_src_prefix); - return git_config_string((const char **) &diff_src_prefix, var, value); + return git_config_string(&diff_src_prefix, var, value); } if (!strcmp(var, "diff.dstprefix")) { FREE_AND_NULL(diff_dst_prefix); - return git_config_string((const char **) &diff_dst_prefix, var, value); + return git_config_string(&diff_dst_prefix, var, value); } if (!strcmp(var, "diff.relative")) { diff_relative = git_config_bool(var, value); diff --git a/environment.c b/environment.c index ab6956559e..701d515135 100644 --- a/environment.c +++ b/environment.c @@ -42,8 +42,8 @@ int is_bare_repository_cfg = -1; /* unspecified */ int warn_ambiguous_refs = 1; int warn_on_object_refname_ambiguity = 1; int repository_format_precious_objects; -const char *git_commit_encoding; -const char *git_log_output_encoding; +char *git_commit_encoding; +char *git_log_output_encoding; char *apply_default_whitespace; char *apply_default_ignorewhitespace; char *git_attributes_file; @@ -58,8 +58,8 @@ size_t packed_git_window_size = DEFAULT_PACKED_GIT_WINDOW_SIZE; size_t packed_git_limit = DEFAULT_PACKED_GIT_LIMIT; size_t delta_base_cache_limit = 96 * 1024 * 1024; unsigned long big_file_threshold = 512 * 1024 * 1024; -const char *editor_program; -const char *askpass_program; +char *editor_program; +char *askpass_program; char *excludes_file; enum auto_crlf auto_crlf = AUTO_CRLF_FALSE; enum eol core_eol = EOL_UNSET; diff --git a/environment.h b/environment.h index be1b88ad6f..e9f01d4d11 100644 --- a/environment.h +++ b/environment.h @@ -224,11 +224,11 @@ int odb_pack_keep(const char *name); const char *get_log_output_encoding(void); const char *get_commit_output_encoding(void); -extern const char *git_commit_encoding; -extern const char *git_log_output_encoding; +extern char *git_commit_encoding; +extern char *git_log_output_encoding; -extern const char *editor_program; -extern const char *askpass_program; +extern char *editor_program; +extern char *askpass_program; extern char *excludes_file; /* diff --git a/gpg-interface.c b/gpg-interface.c index 2b50ed0fa0..5193223714 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -27,14 +27,14 @@ static void gpg_interface_lazy_init(void) } static char *configured_signing_key; -static const char *ssh_default_key_command; +static char *ssh_default_key_command; static char *ssh_allowed_signers; static char *ssh_revocation_file; static enum signature_trust_level configured_min_trust_level = TRUST_UNDEFINED; struct gpg_format { const char *name; - const char *program; + char *program; const char **verify_args; const char **sigs; int (*verify_signed_buffer)(struct signature_check *sigc, diff --git a/http.c b/http.c index fa3ea87451..67cc47d28f 100644 --- a/http.c +++ b/http.c @@ -38,11 +38,11 @@ char curl_errorstr[CURL_ERROR_SIZE]; static int curl_ssl_verify = -1; static int curl_ssl_try; -static const char *curl_http_version = NULL; +static char *curl_http_version; static char *ssl_cert; static char *ssl_cert_type; -static const char *ssl_cipherlist; -static const char *ssl_version; +static char *ssl_cipherlist; +static char *ssl_version; static struct { const char *name; long ssl_version; @@ -95,7 +95,7 @@ static struct { */ }; #ifdef CURLGSSAPI_DELEGATION_FLAG -static const char *curl_deleg; +static char *curl_deleg; static struct { const char *name; long curl_deleg_param; @@ -383,11 +383,11 @@ static int http_options(const char *var, const char *value, if (!strcmp("http.sslcert", var)) return git_config_pathname(&ssl_cert, var, value); if (!strcmp("http.sslcerttype", var)) - return git_config_string((const char **)&ssl_cert_type, var, value); + return git_config_string(&ssl_cert_type, var, value); if (!strcmp("http.sslkey", var)) return git_config_pathname(&ssl_key, var, value); if (!strcmp("http.sslkeytype", var)) - return git_config_string((const char **)&ssl_key_type, var, value); + return git_config_string(&ssl_key_type, var, value); if (!strcmp("http.sslcapath", var)) return git_config_pathname(&ssl_capath, var, value); if (!strcmp("http.sslcainfo", var)) @@ -440,19 +440,19 @@ static int http_options(const char *var, const char *value, return 0; } if (!strcmp("http.proxy", var)) - return git_config_string((const char **)&curl_http_proxy, var, value); + return git_config_string(&curl_http_proxy, var, value); if (!strcmp("http.proxyauthmethod", var)) - return git_config_string((const char **)&http_proxy_authmethod, var, value); + return git_config_string(&http_proxy_authmethod, var, value); if (!strcmp("http.proxysslcert", var)) - return git_config_string((const char **)&http_proxy_ssl_cert, var, value); + return git_config_string(&http_proxy_ssl_cert, var, value); if (!strcmp("http.proxysslkey", var)) - return git_config_string((const char **)&http_proxy_ssl_key, var, value); + return git_config_string(&http_proxy_ssl_key, var, value); if (!strcmp("http.proxysslcainfo", var)) - return git_config_string((const char **)&http_proxy_ssl_ca_info, var, value); + return git_config_string(&http_proxy_ssl_ca_info, var, value); if (!strcmp("http.proxysslcertpasswordprotected", var)) { proxy_ssl_cert_password_required = git_config_bool(var, value); @@ -476,7 +476,7 @@ static int http_options(const char *var, const char *value, } if (!strcmp("http.useragent", var)) - return git_config_string((const char **)&user_agent, var, value); + return git_config_string(&user_agent, var, value); if (!strcmp("http.emptyauth", var)) { if (value && !strcmp("auto", value)) diff --git a/imap-send.c b/imap-send.c index c0130d0e02..a5d1510180 100644 --- a/imap-send.c +++ b/imap-send.c @@ -70,16 +70,16 @@ static char *next_arg(char **); struct imap_server_conf { const char *name; - const char *tunnel; - const char *host; + char *tunnel; + char *host; int port; - const char *folder; - const char *user; - const char *pass; + char *folder; + char *user; + char *pass; int use_ssl; int ssl_verify; int use_html; - const char *auth_method; + char *auth_method; }; static struct imap_server_conf server = { diff --git a/mailmap.c b/mailmap.c index 044466b043..b2efe29b3d 100644 --- a/mailmap.c +++ b/mailmap.c @@ -7,7 +7,7 @@ #include "setup.h" char *git_mailmap_file; -const char *git_mailmap_blob; +char *git_mailmap_blob; struct mailmap_info { char *name; diff --git a/mailmap.h b/mailmap.h index 429a760945..cbda9bc5e0 100644 --- a/mailmap.h +++ b/mailmap.h @@ -4,7 +4,7 @@ struct string_list; extern char *git_mailmap_file; -extern const char *git_mailmap_blob; +extern char *git_mailmap_blob; int read_mailmap(struct string_list *map); void clear_mailmap(struct string_list *map); diff --git a/merge-ll.c b/merge-ll.c index bf1077ae09..e29b15fa4a 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -27,9 +27,9 @@ typedef enum ll_merge_result (*ll_merge_fn)(const struct ll_merge_driver *, struct ll_merge_driver { const char *name; - const char *description; + char *description; ll_merge_fn fn; - const char *recursive; + char *recursive; struct ll_merge_driver *next; char *cmdline; }; @@ -268,7 +268,7 @@ static enum ll_merge_result ll_ext_merge(const struct ll_merge_driver *fn, * merge.default and merge.driver configuration items */ static struct ll_merge_driver *ll_user_merge, **ll_user_merge_tail; -static const char *default_ll_merge; +static char *default_ll_merge; static int read_merge_config(const char *var, const char *value, const struct config_context *ctx UNUSED, diff --git a/pager.c b/pager.c index b8822a9381..e9e121db69 100644 --- a/pager.c +++ b/pager.c @@ -13,7 +13,7 @@ int pager_use_color = 1; #endif static struct child_process pager_process; -static const char *pager_program; +static char *pager_program; /* Is the value coming back from term_columns() just a guess? */ static int term_columns_guessed; diff --git a/pretty.c b/pretty.c index 7ead078998..22a81506b7 100644 --- a/pretty.c +++ b/pretty.c @@ -62,7 +62,7 @@ static int git_pretty_formats_config(const char *var, const char *value, { struct cmt_fmt_map *commit_format = NULL; const char *name; - const char *fmt; + char *fmt; int i; if (!skip_prefix(var, "pretty.", &name)) @@ -93,13 +93,17 @@ static int git_pretty_formats_config(const char *var, const char *value, if (git_config_string(&fmt, var, value)) return -1; - if (skip_prefix(fmt, "format:", &fmt)) + if (skip_prefix(fmt, "format:", &commit_format->user_format)) { commit_format->is_tformat = 0; - else if (skip_prefix(fmt, "tformat:", &fmt) || strchr(fmt, '%')) + } else if (skip_prefix(fmt, "tformat:", &commit_format->user_format)) { commit_format->is_tformat = 1; - else + } else if (strchr(fmt, '%')) { + commit_format->is_tformat = 1; + commit_format->user_format = fmt; + } else { commit_format->is_alias = 1; - commit_format->user_format = fmt; + commit_format->user_format = fmt; + } return 0; } diff --git a/promisor-remote.h b/promisor-remote.h index 2cb9eda9ea..88cb599c39 100644 --- a/promisor-remote.h +++ b/promisor-remote.h @@ -13,7 +13,7 @@ struct object_id; */ struct promisor_remote { struct promisor_remote *next; - const char *partial_clone_filter; + char *partial_clone_filter; const char name[FLEX_ARRAY]; }; diff --git a/remote.c b/remote.c index ec8c158e60..d319f28757 100644 --- a/remote.c +++ b/remote.c @@ -428,29 +428,29 @@ static int handle_config(const char *key, const char *value, else if (!strcmp(subkey, "prunetags")) remote->prune_tags = git_config_bool(key, value); else if (!strcmp(subkey, "url")) { - const char *v; + char *v; if (git_config_string(&v, key, value)) return -1; add_url(remote, v); } else if (!strcmp(subkey, "pushurl")) { - const char *v; + char *v; if (git_config_string(&v, key, value)) return -1; add_pushurl(remote, v); } else if (!strcmp(subkey, "push")) { - const char *v; + char *v; if (git_config_string(&v, key, value)) return -1; refspec_append(&remote->push, v); - free((char *)v); + free(v); } else if (!strcmp(subkey, "fetch")) { - const char *v; + char *v; if (git_config_string(&v, key, value)) return -1; refspec_append(&remote->fetch, v); - free((char *)v); + free(v); } else if (!strcmp(subkey, "receivepack")) { - const char *v; + char *v; if (git_config_string(&v, key, value)) return -1; if (!remote->receivepack) @@ -458,7 +458,7 @@ static int handle_config(const char *key, const char *value, else error(_("more than one receivepack given, using the first")); } else if (!strcmp(subkey, "uploadpack")) { - const char *v; + char *v; if (git_config_string(&v, key, value)) return -1; if (!remote->uploadpack) @@ -471,10 +471,10 @@ static int handle_config(const char *key, const char *value, else if (!strcmp(value, "--tags")) remote->fetch_tags = 2; } else if (!strcmp(subkey, "proxy")) { - return git_config_string((const char **)&remote->http_proxy, + return git_config_string(&remote->http_proxy, key, value); } else if (!strcmp(subkey, "proxyauthmethod")) { - return git_config_string((const char **)&remote->http_proxy_authmethod, + return git_config_string(&remote->http_proxy_authmethod, key, value); } else if (!strcmp(subkey, "vcs")) { return git_config_string(&remote->foreign_vcs, key, value); diff --git a/remote.h b/remote.h index dfd4837e60..e8c6655e42 100644 --- a/remote.h +++ b/remote.h @@ -46,7 +46,7 @@ struct remote_state { struct hashmap branches_hash; struct branch *current_branch; - const char *pushremote_name; + char *pushremote_name; struct rewrites rewrites; struct rewrites rewrites_push; @@ -65,7 +65,7 @@ struct remote { int origin, configured_in_repo; - const char *foreign_vcs; + char *foreign_vcs; /* An array of all of the url_nr URLs configured for the remote */ const char **url; @@ -309,9 +309,9 @@ struct branch { const char *refname; /* The name of the remote listed in the configuration. */ - const char *remote_name; + char *remote_name; - const char *pushremote_name; + char *pushremote_name; /* An array of the "merge" lines in the configuration. */ const char **merge_name; diff --git a/sequencer.c b/sequencer.c index dbd60d79b9..3c81ef9ca5 100644 --- a/sequencer.c +++ b/sequencer.c @@ -306,7 +306,7 @@ static int git_sequencer_config(const char *k, const char *v, } if (!opts->default_strategy && !strcmp(k, "pull.twohead")) { - int ret = git_config_string((const char**)&opts->default_strategy, k, v); + int ret = git_config_string(&opts->default_strategy, k, v); if (ret == 0) { /* * pull.twohead is allowed to be multi-valued; we only diff --git a/upload-pack.c b/upload-pack.c index 8fbd138515..5801eb2639 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -94,7 +94,7 @@ struct upload_pack_data { struct packet_writer writer; - const char *pack_objects_hook; + char *pack_objects_hook; unsigned stateless_rpc : 1; /* v0 only */ unsigned no_done : 1; /* v0 only */ diff --git a/userdiff.h b/userdiff.h index d726804c3e..cc8e5abfef 100644 --- a/userdiff.h +++ b/userdiff.h @@ -7,19 +7,19 @@ struct index_state; struct repository; struct userdiff_funcname { - const char *pattern; + char *pattern; int cflags; }; struct userdiff_driver { const char *name; - const char *external; - const char *algorithm; + char *external; + char *algorithm; int binary; struct userdiff_funcname funcname; - const char *word_regex; - const char *word_regex_multi_byte; - const char *textconv; + char *word_regex; + char *word_regex_multi_byte; + char *textconv; struct notes_cache *textconv_cache; int textconv_want_cache; }; From patchwork Mon May 27 11:46:44 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675098 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 7FE0315DBB3 for ; Mon, 27 May 2024 11:46:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810412; cv=none; b=J294Q0Xlsj+Osu3InB9MeS5C1djMDyZvnwwmI1QYUzzkGnzL4AJUUOkLggE/2GTBwyC5FLmcGTmNo31M0rOC0bBggTnz/XX8yvkr2aAMlqv+0PJgoPixdv70h+s9f+yTOP1sEZpbEvP2XpDGy8723lAswvFpI+CYdJV3ICrcQUc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810412; c=relaxed/simple; bh=NbBnEoJwp1AdhHjPmWewlCp8QvkAIrXNONRrjtSLuXU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=OMZLWH4LP3aVb2uDfvJsDnYPT99qC8EdaE5b2mgF0N5L2JIW02IQq4mv/OsHiBRXRajX8onq7lsiWSTdyfaXpDgFw764LpX0OYn3cQMyWUBOOqK3EvHYJjzA1eyU8uleWpjTawNFEh/p1vD9WNs/s17f2r6KkHQTQAOAk88ktsk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=bMCOKVvs; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=bz7iySdX; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="bMCOKVvs"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="bz7iySdX" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailfout.west.internal (Postfix) with ESMTP id 9917C1C000EC; Mon, 27 May 2024 07:46:48 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 27 May 2024 07:46:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810408; x=1716896808; bh=QXNwf+lpAY PjDpBqFj2WoAik6P6bvQs1IB3BAl9YcT8=; b=bMCOKVvse6qD1m+8Oq6yvUsLZO WvyY46xOlT8IDjzTCKnxAmroG+wFg0OrzHDbXxqTPN3hnBS3hi1d0Q2d+xSgPSdp 9ZOS/YuY9lr/MnsFj+r+dr1Sk+c5FbVx1DXwTymoNOnadz0h3ew5KtzMxrliweAE yA0XFZl3EhFsVrbaE88e7evdHfoOvTn+KHCjW+3TwfXsZcANiicR0XlzDbMUt1Mn rU5qVCLZJargMRCcI1JP3i3JZ9JbzVHMoQSLIXfUV3zdYtYuW9EhUdhhZ2OxPGSm uDdk+WFSYm18loHXMo8yfpE+u+6dhVXnJy+VwODgMKXlAdrPdnKMsUVurDiA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810408; x=1716896808; bh=QXNwf+lpAYPjDpBqFj2WoAik6P6b vQs1IB3BAl9YcT8=; b=bz7iySdX1m/gzvcLtHTj98UqP5SugLOfIaS8TnHYZTzz 0cGVcrOtbk85AZv8HHy1khuBf+d7L/txwzq9pVR8GE3v+y5r/qgjVW0bEO20I7IR D5rKU9OlNjYB7NDYoIYVUy/9zpcHUpu1fVXDgtFq7l71tlUQl5UcrO/4q+5Eky0t Em14XfZ9KZo8MsOvuCUkV+gq5SLJk9BRbAPINfnh7jl0D7/xA0PM2XL1Ivezfx6E pe8lXlCZnBmQcdmAIT953iu1zU+GEnjlrDzHCvyw07xVUhm4+IGUVeHfEG6+LT6h HAwIeTv14Cbw9P07erRQAh32bZoUhD+CXp4GUwPlDw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtjeenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepteeuvefhhfdufedvgeeiueeileegtdfhgeeftdeuveejjedtgfejhedujeeutddu necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:46 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 9b5c3b0d (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:36 +0000 (UTC) Date: Mon, 27 May 2024 13:46:44 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 13/21] config: plug various memory leaks Message-ID: <8b74dff67874a6c1c8d1cd9c8207db046bca985a.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Now that memory ownership rules around `git_config_string()` and `git_config_pathname()` are clearer, it also got easier to spot that the returned memory needs to be free'd. Plug a subset of those cases and mark now-passing tests as leak free. Signed-off-by: Patrick Steinhardt --- alias.c | 4 ++- config.c | 36 +++++++++++++++----- t/t1306-xdg-files.sh | 1 + t/t1350-config-hooks-path.sh | 1 + t/t3415-rebase-autosquash.sh | 1 + t/t4041-diff-submodule-option.sh | 1 + t/t4060-diff-submodule-option-diff-format.sh | 1 + t/t4210-log-i18n.sh | 2 ++ t/t6006-rev-list-format.sh | 1 + t/t7005-editor.sh | 1 + t/t7102-reset.sh | 1 + t/t9129-git-svn-i18n-commitencoding.sh | 1 - t/t9139-git-svn-non-utf8-commitencoding.sh | 1 - 13 files changed, 40 insertions(+), 12 deletions(-) diff --git a/alias.c b/alias.c index 269892c356..4daafd9bda 100644 --- a/alias.c +++ b/alias.c @@ -21,9 +21,11 @@ static int config_alias_cb(const char *key, const char *value, return 0; if (data->alias) { - if (!strcasecmp(p, data->alias)) + if (!strcasecmp(p, data->alias)) { + FREE_AND_NULL(data->v); return git_config_string(&data->v, key, value); + } } else if (data->list) { string_list_append(data->list, p); } diff --git a/config.c b/config.c index da52a7f8a1..496cd1a61e 100644 --- a/config.c +++ b/config.c @@ -1414,8 +1414,10 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.attributesfile")) + if (!strcmp(var, "core.attributesfile")) { + FREE_AND_NULL(git_attributes_file); return git_config_pathname(&git_attributes_file, var, value); + } if (!strcmp(var, "core.hookspath")) { if (ctx->kvi && ctx->kvi->scope == CONFIG_SCOPE_LOCAL && @@ -1428,6 +1430,7 @@ static int git_default_core_config(const char *var, const char *value, "again with " "`GIT_CLONE_PROTECTION_ACTIVE=false`"), value); + FREE_AND_NULL(git_hooks_path); return git_config_pathname(&git_hooks_path, var, value); } @@ -1576,8 +1579,10 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.editor")) + if (!strcmp(var, "core.editor")) { + FREE_AND_NULL(editor_program); return git_config_string(&editor_program, var, value); + } if (!strcmp(var, "core.commentchar") || !strcmp(var, "core.commentstring")) { @@ -1595,11 +1600,13 @@ static int git_default_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.askpass")) + if (!strcmp(var, "core.askpass")) { + FREE_AND_NULL(askpass_program); return git_config_string(&askpass_program, var, value); + } if (!strcmp(var, "core.excludesfile")) { - free(excludes_file); + FREE_AND_NULL(excludes_file); return git_config_pathname(&excludes_file, var, value); } @@ -1702,11 +1709,15 @@ static int git_default_sparse_config(const char *var, const char *value) static int git_default_i18n_config(const char *var, const char *value) { - if (!strcmp(var, "i18n.commitencoding")) + if (!strcmp(var, "i18n.commitencoding")) { + FREE_AND_NULL(git_commit_encoding); return git_config_string(&git_commit_encoding, var, value); + } - if (!strcmp(var, "i18n.logoutputencoding")) + if (!strcmp(var, "i18n.logoutputencoding")) { + FREE_AND_NULL(git_log_output_encoding); return git_config_string(&git_log_output_encoding, var, value); + } /* Add other config variables here and to Documentation/config.txt. */ return 0; @@ -1779,10 +1790,15 @@ static int git_default_push_config(const char *var, const char *value) static int git_default_mailmap_config(const char *var, const char *value) { - if (!strcmp(var, "mailmap.file")) + if (!strcmp(var, "mailmap.file")) { + FREE_AND_NULL(git_mailmap_file); return git_config_pathname(&git_mailmap_file, var, value); - if (!strcmp(var, "mailmap.blob")) + } + + if (!strcmp(var, "mailmap.blob")) { + FREE_AND_NULL(git_mailmap_blob); return git_config_string(&git_mailmap_blob, var, value); + } /* Add other config variables here and to Documentation/config.txt. */ return 0; @@ -1790,8 +1806,10 @@ static int git_default_mailmap_config(const char *var, const char *value) static int git_default_attr_config(const char *var, const char *value) { - if (!strcmp(var, "attr.tree")) + if (!strcmp(var, "attr.tree")) { + FREE_AND_NULL(git_attr_tree); return git_config_string(&git_attr_tree, var, value); + } /* * Add other attribute related config variables here and to diff --git a/t/t1306-xdg-files.sh b/t/t1306-xdg-files.sh index 40d3c42618..53e5b290b9 100755 --- a/t/t1306-xdg-files.sh +++ b/t/t1306-xdg-files.sh @@ -7,6 +7,7 @@ test_description='Compatibility with $XDG_CONFIG_HOME/git/ files' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'read config: xdg file exists and ~/.gitconfig doesn'\''t' ' diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh index f6dc83e2aa..5c47f9ecc3 100755 --- a/t/t1350-config-hooks-path.sh +++ b/t/t1350-config-hooks-path.sh @@ -2,6 +2,7 @@ test_description='Test the core.hooksPath configuration variable' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'set up a pre-commit hook in core.hooksPath' ' diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index fcc40d6fe1..22452ff84c 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -5,6 +5,7 @@ test_description='auto squash' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-rebase.sh diff --git a/t/t4041-diff-submodule-option.sh b/t/t4041-diff-submodule-option.sh index 0c1502d4b0..8fc40e75eb 100755 --- a/t/t4041-diff-submodule-option.sh +++ b/t/t4041-diff-submodule-option.sh @@ -12,6 +12,7 @@ This test tries to verify the sanity of the --submodule option of git diff. GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Tested non-UTF-8 encoding diff --git a/t/t4060-diff-submodule-option-diff-format.sh b/t/t4060-diff-submodule-option-diff-format.sh index 97c6424cd5..8ce67442d9 100755 --- a/t/t4060-diff-submodule-option-diff-format.sh +++ b/t/t4060-diff-submodule-option-diff-format.sh @@ -10,6 +10,7 @@ test_description='Support for diff format verbose submodule difference in git di This test tries to verify the sanity of --submodule=diff option of git diff. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Tested non-UTF-8 encoding diff --git a/t/t4210-log-i18n.sh b/t/t4210-log-i18n.sh index 75216f19ce..7120030b5c 100755 --- a/t/t4210-log-i18n.sh +++ b/t/t4210-log-i18n.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test log with i18n features' + +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gettext.sh # two forms of é diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 573eb97a0f..f1623b1c06 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -8,6 +8,7 @@ test_description='git rev-list --pretty=format test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index 5fcf281dfb..b9822294fe 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -2,6 +2,7 @@ test_description='GIT_EDITOR, core.editor, and stuff' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh unset EDITOR VISUAL GIT_EDITOR diff --git a/t/t7102-reset.sh b/t/t7102-reset.sh index 62d9f846ce..2add26d768 100755 --- a/t/t7102-reset.sh +++ b/t/t7102-reset.sh @@ -10,6 +10,7 @@ Documented tests for git reset' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit_msg () { diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 185248a4cd..01e1e8a8f7 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -4,7 +4,6 @@ test_description='git svn honors i18n.commitEncoding in config' -TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh compare_git_head_with () { diff --git a/t/t9139-git-svn-non-utf8-commitencoding.sh b/t/t9139-git-svn-non-utf8-commitencoding.sh index b7f756b2b7..22d80b0be2 100755 --- a/t/t9139-git-svn-non-utf8-commitencoding.sh +++ b/t/t9139-git-svn-non-utf8-commitencoding.sh @@ -4,7 +4,6 @@ test_description='git svn refuses to dcommit non-UTF8 messages' -TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh # ISO-2022-JP can pass for valid UTF-8, so skipping that in this test From patchwork Mon May 27 11:46:49 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675099 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BCFB715DBD8 for ; Mon, 27 May 2024 11:46:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810416; cv=none; b=WjAqYztK6fZW32wmd1mvKoeDZcONzWmKZI51D/lP51Bl5umXd4KJyp3FxQakCWni0J+yu3OSesHnFd/ZBc88duycwm5LEvw6H1kemy+Vrh08EcnXQO8P6gJhnfHfg3nMF+ETOIaRvetmLmmwtVkVo1+84UW/SocDx6ReYnsA7zc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810416; c=relaxed/simple; bh=7R5ZlvTNCXKGEJXrFExF+bgnI/w9LJxPq7rLO+oRnyU=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=PZntVrMh3O/9g06UQZ1CBTzQv0ajUdznfZYTlTpw1hvB85nXzLOmz7mr98BIiNfctlPL31gej1v2eUyRJX1bXryXjywpgTGF8F/SZNWk2mlnPtB9NxPXe/rzm3AKSMcMpaE7704r/PZCfY4gdUpcISHyPuHCvDohjzWoZKzoUno= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=jQbeyBbT; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=HXS5KBhg; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="jQbeyBbT"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="HXS5KBhg" Received: from compute7.internal (compute7.nyi.internal [10.202.2.48]) by mailfhigh.west.internal (Postfix) with ESMTP id F29CB1800097; Mon, 27 May 2024 07:46:53 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute7.internal (MEProxy); Mon, 27 May 2024 07:46:54 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810413; x=1716896813; bh=xlTExEJObo 4eH8b/JdHQW2kZvXikME6x3CW4Y1CEEok=; b=jQbeyBbTpilWsPvTuaKm7WH8fz tm32r7JnbG/a88T9Yx7ptpMpZQ5y97QzlKZRbtsU+dRobJkKjIAQsp3A6brx3oLD mUX/MfjrWKZL5QlTpXkh9CvDVY1V8yk5lNTmAXqs/F6T79ZrvzGJVoNMJsZBVkEL 3IXswR0+TeBEeOCk8NqMXx8qgs8sCloXi4KEN9wUbIHma/+cypZ1ay8zkC//NNad JoAlbPPQkoNNLjgpF8sV+pwJWmolW/RfV4rhbUubqWSmDKMh0DT6ytSLx2McScYU lMXIYHLBJw7VQZzikpLjpXfCO1BCMDncAcg7/fs6mI2Bku9XiCLe/zFaK3JA== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810413; x=1716896813; bh=xlTExEJObo4eH8b/JdHQW2kZvXik ME6x3CW4Y1CEEok=; b=HXS5KBhgZQ1eA9fibIntZGNfRmElVbpetu7SE7px/Feq 0KtgahUz76hnKyGSkl2Yb9Z4AredD4RslujGnEC4ifuEhm2StRKyLlPVwMAyf07i 7Y6vGt8qGi665oCjoqGQrUfPp1FAnExvA6Ok1cwexNGwgGsOP3j+A9ynmato4Pqv dP81kKC7/7y9zpun6Ep7tXdGf95b4lmbuxu1V6OLqHeN1X/5eK4mP4z6zdVSPT2W 4CXvStTIL9qG39nTByA+eOhhqoEcwL3J+kMqg5BNmaFDBIugA0U+moUk69BX6DFh eP2lczGtBT7HiL5AwxWK7USxsejditF/Jppbi6O+rA== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepfeenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:52 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 765db800 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:41 +0000 (UTC) Date: Mon, 27 May 2024 13:46:49 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 14/21] builtin/credential: clear credential before exit Message-ID: <265665fe6cb7dc56bb637624910369f2bd0525e8.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We never release memory associated with `struct credential`. Fix this and mark the corresponding test as leak free. Signed-off-by: Patrick Steinhardt --- builtin/credential.c | 2 ++ t/t0300-credentials.sh | 2 ++ 2 files changed, 4 insertions(+) diff --git a/builtin/credential.c b/builtin/credential.c index 5100d441f2..b72e76dd9a 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -39,5 +39,7 @@ int cmd_credential(int argc, const char **argv, const char *prefix UNUSED) } else { usage(usage_msg); } + + credential_clear(&c); return 0; } diff --git a/t/t0300-credentials.sh b/t/t0300-credentials.sh index 432f029d48..6a76b7fdbd 100755 --- a/t/t0300-credentials.sh +++ b/t/t0300-credentials.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='basic credential helper tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-credential.sh From patchwork Mon May 27 11:46:54 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675100 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 47A59152DF2 for ; Mon, 27 May 2024 11:46:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810420; cv=none; b=MEZOjyq3XTMu65DpdkmPWWU8WFcGHXX01K9rzXeI9ZxeF28TsxUWsBVNK/SN7cBhZCjNOchgYP/+df73lWJssGpxIegDwBNKr2jmlyHIOvLDh06xlvSm69ufEtaavx42KZ5V6NJoVW2T65hxPXNooBQqOoTEuZdOH19levdc6Dk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810420; c=relaxed/simple; bh=25OWtudykoFW6FginvwK+AkqS/6JMn9cV1tmksr63oo=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=nYIg8QckEJN5JawSlFd0l+52tvgh6HVlP7GUXo1WMaMIiRCx1a4LQShPELMgNj4vjCBBXAvyHhccryRqmKR0LlNd0VyvaHXZnh3XWjQMaW2bGMDAiFRrX1g0Kriw17Dp4V2SgIerjsrQ2UIDMbHt82ZKapMYk18nBBuFaGr13/Q= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=mKVJ2oU9; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=Eew416w6; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="mKVJ2oU9"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="Eew416w6" Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailfhigh.west.internal (Postfix) with ESMTP id 6032B180009D; Mon, 27 May 2024 07:46:58 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Mon, 27 May 2024 07:46:58 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810418; x=1716896818; bh=Wwmx38uv0I OGM2/l3KO+mPGzb3zGvLTPlOmg9a7V20w=; b=mKVJ2oU9qKVZhq+gqDJ2oZWRND DvLsdLcwyApPRZvzSOAEl/aE/c3+UOm1jLr8f0oJMwAArv6hf0m5Ts4hnk3EMfgm Q0gSJtRaLY6x18pNnLbwERzFy5OHJGWMWlDdDZBUP9KILd2O4XzTxrJRGLEZogEE xoEAskSyp465LWW5/VO0UQCykhS9PQEjFwKLH1OGrVk4QHDUMY9O0pwHLZYRc0KO ZSkiDqmUFdI/W4KU2mphz4fLgJoZuw30WN3QaMSoaIto54g1gF17EtaDpq9Iwfxi skee9qopUkNUSvx07Uto42sK7sSixBNuLngdxK22JcYmL7DW/OMGv/KRC2Pg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810418; x=1716896818; bh=Wwmx38uv0IOGM2/l3KO+mPGzb3zG vLTPlOmg9a7V20w=; b=Eew416w6uktW3rVQZm/6XBxMeaCpDCDk+RO/3H/vSl4M dJKTmex00oSMRnuauug7mPnkuDnfwjwHBivDT8LcD7ukJ/x2RdcjwkPZfyDkj2Qw AiHdmqj9CdrsyUHeJN0arua3v4t/tb8RKhRmDhZi+XIUtbPEmcTJ/OkURjnNFDJH Ow2ONDu1G8vpHHdZfwWTXieZVQj5JkBNyJ4TgspX9uPWdkZTs70EvesJxMpIjLJM JXMsY+9ydUVo/XDiqBHLe454MZTll6DatgBLGSituREtrx4Th+moMogqB1HOvbQL fixg2o+sOy0lHBhola969GskJDWkMu+q43I6x4+4uQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:46:56 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 68661363 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:46 +0000 (UTC) Date: Mon, 27 May 2024 13:46:54 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 15/21] commit-reach: fix memory leak in `ahead_behind()` Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: We use a priority queue in `ahead_behind()` to compute the ahead/behind count for commits. We may not iterate through all commits part of that queue though in case all of its entries are stale. Consequently, as we never make the effort to release the remaining commits, we end up leaking bit arrays that we have allocated for each of the contained commits. Plug this leak and mark the corresponding test as leak free. Signed-off-by: Patrick Steinhardt --- commit-reach.c | 4 ++++ t/t3203-branch-output.sh | 2 ++ 2 files changed, 6 insertions(+) diff --git a/commit-reach.c b/commit-reach.c index 8f9b008f87..384aee1ab3 100644 --- a/commit-reach.c +++ b/commit-reach.c @@ -1106,6 +1106,10 @@ void ahead_behind(struct repository *r, /* STALE is used here, PARENT2 is used by insert_no_dup(). */ repo_clear_commit_marks(r, PARENT2 | STALE); + while (prio_queue_peek(&queue)) { + struct commit *c = prio_queue_get(&queue); + free_bit_array(c); + } clear_bit_arrays(&bit_arrays); clear_prio_queue(&queue); } diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 758963b189..e627f08a17 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git branch display tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-terminal.sh From patchwork Mon May 27 11:46:59 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675101 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8B6BD152DF2 for ; Mon, 27 May 2024 11:47:04 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810426; cv=none; b=ajJRutKak/1UsoF61TilWKqHUH78iFV/1p8ijIZDdWHtucC5Nzwtp7q6zhzuRopUW5gj2cwGDNHsSoocxwFwg2SXseiHjmWXOEQIyKANMoY8llqJsFbHJAtnb6hZhN1SUsN6vvqOBr97NsZ+FrLyeeT6CnUnggAxKoikfeyJHEA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810426; c=relaxed/simple; bh=PmA316NJ/7qpKJ735+/ssBzNOrYrsDUhLCxl4zQjn+c=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=QXj6J0Im4HpElnNx4jixN/4+ASQLjxcszDmIJxU0guCMzxXnnZeLBWlm+vXJgo8pX+fhkBY+oF28l7RakUp3JbTV7h6iQXx8Z1iZrwfDTvw7lGvX3zEA5OARZhn+LFESW3ndAsygP4Ax3qcLWLCzPAu7sx0NHZwl0hMJxFKie0c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=b9UoFNVI; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=OOZcqsV+; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="b9UoFNVI"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="OOZcqsV+" Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailfout.west.internal (Postfix) with ESMTP id BDFA41C000C8; Mon, 27 May 2024 07:47:03 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Mon, 27 May 2024 07:47:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810423; x=1716896823; bh=Q9oS7vY43z VrV0QFJDCvCT/EUmf36M0mkn4MXXLj+EE=; b=b9UoFNVIamb1qUmFN+cDBJx/tj MSUf6fQESwAgRPYdQR54HKmdHnb08o1oGsoKf3XVAp86FB0PDCzrPd1JUKnNoXPC 83OWBlTVqA+2jnO8FnNupW7cjadxDYw8gc0aMGHa3P+M587Ti8N9bgAfoW7bTSNr WHfPn9qGqQJ/1TylFL9TPPfuikev4kuqDi7qYFqf53cc3KkGa8Qli5DZsf60Bh2U K+98v0zPHgA75Ee7md35RZlDDEqqazUYL2QIrUyvnhG0iJJCx+PMLL3BGHJnKeDc XOtlCpoSAclUhf8n7jjm0DKUJBOaMom1dl4ggtjKljttgKmiE7qt5jCRPPIQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810423; x=1716896823; bh=Q9oS7vY43zVrV0QFJDCvCT/EUmf3 6M0mkn4MXXLj+EE=; b=OOZcqsV+xhj3pKrtW1tb4b0StFox+k8tR8I2BGXqn6Hu XDOZIqnfj/6ih5ZJpvrLvZnDMv/u5JYhdUuDmgjPL0ukqbnsbdjn1RZ84BAivm1P VJD0lge9zl2+F4Sm8zRO27Ld4dFBTLyBt8F86kGYB3KtmpPDRVbNt4f5sxpRrDoc WN3AH15a/9t1e2sy1OaoRpBuJY9TDalzmAz0Qx1+Fg3VRn5j2CyFwh/251E61T0g xjHZJHQ3GaZSc4bAdhJZKF24DNJGROOTts8N0Vz+cbZCsYLZmzJ739xsiE2BxKir W0h396OJjxtTKnfXqGHbJMm/RbOVgXGN4+QIQP/XZw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:47:02 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id cd60e62a (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:51 +0000 (UTC) Date: Mon, 27 May 2024 13:46:59 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 16/21] submodule: fix leaking memory for submodule entries Message-ID: <7c75a94756c676a92a8dc719f270c692dc5a5c18.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: In `free_one_config()` we never end up freeing the `url` and `ignore` fields and thus leak memory. Fix those leaks and mark now-passing tests as leak free. Signed-off-by: Patrick Steinhardt --- submodule-config.c | 2 ++ t/t1013-read-tree-submodule.sh | 1 + t/t2013-checkout-submodule.sh | 1 + t/t3007-ls-files-recurse-submodules.sh | 1 + t/t7112-reset-submodule.sh | 1 + 5 files changed, 6 insertions(+) diff --git a/submodule-config.c b/submodule-config.c index 11428b4ada..ec45ea67b9 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -91,6 +91,8 @@ static void free_one_config(struct submodule_entry *entry) free((void *) entry->config->path); free((void *) entry->config->name); free((void *) entry->config->branch); + free((void *) entry->config->url); + free((void *) entry->config->ignore); free((void *) entry->config->update_strategy.command); free(entry->config); } diff --git a/t/t1013-read-tree-submodule.sh b/t/t1013-read-tree-submodule.sh index bfc90d4cf2..cf8b94ebed 100755 --- a/t/t1013-read-tree-submodule.sh +++ b/t/t1013-read-tree-submodule.sh @@ -2,6 +2,7 @@ test_description='read-tree can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t2013-checkout-submodule.sh b/t/t2013-checkout-submodule.sh index b2bdd1fcb4..3c1d663d94 100755 --- a/t/t2013-checkout-submodule.sh +++ b/t/t2013-checkout-submodule.sh @@ -2,6 +2,7 @@ test_description='checkout can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh diff --git a/t/t3007-ls-files-recurse-submodules.sh b/t/t3007-ls-files-recurse-submodules.sh index 61771eec83..f04bdc8c78 100755 --- a/t/t3007-ls-files-recurse-submodules.sh +++ b/t/t3007-ls-files-recurse-submodules.sh @@ -6,6 +6,7 @@ This test verifies the recurse-submodules feature correctly lists files from submodules. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup directory structure and submodules' ' diff --git a/t/t7112-reset-submodule.sh b/t/t7112-reset-submodule.sh index a3e2413bc3..b0d3d93b0b 100755 --- a/t/t7112-reset-submodule.sh +++ b/t/t7112-reset-submodule.sh @@ -2,6 +2,7 @@ test_description='reset can handle submodules' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-submodule-update.sh From patchwork Mon May 27 11:47:04 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675102 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DA75B152DF2 for ; Mon, 27 May 2024 11:47:08 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810430; cv=none; b=PVHS3PZe9d/KwNSj86bA8ejN2B9c/GgmzbUpDHM3V1Vizy2eTXkG16dKhSM1HzvgPkYbpqtOp3s5gACX253oaQXa7/IZqb/vSnAyUxN3AgAak2xULTelLP77VLhW6iy3FffwXQoIkLbHNvWicBLi753YdM2U3+TAswGmRW3RUPQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810430; c=relaxed/simple; bh=Rat0pqM2tEYaOXEn9lzkvVlrpYE83yfLKtcdbV3Rcvs=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=Skc/alcNsij8cEO7EddMriv0J52uOFv7tn7fSpxzJ8LMbiqzBv2XFmH7JZWqMpCnruLjmiyMNI04NNhOc/WY78t5niY2pJRVz1d3+Vrnd4oqn5QssKv/NepD1kpBhwZ1Q+4DzvsKdbrV1DhFXDvSEtSZrC9c+VbDmUxCv+12uMU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=GE6auMX6; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=SpgWdOpc; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="GE6auMX6"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="SpgWdOpc" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfout.west.internal (Postfix) with ESMTP id 1E70E1C000AF; Mon, 27 May 2024 07:47:08 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 27 May 2024 07:47:08 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810427; x=1716896827; bh=T4i/tw5+bc VWL8EsYgyjcjMyEIJ5tpRrmarDwVsXUYA=; b=GE6auMX6qgMaQiQxGwahW51YFd Pwzyx+hm/crRzRCC1s3kWMHVG6KxD/iKCfMJk3SPFTI/aPfyuRGTYFSZAmFNF9Xm XCI/soWdXnrZhDSvquYWfzXKXSVjI1sUdAZGS6ZH8xURRBIyeL6zK7q7apsz/SUx rzvAVce7lXx3wUxZGGxoUR3paxCi2NWRVbgrFQSJBANfmaORcqpGjKAvL9/3rwRw Qqj9ZbbkrQJlg793rZUKAZBF6r42B5uDmaF2G0qH+UKAMcq9/zz9LmCCMFLH1bTz T3sCjQ93UBi4EfYRUy8mEufrPCItrWpp1KKXtoMZn+1qtZyfSa3i3KtHuVnw== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810427; x=1716896827; bh=T4i/tw5+bcVWL8EsYgyjcjMyEIJ5 tpRrmarDwVsXUYA=; b=SpgWdOpcNreeeBG2NoQHm8BlUZDqdVY76e/uR0Jc+dp+ 9XoHBM0w8lQfdY/WSSmvTMTOpeN7DmrW1K/Re0FZ567iI9QOYHqkQMs2/YptcO4v cyim/Fo7OCLJWHM4BzpuuxHjKf8uo1j22w3VloJmI57it42GZAuO6J1y45O15Q7o ahXyNJU9cj7YfaX0igxhQeDZTbxfpP0Dcd/JFLX+I5YZulLQaPJ0Z9EYQteCKe9S rhVExH7qPh/N22hL5esvwLxTB8Z80U/jyIFXzV9NWuirSJ38H9BLR9gcmJrgkA9P Enzt0xGHDzUBWCkR90dCQULC18sX5Z4Kpx2A49M9Eg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepfeenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:47:06 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 59590790 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:46:56 +0000 (UTC) Date: Mon, 27 May 2024 13:47:04 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 17/21] strvec: add functions to replace and remove strings Message-ID: <0f61ee9929ab70d5231af28f118c3b395546d570.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Add two functions that allow to replace and remove strings contained in the strvec. This will be used by a subsequent commit that refactors git-mv(1). While at it, add a bunch of unit tests that cover both old and new functionality. Signed-off-by: Patrick Steinhardt --- Makefile | 1 + strvec.c | 20 +++ strvec.h | 13 ++ t/unit-tests/t-strvec.c | 269 ++++++++++++++++++++++++++++++++++++++++ t/unit-tests/test-lib.c | 13 ++ t/unit-tests/test-lib.h | 13 ++ 6 files changed, 329 insertions(+) create mode 100644 t/unit-tests/t-strvec.c diff --git a/Makefile b/Makefile index cf504963c2..d4000fb1d6 100644 --- a/Makefile +++ b/Makefile @@ -1336,6 +1336,7 @@ THIRD_PARTY_SOURCES += sha1dc/% UNIT_TEST_PROGRAMS += t-mem-pool UNIT_TEST_PROGRAMS += t-strbuf +UNIT_TEST_PROGRAMS += t-strvec UNIT_TEST_PROGRAMS += t-ctype UNIT_TEST_PROGRAMS += t-prio-queue UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS)) diff --git a/strvec.c b/strvec.c index 178f4f3748..d4073ec9fa 100644 --- a/strvec.c +++ b/strvec.c @@ -56,6 +56,26 @@ void strvec_pushv(struct strvec *array, const char **items) strvec_push(array, *items); } +const char *strvec_replace(struct strvec *array, size_t idx, const char *replacement) +{ + char *to_free; + if (idx >= array->nr) + BUG("index outside of array boundary"); + to_free = (char *) array->v[idx]; + array->v[idx] = xstrdup(replacement); + free(to_free); + return array->v[idx]; +} + +void strvec_remove(struct strvec *array, size_t idx) +{ + if (idx >= array->nr) + BUG("index outside of array boundary"); + free((char *)array->v[idx]); + memmove(array->v + idx, array->v + idx + 1, (array->nr - idx) * sizeof(char *)); + array->nr--; +} + void strvec_pop(struct strvec *array) { if (!array->nr) diff --git a/strvec.h b/strvec.h index 4715d3e51f..6c7e8b7d50 100644 --- a/strvec.h +++ b/strvec.h @@ -64,6 +64,19 @@ void strvec_pushl(struct strvec *, ...); /* Push a null-terminated array of strings onto the end of the array. */ void strvec_pushv(struct strvec *, const char **); +/** + * Replace the value at the given index with a new value. The index must be + * valid. Returns a pointer to the inserted value. + */ +const char *strvec_replace(struct strvec *array, size_t idx, const char *replacement); + +/* + * Remove the value at the given index. The remainder of the array will be + * moved to fill the resulting gap. The provided index must point into the + * array. + */ +void strvec_remove(struct strvec *array, size_t idx); + /** * Remove the final element from the array. If there are no * elements in the array, do nothing. diff --git a/t/unit-tests/t-strvec.c b/t/unit-tests/t-strvec.c new file mode 100644 index 0000000000..f17fb10d9e --- /dev/null +++ b/t/unit-tests/t-strvec.c @@ -0,0 +1,269 @@ +#include "test-lib.h" +#include "strbuf.h" +#include "strvec.h" + +#define check_strvec(vec, ...) \ + check_strvec_loc(TEST_LOCATION(), vec, __VA_ARGS__) +static void check_strvec_loc(const char *loc, struct strvec *vec, ...) +{ + va_list ap; + size_t nr = 0; + + va_start(ap, vec); + while (1) { + const char *str = va_arg(ap, const char *); + if (!str) + break; + + if (!check_uint(vec->nr, >, nr) || + !check_uint(vec->alloc, >, nr) || + !check_str(vec->v[nr], str)) { + struct strbuf msg = STRBUF_INIT; + strbuf_addf(&msg, "strvec index %"PRIuMAX, (uintmax_t) nr); + test_assert(loc, msg.buf, 0); + strbuf_release(&msg); + return; + } + + nr++; + } + + check_uint(vec->nr, ==, nr); + check_uint(vec->alloc, >=, nr); + check_pointer_eq(vec->v[nr], NULL); +} + +static void t_static_init(void) +{ + struct strvec vec = STRVEC_INIT; + check_pointer_eq(vec.v, empty_strvec); + check_uint(vec.nr, ==, 0); + check_uint(vec.alloc, ==, 0); +} + +static void t_dynamic_init(void) +{ + struct strvec vec; + strvec_init(&vec); + check_pointer_eq(vec.v, empty_strvec); + check_uint(vec.nr, ==, 0); + check_uint(vec.alloc, ==, 0); +} + +static void t_clear(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_push(&vec, "foo"); + strvec_clear(&vec); + check_pointer_eq(vec.v, empty_strvec); + check_uint(vec.nr, ==, 0); + check_uint(vec.alloc, ==, 0); +} + +static void t_push(void) +{ + struct strvec vec = STRVEC_INIT; + + strvec_push(&vec, "foo"); + check_strvec(&vec, "foo", NULL); + + strvec_push(&vec, "bar"); + check_strvec(&vec, "foo", "bar", NULL); + + strvec_clear(&vec); +} + +static void t_pushf(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushf(&vec, "foo: %d", 1); + check_strvec(&vec, "foo: 1", NULL); + strvec_clear(&vec); +} + +static void t_pushl(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + check_strvec(&vec, "foo", "bar", "baz", NULL); + strvec_clear(&vec); +} + +static void t_pushv(void) +{ + const char *strings[] = { + "foo", "bar", "baz", NULL, + }; + struct strvec vec = STRVEC_INIT; + + strvec_pushv(&vec, strings); + check_strvec(&vec, "foo", "bar", "baz", NULL); + + strvec_clear(&vec); +} + +static void t_replace_at_head(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_replace(&vec, 0, "replaced"); + check_strvec(&vec, "replaced", "bar", "baz", NULL); + strvec_clear(&vec); +} + +static void t_replace_at_tail(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_replace(&vec, 2, "replaced"); + check_strvec(&vec, "foo", "bar", "replaced", NULL); + strvec_clear(&vec); +} + +static void t_replace_in_between(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_replace(&vec, 1, "replaced"); + check_strvec(&vec, "foo", "replaced", "baz", NULL); + strvec_clear(&vec); +} + +static void t_replace_with_substring(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", NULL); + strvec_replace(&vec, 0, vec.v[0] + 1); + check_strvec(&vec, "oo", NULL); + strvec_clear(&vec); +} + +static void t_remove_at_head(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_remove(&vec, 0); + check_strvec(&vec, "bar", "baz", NULL); + strvec_clear(&vec); +} + +static void t_remove_at_tail(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_remove(&vec, 2); + check_strvec(&vec, "foo", "bar", NULL); + strvec_clear(&vec); +} + +static void t_remove_in_between(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_remove(&vec, 1); + check_strvec(&vec, "foo", "baz", NULL); + strvec_clear(&vec); +} + +static void t_pop_empty_array(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pop(&vec); + check_strvec(&vec, NULL); + strvec_clear(&vec); +} + +static void t_pop_non_empty_array(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_pushl(&vec, "foo", "bar", "baz", NULL); + strvec_pop(&vec); + check_strvec(&vec, "foo", "bar", NULL); + strvec_clear(&vec); +} + +static void t_split_empty_string(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_split(&vec, ""); + check_strvec(&vec, NULL); + strvec_clear(&vec); +} + +static void t_split_single_item(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_split(&vec, "foo"); + check_strvec(&vec, "foo", NULL); + strvec_clear(&vec); +} + +static void t_split_multiple_items(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_split(&vec, "foo bar baz"); + check_strvec(&vec, "foo", "bar", "baz", NULL); + strvec_clear(&vec); +} + +static void t_split_whitespace_only(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_split(&vec, " \t\n"); + check_strvec(&vec, NULL); + strvec_clear(&vec); +} + +static void t_split_multiple_consecutive_whitespaces(void) +{ + struct strvec vec = STRVEC_INIT; + strvec_split(&vec, "foo\n\t bar"); + check_strvec(&vec, "foo", "bar", NULL); + strvec_clear(&vec); +} + +static void t_detach(void) +{ + struct strvec vec = STRVEC_INIT; + const char **detached; + + strvec_push(&vec, "foo"); + + detached = strvec_detach(&vec); + check_str(detached[0], "foo"); + check_pointer_eq(detached[1], NULL); + + check_pointer_eq(vec.v, empty_strvec); + check_uint(vec.nr, ==, 0); + check_uint(vec.alloc, ==, 0); + + free((char *) detached[0]); + free(detached); +} + +int cmd_main(int argc, const char **argv) +{ + TEST(t_static_init(), "static initialization"); + TEST(t_dynamic_init(), "dynamic initialization"); + TEST(t_clear(), "clear"); + TEST(t_push(), "push"); + TEST(t_pushf(), "pushf"); + TEST(t_pushl(), "pushl"); + TEST(t_pushv(), "pushv"); + TEST(t_replace_at_head(), "replace at head"); + TEST(t_replace_in_between(), "replace in between"); + TEST(t_replace_at_tail(), "replace at tail"); + TEST(t_replace_with_substring(), "replace with substring"); + TEST(t_remove_at_head(), "remove at head"); + TEST(t_remove_in_between(), "remove in between"); + TEST(t_remove_at_tail(), "remove at tail"); + TEST(t_pop_empty_array(), "pop with empty array"); + TEST(t_pop_non_empty_array(), "pop with non-empty array"); + TEST(t_split_empty_string(), "split empty string"); + TEST(t_split_single_item(), "split single item"); + TEST(t_split_multiple_items(), "split multiple items"); + TEST(t_split_whitespace_only(), "split whitespace only"); + TEST(t_split_multiple_consecutive_whitespaces(), "split multiple consecutive whitespaces"); + TEST(t_detach(), "detach"); + return test_done(); +} diff --git a/t/unit-tests/test-lib.c b/t/unit-tests/test-lib.c index 66d6980ffb..3c513ce59a 100644 --- a/t/unit-tests/test-lib.c +++ b/t/unit-tests/test-lib.c @@ -318,6 +318,19 @@ int check_bool_loc(const char *loc, const char *check, int ok) union test__tmp test__tmp[2]; +int check_pointer_eq_loc(const char *loc, const char *check, int ok, + const void *a, const void *b) +{ + int ret = test_assert(loc, check, ok); + + if (!ret) { + test_msg(" left: %p", a); + test_msg(" right: %p", b); + } + + return ret; +} + int check_int_loc(const char *loc, const char *check, int ok, intmax_t a, intmax_t b) { diff --git a/t/unit-tests/test-lib.h b/t/unit-tests/test-lib.h index a8f07ae0b7..2de6d715d5 100644 --- a/t/unit-tests/test-lib.h +++ b/t/unit-tests/test-lib.h @@ -75,6 +75,18 @@ int test_assert(const char *location, const char *check, int ok); check_bool_loc(TEST_LOCATION(), #x, x) int check_bool_loc(const char *loc, const char *check, int ok); +/* + * Compare two integers. Prints a message with the two values if the + * comparison fails. NB this is not thread safe. + */ +#define check_pointer_eq(a, b) \ + (test__tmp[0].p = (a), test__tmp[1].p = (b), \ + check_pointer_eq_loc(TEST_LOCATION(), #a" == "#b, \ + test__tmp[0].p == test__tmp[1].p, \ + test__tmp[0].p, test__tmp[1].p)) +int check_pointer_eq_loc(const char *loc, const char *check, int ok, + const void *a, const void *b); + /* * Compare two integers. Prints a message with the two values if the * comparison fails. NB this is not thread safe. @@ -136,6 +148,7 @@ union test__tmp { intmax_t i; uintmax_t u; char c; + const void *p; }; extern union test__tmp test__tmp[2]; From patchwork Mon May 27 11:47:09 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675103 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 39A76152DF2 for ; Mon, 27 May 2024 11:47:14 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810435; cv=none; b=MHmG752BxK7ZkJjf46daWxtDoFXvhZ2AARsj1Dto7L40Ite4QGnCo8H/ZPwm3o6+cg72u4CbYV3JuaHz3AqT5X/qpfev3qJ7/7rfB3p2fUH15a44CXRskalpJvNkOlpE5GXpAS8hUf0YIEkAWvfXeuW3BhSGprvJI76Kdrq5Tkg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810435; c=relaxed/simple; bh=m15Q2qGLXo7dgU0rTr4Wp2tcW5g4g1+7PrlA5in7rgQ=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=DmWpPA4gMCX6jVX9LXeq9eJj3UlLHvtu+mzboLnKk0BGTAGhuvDaOuZoOB/hdI7Z7GIo55OB2yvWY/7zXFbeIyA98LtUfhNYfpc596quolJv3s+dAZlO6wQvRZf2P9zW6W2it8Qojp7MvQUCZNRK3kvgQSIlucsiOIshjO13QIs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=D1tM/KCj; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=M1KKxxHP; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="D1tM/KCj"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="M1KKxxHP" Received: from compute2.internal (compute2.nyi.internal [10.202.2.46]) by mailfout.west.internal (Postfix) with ESMTP id 7B9AD1C000AF; Mon, 27 May 2024 07:47:13 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 27 May 2024 07:47:13 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810433; x=1716896833; bh=JOu1SOFZv4 CL3KiBbCGI1sukxDE+xURPP5bBYO3jYak=; b=D1tM/KCj9zh80BamWIas81Bncx AN2fuuwBiFlUpLFHRxwf+6eWl0Pmnh6fyDYoiTL6UhFibArWx2RljkOWYauIOxZ3 pXusamiVEKEk30siQqTOdYIVABFAlPSzqhZi0ew8XprdbJ19v3lkRSAchLR4xzpS jtQROBM8CetS4QVAaKnvDGzgFjBZaFGqd23mmmNx2yhbMsYLY89LJ42WngZ3p5Tl FCEQKI/ZDR59rsXFJou8QPU0zmcFZUR/xHS8Lq8KWyZVF3tOLyrStlo5aXDXTxii ZuBKz2KdNuC/6nMaZt+DeFNn0by+Xli5jknTxKVGGC+optuWslQPBT0J+Aow== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810433; x=1716896833; bh=JOu1SOFZv4CL3KiBbCGI1sukxDE+ xURPP5bBYO3jYak=; b=M1KKxxHPDDv3yjghXRbV4sI7WLK58yAxrk3mZMMdqnQn MBe/aZZzWYP3tYBf9NqgtLdUewv1a4CPNK9MF4Udbx+8yw2NfhSOLMdehYRGxyCb SYZpn+BaEzcEoVXXJ6PCu5KzWZ0bV4E+x6dp6+Hac5a9+0ttjJXlhEhz3XOW9G1F bbjfaiv3/RWwhxiO0RWbqJr/+WW+XkcV1d538qJqCuoRC41wyLBlogj8FR/8PPns sUof0GZhWPAbdAAiJ3FKAj1jKzyQqQabzcYEIO5XmFsWZK61TH0tLnR82rqII+Em 0UuG8jin8OCQ4qJbo/DNrf7kx1NJvLIOBUAtAttKbQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:47:11 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id b787345e (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:47:01 +0000 (UTC) Date: Mon, 27 May 2024 13:47:09 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 18/21] builtin/mv: refactor `add_slash()` to always return allocated strings Message-ID: <1830e2a568d4a97c914b8fc6eafdfbb62527296d.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: The `add_slash()` function will only conditionally return an allocated string when the passed-in string did not yet have a trailing slash. This makes the memory ownership harder to track than really necessary. It's dubious whether this optimization really buys us all that much. The number of times we execute this function is bounded by the number of arguments to git-mv(1), so in the typical case we may end up saving an allocation or two. Simplify the code to unconditionally return allocated strings. Signed-off-by: Patrick Steinhardt --- builtin/mv.c | 38 ++++++++++++++++++++------------------ 1 file changed, 20 insertions(+), 18 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index 74aa9746aa..9f4c75df04 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -76,7 +76,7 @@ static const char **internal_prefix_pathspec(const char *prefix, return result; } -static const char *add_slash(const char *path) +static char *add_slash(const char *path) { size_t len = strlen(path); if (len && path[len - 1] != '/') { @@ -86,7 +86,7 @@ static const char *add_slash(const char *path) with_slash[len] = 0; return with_slash; } - return path; + return xstrdup(path); } #define SUBMODULE_WITH_GITDIR ((const char *)1) @@ -111,7 +111,7 @@ static void prepare_move_submodule(const char *src, int first, static int index_range_of_same_dir(const char *src, int length, int *first_p, int *last_p) { - const char *src_w_slash = add_slash(src); + char *src_w_slash = add_slash(src); int first, last, len_w_slash = length + 1; first = index_name_pos(the_repository->index, src_w_slash, len_w_slash); @@ -124,8 +124,8 @@ static int index_range_of_same_dir(const char *src, int length, if (strncmp(path, src_w_slash, len_w_slash)) break; } - if (src_w_slash != src) - free((char *)src_w_slash); + + free(src_w_slash); *first_p = first; *last_p = last; return last - first; @@ -141,7 +141,7 @@ static int index_range_of_same_dir(const char *src, int length, static int empty_dir_has_sparse_contents(const char *name) { int ret = 0; - const char *with_slash = add_slash(name); + char *with_slash = add_slash(name); int length = strlen(with_slash); int pos = index_name_pos(the_repository->index, with_slash, length); @@ -159,8 +159,7 @@ static int empty_dir_has_sparse_contents(const char *name) } free_return: - if (with_slash != name) - free((char *)with_slash); + free(with_slash); return ret; } @@ -178,7 +177,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) OPT_END(), }; const char **source, **destination, **dest_path, **submodule_gitfile; - const char *dst_w_slash; + char *dst_w_slash = NULL; const char **src_dir = NULL; int src_dir_nr = 0, src_dir_alloc = 0; struct strbuf a_src_dir = STRBUF_INIT; @@ -243,10 +242,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix) dst_mode = SPARSE; } } - if (dst_w_slash != dest_path[0]) { - free((char *)dst_w_slash); - dst_w_slash = NULL; - } /* Checking */ for (i = 0; i < argc; i++) { @@ -265,12 +260,14 @@ int cmd_mv(int argc, const char **argv, const char *prefix) pos = index_name_pos(the_repository->index, src, length); if (pos < 0) { - const char *src_w_slash = add_slash(src); + char *src_w_slash = add_slash(src); if (!path_in_sparse_checkout(src_w_slash, the_repository->index) && empty_dir_has_sparse_contents(src)) { + free(src_w_slash); modes[i] |= SKIP_WORKTREE_DIR; goto dir_check; } + free(src_w_slash); /* only error if existence is expected. */ if (!(modes[i] & SPARSE)) bad = _("bad source"); @@ -310,7 +307,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) dir_check: if (S_ISDIR(st.st_mode)) { - int j, dst_len, n; + char *dst_with_slash; + size_t dst_with_slash_len; + int j, n; int first = index_name_pos(the_repository->index, src, length), last; if (first >= 0) { @@ -335,19 +334,21 @@ int cmd_mv(int argc, const char **argv, const char *prefix) REALLOC_ARRAY(modes, n); REALLOC_ARRAY(submodule_gitfile, n); - dst = add_slash(dst); - dst_len = strlen(dst); + dst_with_slash = add_slash(dst); + dst_with_slash_len = strlen(dst_with_slash); for (j = 0; j < last - first; j++) { const struct cache_entry *ce = the_repository->index->cache[first + j]; const char *path = ce->name; source[argc + j] = path; destination[argc + j] = - prefix_path(dst, dst_len, path + length + 1); + prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1); memset(modes + argc + j, 0, sizeof(enum update_mode)); modes[argc + j] |= ce_skip_worktree(ce) ? SPARSE : INDEX; submodule_gitfile[argc + j] = NULL; } + + free(dst_with_slash); argc += last - first; goto act_on_entry; } @@ -565,6 +566,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("Unable to write new index file")); + free(dst_w_slash); string_list_clear(&src_for_dst, 0); string_list_clear(&dirty_paths, 0); UNLEAK(source); From patchwork Mon May 27 11:47:13 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675104 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B7EB3152DF2 for ; Mon, 27 May 2024 11:47:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810440; cv=none; b=kFF/kwT5q0S/aZ+GjvKQ+PSjElFrhupluabTNc8xPn9QXg3njUsIA7vwwHVwLdGY9svc5uGBWJH/FojcfFVCZmfBGs2Mt96xbEvo/5bSOzz5F1t4wKvb3PQZjEhVKIDiTm5fAU/OW3t4SeQ+AZGtrwFXKdWZLNTUoQ1I581j6B0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810440; c=relaxed/simple; bh=nlgcwhZC6lE3I0UiwMB5m/8MBUyXOGoMhZYk8MDseVk=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=tjFqYqJDemqWhaPi4CtrUg02FdJ8PQLrSuCzdeBs9vgw56CgwjOSm7pGgaY7djEjR6ocGPD9erfnqCu7VRySimIqr9gkkSD4WIQEAJ0E/z/mAjNR4P03wbsXff11HFb5Y66jrehcxGNXDYjXEp5Bkjg4/4q1inRtuF40AhSSA5I= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=QNCSRdzM; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=E29CONyD; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="QNCSRdzM"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="E29CONyD" Received: from compute5.internal (compute5.nyi.internal [10.202.2.45]) by mailfhigh.west.internal (Postfix) with ESMTP id CE1A5180009D; Mon, 27 May 2024 07:47:17 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute5.internal (MEProxy); Mon, 27 May 2024 07:47:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810437; x=1716896837; bh=fF3/++Yo27 6+O/gJ2QyAd1IBfI/MuLbvcVnIBTyjjQQ=; b=QNCSRdzMeBqZ/Q9agDEleMzwO1 aSSjYc4D7WFBBOQ3diqzNCm3bEZ7u5jD32dnzt6ktEOU9h5kL/NGs+ASZTk2BM2a b+0YfJl1IOQsx8liGLj9rJFBICE7tnJw0PLZ1pBrZWG3BAxT1DcQ1NmvV64SfCzM LI4CVlpatetYHndpL9fYIT0/8Xgu+FEMAcRmDab4r7PXNhQ79lTGPxhH79Qn4Qm2 6WlLOy5E0uKpRECdUMmubBq3R1wTO4dT/dJIxwkEQUcRMYsQlGXfi6h2dy+HSF+t DdQC7eOh0bG02th6+vNHGkqkKRsdI0UJsh3nqKu9s/c0H+XaeXZxb6YI7E4w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810437; x=1716896837; bh=fF3/++Yo276+O/gJ2QyAd1IBfI/M uLbvcVnIBTyjjQQ=; b=E29CONyDeAeTzZ9hrZn23oUSnpq2+sdg9DaVaJRSwHkD S1jr02GdFCLs5v8UmrMhhFgTd+A3tm9Q22VGJXmcLpMA0RWk38PX1T0eYItjneRp PlJEgzX955v0mavRvf3D4rO1njlkKn0zF+m+ddH8nE1ZK84v9x/+qm9ay0KSmS/L qLPuzpwta36+g949DzG5C7iYOIhY9xgKsxhKLluZmpoqowYwR8+R1du3vjTPMn+b dr/hCystPheFTR+qWkCoiIh2G4t3GeLEcAMjJNghjn77E1l7svp8QaQJ8RuXes8O JRTV3DPXKO0i4vth/6Qeiul7gOUVgFsM7I3aCVUxLg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepvdenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:47:16 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id 65945b32 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:47:05 +0000 (UTC) Date: Mon, 27 May 2024 13:47:13 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 19/21] builtin/mv duplicate string list memory Message-ID: <9eeafac3650d6573c4ef09ccb499b75c5de2f3d6.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: makes the next patch easier, where we will migrate to the paths being owned by a strvec. given that we are talking about command line parameters here it's also not like we have tons of allocations that this would save while at it, fix a memory leak Signed-off-by: Patrick Steinhardt --- builtin/mv.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index 9f4c75df04..12dcc0b13c 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -183,11 +183,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix) struct strbuf a_src_dir = STRBUF_INIT; enum update_mode *modes, dst_mode = 0; struct stat st, dest_st; - struct string_list src_for_dst = STRING_LIST_INIT_NODUP; + struct string_list src_for_dst = STRING_LIST_INIT_DUP; struct lock_file lock_file = LOCK_INIT; struct cache_entry *ce; - struct string_list only_match_skip_worktree = STRING_LIST_INIT_NODUP; - struct string_list dirty_paths = STRING_LIST_INIT_NODUP; + struct string_list only_match_skip_worktree = STRING_LIST_INIT_DUP; + struct string_list dirty_paths = STRING_LIST_INIT_DUP; + int ret; git_config(git_default_config, NULL); @@ -440,8 +441,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (only_match_skip_worktree.nr) { advise_on_updating_sparse_paths(&only_match_skip_worktree); - if (!ignore_errors) - return 1; + if (!ignore_errors) { + ret = 1; + goto out; + } } for (i = 0; i < argc; i++) { @@ -566,12 +569,16 @@ int cmd_mv(int argc, const char **argv, const char *prefix) COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("Unable to write new index file")); + ret = 0; + +out: free(dst_w_slash); string_list_clear(&src_for_dst, 0); string_list_clear(&dirty_paths, 0); + string_list_clear(&only_match_skip_worktree, 0); UNLEAK(source); UNLEAK(dest_path); free(submodule_gitfile); free(modes); - return 0; + return ret; } From patchwork Mon May 27 11:47:18 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675105 Received: from wfout5-smtp.messagingengine.com (wfout5-smtp.messagingengine.com [64.147.123.148]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0982415E5B9 for ; Mon, 27 May 2024 11:47:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.148 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810444; cv=none; b=DVSl8jyRb/ZEZw3hW2Tn4HDC/28uH2M5vonRWcZV12GBGPd7KMkD8gW2uFolYOkgi+RteS90hMPKppIDeZ7oeAZb+w2DAWPcRPwCsbZeOnmffbcUVPvnkRA/dRTQ2QfIytCvufQfgbdLar2WfIpTx4PrJ7iTSu53DsB3S16GDIk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810444; c=relaxed/simple; bh=vBDW+mldnNjFq3BVYrh3M7uQiCeIISx85cTtmjH6Q0w=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=BjnaT0c2ccAgxLYv0iL2iaGp2sBkeEQHbqk37PXwAg045/nmOOYi2AW9GfwIh3L4v4h0SDIEQrydz84Hx5vmCVHKG9roehMskB1d4oAOVp3+EGiyf3ahgLMuxMAx2q88w3JP3qWImRzEtQgu4L1rdv4u7OoL61lPjd3Nl5fOudw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=dG585De2; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=H0BcR5cQ; arc=none smtp.client-ip=64.147.123.148 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="dG585De2"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="H0BcR5cQ" Received: from compute3.internal (compute3.nyi.internal [10.202.2.43]) by mailfout.west.internal (Postfix) with ESMTP id 35A2B1C000CD; Mon, 27 May 2024 07:47:22 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute3.internal (MEProxy); Mon, 27 May 2024 07:47:22 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810441; x=1716896841; bh=tIZnt1NB54 EKQzEBE3VWMpIl9rOX0OA4XzwMgH2XCWE=; b=dG585De2cb+iyxyFscqe5x5eXZ yiDn48S7ogJppUEfQ9X2NnlM18yEJcemQWEoVYwxAlWD6cuiJ6esb82ouDTytr+J DaGqjtNgB/XjL+w3CWcmZJDPd6SmmIMYl2M7copTndoavF2D5Obk210+9ghVxN8M pQEZEdXAFBWIpy/ihoV4JFJ6O8cGfs1svGsBlDjqdGZXAEqn1uqof+EocCXwlExW CjzQklDdPDI1Dxf0Hdh7ViuE5D0G/vq+71bKDkbCl1qIm0/2hvQdtsGAnMYySlV9 idHW4TTCrXu4e/OyRmfRjs+ZFkSC+Tq9fsTnmYOsWl39ztj8148EYRt8pL5g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810441; x=1716896841; bh=tIZnt1NB54EKQzEBE3VWMpIl9rOX 0OA4XzwMgH2XCWE=; b=H0BcR5cQz9NBQf9z8RZJdwnphAg/Cl5qjAJXFCol76sU cwmfXX03rjA3caTTCZ3BxHV73BCq907houRm/SZAOOd8BV7liX04s9VY6PPw+eCK AAVeL7tzGidh1VKIcoPVLNJJoQDGuzoX/4KX6N6ZqpfJgpxv+Phwz8h2JnIGYT4x UHzPF+jphV78z4txvk50ZgV7kXVzJSjB5xDRTMQ03LHnYcQxE59U0Ip7ur0x0cUw l5oOIGp5ja729/k/Mf/0Vwpi6o2ZFv2u+Xyz71pkTPoOTqtDb04HLYUps+7dhcId eOza29hgjWjX7LVMs7479pUh5X0ZcGEpSE+Lx7W9iw== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepudenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:47:20 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id b1a13543 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:47:10 +0000 (UTC) Date: Mon, 27 May 2024 13:47:18 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 20/21] builtin/mv: refactor to use `struct strvec` Message-ID: <48b9d3e3436aff539e5c76c945f95067110254ff.1716810168.git.ps@pks.im> References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Memory allocation patterns in git-mv(1) are extremely hard to follow: We copy around string pointers into manually-managed arrays, some of which alias each other, but only sometimes, while we also drop some of those strings at other times without ever daring to free them. While this may be my own subjective feeling, it seems like others have given up as the code has multiple calls to `UNLEAK()`. These are not sufficient though, and git-mv(1) is still leaking all over the place even with them. Refactor the code to instead track strings in `struct strvec`. While this has the effect of effectively duplicating some of the strings without an actual need, it is way easier to reason about and fixes all of the aliasing of memory that has been going on. It allows us to get rid of the `UNLEAK()` calls and also fixes leaks that those calls did not paper over. Mark tests which are now leak-free accordingly. Signed-off-by: Patrick Steinhardt --- builtin/mv.c | 125 +++++++++++------------ t/t4001-diff-rename.sh | 4 +- t/t4043-diff-rename-binary.sh | 1 + t/t4120-apply-popt.sh | 1 + t/t6400-merge-df.sh | 1 + t/t6412-merge-large-rename.sh | 1 + t/t6426-merge-skip-unneeded-updates.sh | 1 + t/t6429-merge-sequence-rename-caching.sh | 1 + 8 files changed, 68 insertions(+), 67 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index 12dcc0b13c..e461d29ca1 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -20,6 +20,7 @@ #include "read-cache-ll.h" #include "repository.h" #include "setup.h" +#include "strvec.h" #include "submodule.h" #include "entry.h" @@ -38,42 +39,32 @@ enum update_mode { #define DUP_BASENAME 1 #define KEEP_TRAILING_SLASH 2 -static const char **internal_prefix_pathspec(const char *prefix, - const char **pathspec, - int count, unsigned flags) +static void internal_prefix_pathspec(struct strvec *out, + const char *prefix, + const char **pathspec, + int count, unsigned flags) { - int i; - const char **result; int prefixlen = prefix ? strlen(prefix) : 0; - ALLOC_ARRAY(result, count + 1); /* Create an intermediate copy of the pathspec based on the flags */ - for (i = 0; i < count; i++) { - int length = strlen(pathspec[i]); - int to_copy = length; - char *it; + for (int i = 0; i < count; i++) { + size_t length = strlen(pathspec[i]); + size_t to_copy = length; + const char *maybe_basename; + char *trimmed, *prefixed_path; + while (!(flags & KEEP_TRAILING_SLASH) && to_copy > 0 && is_dir_sep(pathspec[i][to_copy - 1])) to_copy--; - it = xmemdupz(pathspec[i], to_copy); - if (flags & DUP_BASENAME) { - result[i] = xstrdup(basename(it)); - free(it); - } else { - result[i] = it; - } - } - result[count] = NULL; + trimmed = xmemdupz(pathspec[i], to_copy); + maybe_basename = (flags & DUP_BASENAME) ? basename(trimmed) : trimmed; + prefixed_path = prefix_path(prefix, prefixlen, maybe_basename); + strvec_push(out, prefixed_path); - /* Prefix the pathspec and free the old intermediate strings */ - for (i = 0; i < count; i++) { - const char *match = prefix_path(prefix, prefixlen, result[i]); - free((char *) result[i]); - result[i] = match; + free(prefixed_path); + free(trimmed); } - - return result; } static char *add_slash(const char *path) @@ -176,7 +167,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix) OPT_BOOL(0, "sparse", &ignore_sparse, N_("allow updating entries outside of the sparse-checkout cone")), OPT_END(), }; - const char **source, **destination, **dest_path, **submodule_gitfile; + struct strvec sources = STRVEC_INIT; + struct strvec dest_paths = STRVEC_INIT; + struct strvec destinations = STRVEC_INIT; + const char **submodule_gitfile; char *dst_w_slash = NULL; const char **src_dir = NULL; int src_dir_nr = 0, src_dir_alloc = 0; @@ -201,7 +195,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) if (repo_read_index(the_repository) < 0) die(_("index file corrupt")); - source = internal_prefix_pathspec(prefix, argv, argc, 0); + internal_prefix_pathspec(&sources, prefix, argv, argc, 0); CALLOC_ARRAY(modes, argc); /* @@ -212,41 +206,39 @@ int cmd_mv(int argc, const char **argv, const char *prefix) flags = KEEP_TRAILING_SLASH; if (argc == 1 && is_directory(argv[0]) && !is_directory(argv[1])) flags = 0; - dest_path = internal_prefix_pathspec(prefix, argv + argc, 1, flags); - dst_w_slash = add_slash(dest_path[0]); + internal_prefix_pathspec(&dest_paths, prefix, argv + argc, 1, flags); + dst_w_slash = add_slash(dest_paths.v[0]); submodule_gitfile = xcalloc(argc, sizeof(char *)); - if (dest_path[0][0] == '\0') + if (dest_paths.v[0][0] == '\0') /* special case: "." was normalized to "" */ - destination = internal_prefix_pathspec(dest_path[0], argv, argc, DUP_BASENAME); - else if (!lstat(dest_path[0], &st) && - S_ISDIR(st.st_mode)) { - destination = internal_prefix_pathspec(dst_w_slash, argv, argc, DUP_BASENAME); + internal_prefix_pathspec(&destinations, dest_paths.v[0], argv, argc, DUP_BASENAME); + else if (!lstat(dest_paths.v[0], &st) && S_ISDIR(st.st_mode)) { + internal_prefix_pathspec(&destinations, dst_w_slash, argv, argc, DUP_BASENAME); + } else if (!path_in_sparse_checkout(dst_w_slash, the_repository->index) && + empty_dir_has_sparse_contents(dst_w_slash)) { + internal_prefix_pathspec(&destinations, dst_w_slash, argv, argc, DUP_BASENAME); + dst_mode = SKIP_WORKTREE_DIR; + } else if (argc != 1) { + die(_("destination '%s' is not a directory"), dest_paths.v[0]); } else { - if (!path_in_sparse_checkout(dst_w_slash, the_repository->index) && - empty_dir_has_sparse_contents(dst_w_slash)) { - destination = internal_prefix_pathspec(dst_w_slash, argv, argc, DUP_BASENAME); - dst_mode = SKIP_WORKTREE_DIR; - } else if (argc != 1) { - die(_("destination '%s' is not a directory"), dest_path[0]); - } else { - destination = dest_path; - /* - * is a file outside of sparse-checkout - * cone. Insist on cone mode here for backward - * compatibility. We don't want dst_mode to be assigned - * for a file when the repo is using no-cone mode (which - * is deprecated at this point) sparse-checkout. As - * SPARSE here is only considering cone-mode situation. - */ - if (!path_in_cone_mode_sparse_checkout(destination[0], the_repository->index)) - dst_mode = SPARSE; - } + strvec_pushv(&destinations, dest_paths.v); + + /* + * is a file outside of sparse-checkout + * cone. Insist on cone mode here for backward + * compatibility. We don't want dst_mode to be assigned + * for a file when the repo is using no-cone mode (which + * is deprecated at this point) sparse-checkout. As + * SPARSE here is only considering cone-mode situation. + */ + if (!path_in_cone_mode_sparse_checkout(destinations.v[0], the_repository->index)) + dst_mode = SPARSE; } /* Checking */ for (i = 0; i < argc; i++) { - const char *src = source[i], *dst = destination[i]; + const char *src = sources.v[i], *dst = destinations.v[i]; int length; const char *bad = NULL; int skip_sparse = 0; @@ -330,8 +322,6 @@ int cmd_mv(int argc, const char **argv, const char *prefix) src_dir[src_dir_nr++] = src; n = argc + last - first; - REALLOC_ARRAY(source, n); - REALLOC_ARRAY(destination, n); REALLOC_ARRAY(modes, n); REALLOC_ARRAY(submodule_gitfile, n); @@ -341,12 +331,16 @@ int cmd_mv(int argc, const char **argv, const char *prefix) for (j = 0; j < last - first; j++) { const struct cache_entry *ce = the_repository->index->cache[first + j]; const char *path = ce->name; - source[argc + j] = path; - destination[argc + j] = - prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1); + char *prefixed_path = prefix_path(dst_with_slash, dst_with_slash_len, path + length + 1); + + strvec_push(&sources, path); + strvec_push(&destinations, prefixed_path); + memset(modes + argc + j, 0, sizeof(enum update_mode)); modes[argc + j] |= ce_skip_worktree(ce) ? SPARSE : INDEX; submodule_gitfile[argc + j] = NULL; + + free(prefixed_path); } free(dst_with_slash); @@ -430,8 +424,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) remove_entry: if (--argc > 0) { int n = argc - i; - MOVE_ARRAY(source + i, source + i + 1, n); - MOVE_ARRAY(destination + i, destination + i + 1, n); + strvec_remove(&sources, i); + strvec_remove(&destinations, i); MOVE_ARRAY(modes + i, modes + i + 1, n); MOVE_ARRAY(submodule_gitfile + i, submodule_gitfile + i + 1, n); @@ -448,7 +442,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) } for (i = 0; i < argc; i++) { - const char *src = source[i], *dst = destination[i]; + const char *src = sources.v[i], *dst = destinations.v[i]; enum update_mode mode = modes[i]; int pos; int sparse_and_dirty = 0; @@ -576,8 +570,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix) string_list_clear(&src_for_dst, 0); string_list_clear(&dirty_paths, 0); string_list_clear(&only_match_skip_worktree, 0); - UNLEAK(source); - UNLEAK(dest_path); + strvec_clear(&sources); + strvec_clear(&dest_paths); + strvec_clear(&destinations); free(submodule_gitfile); free(modes); return ret; diff --git a/t/t4001-diff-rename.sh b/t/t4001-diff-rename.sh index 49c042a38a..cd1931dd55 100755 --- a/t/t4001-diff-rename.sh +++ b/t/t4001-diff-rename.sh @@ -3,9 +3,9 @@ # Copyright (c) 2005 Junio C Hamano # -test_description='Test rename detection in diff engine. +test_description='Test rename detection in diff engine.' -' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4043-diff-rename-binary.sh b/t/t4043-diff-rename-binary.sh index 2a2cf91352..e486493908 100755 --- a/t/t4043-diff-rename-binary.sh +++ b/t/t4043-diff-rename-binary.sh @@ -5,6 +5,7 @@ test_description='Move a binary file' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh diff --git a/t/t4120-apply-popt.sh b/t/t4120-apply-popt.sh index 697e86c0ff..f788428540 100755 --- a/t/t4120-apply-popt.sh +++ b/t/t4120-apply-popt.sh @@ -5,6 +5,7 @@ test_description='git apply -p handling.' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6400-merge-df.sh b/t/t6400-merge-df.sh index 3de4ef6bd9..27d6efdc9a 100755 --- a/t/t6400-merge-df.sh +++ b/t/t6400-merge-df.sh @@ -7,6 +7,7 @@ test_description='Test merge with directory/file conflicts' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'prepare repository' ' diff --git a/t/t6412-merge-large-rename.sh b/t/t6412-merge-large-rename.sh index ca018d11f5..d0863a8fb5 100755 --- a/t/t6412-merge-large-rename.sh +++ b/t/t6412-merge-large-rename.sh @@ -4,6 +4,7 @@ test_description='merging with large rename matrix' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh count() { diff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh index b059475ed0..62f0180325 100755 --- a/t/t6426-merge-skip-unneeded-updates.sh +++ b/t/t6426-merge-skip-unneeded-updates.sh @@ -22,6 +22,7 @@ test_description="merge cases" # underscore notation is to differentiate different # files that might be renamed into each other's paths.) +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-merge.sh diff --git a/t/t6429-merge-sequence-rename-caching.sh b/t/t6429-merge-sequence-rename-caching.sh index 0f39ed0d08..cb1c4ceef7 100755 --- a/t/t6429-merge-sequence-rename-caching.sh +++ b/t/t6429-merge-sequence-rename-caching.sh @@ -2,6 +2,7 @@ test_description="remember regular & dir renames in sequence of merges" +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # From patchwork Mon May 27 11:47:23 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 13675106 Received: from wfhigh8-smtp.messagingengine.com (wfhigh8-smtp.messagingengine.com [64.147.123.159]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5F67A15DBBA for ; Mon, 27 May 2024 11:47:28 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=64.147.123.159 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810449; cv=none; b=TMC7q5f3PRM5Av94o2LL0nhKCsI5NiGVr1jxKIH8hqkpD9TcUf1bbPcpDvMtYHPCWw7+fQni5lttoZAD7E9lmPr1iqrQnawRGE9t0B2MDINIw/Ur3KgWbjpkRiOYaUjy7EA7I/rEM3Ti8lUgV47f1ROqfK4scNRfAA721nan3/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716810449; c=relaxed/simple; bh=XmXgW/7lu7WZGZ6htfDjawGBrh6IiEkLGYak7K4Lfb4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=P7oeqnaDb7pKfCf6erptbmcr4P4gxIWOyVtedundO6bLsIfPddk+raV6To8UUPcUq6sS5fY4yXR3XI5p3+FRdox+7TIch8kXeFagnrCENXHK7uSAS63p40TCeIKqDHJemNgtMOulNvBqgb3oVIFC0AYPV5OSKicINwj5aaNEwRs= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im; spf=pass smtp.mailfrom=pks.im; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b=gfhbSLq+; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b=V73BlRuq; arc=none smtp.client-ip=64.147.123.159 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=pks.im Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=pks.im Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=pks.im header.i=@pks.im header.b="gfhbSLq+"; dkim=pass (2048-bit key) header.d=messagingengine.com header.i=@messagingengine.com header.b="V73BlRuq" Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailfhigh.west.internal (Postfix) with ESMTP id 9BB7D180009D; Mon, 27 May 2024 07:47:27 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Mon, 27 May 2024 07:47:27 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=cc:cc :content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm1; t=1716810447; x=1716896847; bh=+MkkcJTIFU hHaGabDj71Ke+65SyieN1SBmpiPwcIl9U=; b=gfhbSLq+YDEVtSRpPbWxCNbIum 5rfTMovdXT9XzJnRCYDToFwyW4agw0QkzN8E38B3yu3GB6YhgkILr4BNCJElAm3g 8uFODHzqdHVWjzAgyx7q3PJ/Nh5wvsl+GAomHgkpXo7wLSyahB7ctNPY67V7dhii PHf2VvkbIkrg+598G4zyTtIXZ59trIe0WK5LskixyoqvStYbfz/XBXWzLXIfYdwB fhZRT9RzKJWQXLQ8A/ahWrUxUI1aGrK1GIqEb3qsl0erRKXfTuStqmRCDvK74ihv D/W77ocissWIuEhdjGTvPUMlsjw7ynGyeNR0PvTZ/RrixeHwSMNfewXf4/Qg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm1; t=1716810447; x=1716896847; bh=+MkkcJTIFUhHaGabDj71Ke+65Syi eN1SBmpiPwcIl9U=; b=V73BlRuqPbYLImJLvTjzf9VuljvuQ+6VUVp1m1VPbQyV bFNpmlwZ4wqaVKVvgEmz1WT86jn/i6b1fHprCN8HCiJ3jgm9lqeekzU6UsI4so+a 6S8kwynhOrDRsd27ihlqR60RlBhvfO+W+/UtgRDZsRyQ2W2stiE5VNoEJ7751CS4 5rROAbB+6wNPXLoRLuJq6lom9JOybHbgvIhNT80UqePYj2xyUCzDyGMWBGOIN4DA OfeBUfN9oP8ZmE8aB6qGfBJ37rZ7NNOA1Ur/YD9/UkEIW22izAJokazeZG0l6+S5 lk3GqhaEYFUDEphTlVEprVUqj5oxqDcrOCEaCWgLFQ== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedvledrvdejgedggeefucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvfevuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepueektdevtdffveeljeetgfehheeigeekleduvdeffeeghefgledttdehjeelffet necuvehluhhsthgvrhfuihiivgepgeenucfrrghrrghmpehmrghilhhfrhhomhepphhsse hpkhhsrdhimh X-ME-Proxy: Feedback-ID: i197146af:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Mon, 27 May 2024 07:47:25 -0400 (EDT) Received: by localhost (OpenSMTPD) with ESMTPSA id ade32d89 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Mon, 27 May 2024 11:47:15 +0000 (UTC) Date: Mon, 27 May 2024 13:47:23 +0200 From: Patrick Steinhardt To: git@vger.kernel.org Cc: Eric Sunshine , Junio C Hamano , Karthik Nayak , Jeff King Subject: [PATCH v3 21/21] builtin/mv: fix leaks for submodule gitfile paths Message-ID: References: Precedence: bulk X-Mailing-List: git@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Similar to the preceding commit, we have effectively given tracking memory ownership of submodule gitfile paths. Refactor the code to start tracking allocated strings in a separate `struct strvec` such that we can easily plug those leaks. Mark now-passing tests as leak free. Note that ideally, we wouldn't require two separate data structures to track those paths. But we do need to store `NULL` pointers for the gitfile paths such that we can indicate that its corresponding entries in the other arrays do not have such a path at all. And given that `struct strvec`s cannot store `NULL` pointers we cannot use them to store this information. There is another small gotcha that is easy to miss: you may be wondering why we don't want to store `SUBMODULE_WITH_GITDIR` in the strvec. This is because this is a mere sentinel value and not actually a string at all. Signed-off-by: Patrick Steinhardt --- builtin/mv.c | 44 +++++++++++++---------- t/t4059-diff-submodule-not-initialized.sh | 1 + t/t7001-mv.sh | 2 ++ t/t7417-submodule-path-url.sh | 1 + t/t7421-submodule-summary-add.sh | 1 + 5 files changed, 30 insertions(+), 19 deletions(-) diff --git a/builtin/mv.c b/builtin/mv.c index e461d29ca1..81ca910de6 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -82,21 +82,23 @@ static char *add_slash(const char *path) #define SUBMODULE_WITH_GITDIR ((const char *)1) -static void prepare_move_submodule(const char *src, int first, - const char **submodule_gitfile) +static const char *submodule_gitfile_path(const char *src, int first) { struct strbuf submodule_dotgit = STRBUF_INIT; + const char *path; + if (!S_ISGITLINK(the_repository->index->cache[first]->ce_mode)) die(_("Directory %s is in index and no submodule?"), src); if (!is_staging_gitmodules_ok(the_repository->index)) die(_("Please stage your changes to .gitmodules or stash them to proceed")); + strbuf_addf(&submodule_dotgit, "%s/.git", src); - *submodule_gitfile = read_gitfile(submodule_dotgit.buf); - if (*submodule_gitfile) - *submodule_gitfile = xstrdup(*submodule_gitfile); - else - *submodule_gitfile = SUBMODULE_WITH_GITDIR; + + path = read_gitfile(submodule_dotgit.buf); strbuf_release(&submodule_dotgit); + if (path) + return path; + return SUBMODULE_WITH_GITDIR; } static int index_range_of_same_dir(const char *src, int length, @@ -170,7 +172,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) struct strvec sources = STRVEC_INIT; struct strvec dest_paths = STRVEC_INIT; struct strvec destinations = STRVEC_INIT; - const char **submodule_gitfile; + struct strvec submodule_gitfiles_to_free = STRVEC_INIT; + const char **submodule_gitfiles; char *dst_w_slash = NULL; const char **src_dir = NULL; int src_dir_nr = 0, src_dir_alloc = 0; @@ -208,7 +211,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) flags = 0; internal_prefix_pathspec(&dest_paths, prefix, argv + argc, 1, flags); dst_w_slash = add_slash(dest_paths.v[0]); - submodule_gitfile = xcalloc(argc, sizeof(char *)); + submodule_gitfiles = xcalloc(argc, sizeof(char *)); if (dest_paths.v[0][0] == '\0') /* special case: "." was normalized to "" */ @@ -306,8 +309,10 @@ int cmd_mv(int argc, const char **argv, const char *prefix) int first = index_name_pos(the_repository->index, src, length), last; if (first >= 0) { - prepare_move_submodule(src, first, - submodule_gitfile + i); + const char *path = submodule_gitfile_path(src, first); + if (path != SUBMODULE_WITH_GITDIR) + path = strvec_push(&submodule_gitfiles_to_free, path); + submodule_gitfiles[i] = path; goto act_on_entry; } else if (index_range_of_same_dir(src, length, &first, &last) < 1) { @@ -323,7 +328,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) n = argc + last - first; REALLOC_ARRAY(modes, n); - REALLOC_ARRAY(submodule_gitfile, n); + REALLOC_ARRAY(submodule_gitfiles, n); dst_with_slash = add_slash(dst); dst_with_slash_len = strlen(dst_with_slash); @@ -338,7 +343,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix) memset(modes + argc + j, 0, sizeof(enum update_mode)); modes[argc + j] |= ce_skip_worktree(ce) ? SPARSE : INDEX; - submodule_gitfile[argc + j] = NULL; + submodule_gitfiles[argc + j] = NULL; free(prefixed_path); } @@ -427,8 +432,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) strvec_remove(&sources, i); strvec_remove(&destinations, i); MOVE_ARRAY(modes + i, modes + i + 1, n); - MOVE_ARRAY(submodule_gitfile + i, - submodule_gitfile + i + 1, n); + MOVE_ARRAY(submodule_gitfiles + i, + submodule_gitfiles + i + 1, n); i--; } } @@ -462,12 +467,12 @@ int cmd_mv(int argc, const char **argv, const char *prefix) continue; die_errno(_("renaming '%s' failed"), src); } - if (submodule_gitfile[i]) { + if (submodule_gitfiles[i]) { if (!update_path_in_gitmodules(src, dst)) gitmodules_modified = 1; - if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR) + if (submodule_gitfiles[i] != SUBMODULE_WITH_GITDIR) connect_work_tree_and_git_dir(dst, - submodule_gitfile[i], + submodule_gitfiles[i], 1); } @@ -573,7 +578,8 @@ int cmd_mv(int argc, const char **argv, const char *prefix) strvec_clear(&sources); strvec_clear(&dest_paths); strvec_clear(&destinations); - free(submodule_gitfile); + strvec_clear(&submodule_gitfiles_to_free); + free(submodule_gitfiles); free(modes); return ret; } diff --git a/t/t4059-diff-submodule-not-initialized.sh b/t/t4059-diff-submodule-not-initialized.sh index d489230df8..668f526303 100755 --- a/t/t4059-diff-submodule-not-initialized.sh +++ b/t/t4059-diff-submodule-not-initialized.sh @@ -9,6 +9,7 @@ This test tries to verify that add_submodule_odb works when the submodule was initialized previously but the checkout has since been removed. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # Tested non-UTF-8 encoding diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 879a6dce60..86258f9f43 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git mv in subdirs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff-data.sh diff --git a/t/t7417-submodule-path-url.sh b/t/t7417-submodule-path-url.sh index 5e3051da8b..dbbb3853dc 100755 --- a/t/t7417-submodule-path-url.sh +++ b/t/t7417-submodule-path-url.sh @@ -4,6 +4,7 @@ test_description='check handling of .gitmodule path with dash' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t7421-submodule-summary-add.sh b/t/t7421-submodule-summary-add.sh index ce64d8b137..479c8fdde1 100755 --- a/t/t7421-submodule-summary-add.sh +++ b/t/t7421-submodule-summary-add.sh @@ -10,6 +10,7 @@ while making sure to add submodules using `git submodule add` instead of `git add` as done in t7401. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' '