From patchwork Wed Dec 16 07:52:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976889 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id CFB33C4361B for ; Wed, 16 Dec 2020 07:53:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7609423343 for ; Wed, 16 Dec 2020 07:53:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725815AbgLPHxg (ORCPT ); Wed, 16 Dec 2020 02:53:36 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:59827 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725769AbgLPHxg (ORCPT ); Wed, 16 Dec 2020 02:53:36 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 5EA225C00F5; Wed, 16 Dec 2020 02:52:45 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Wed, 16 Dec 2020 02:52:45 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=l8X5sAsYliYiJqTcndbVaPVaDUG Ae7OIaTrD0eQYB4c=; b=aSEwzgd24bQOeDi60qnPGEToeyvn1pngDox/eGpK5/g ajAyQVTVGiSsxJ9KtgoHDUBQFqEPthdkzyJVQ3/NcTZBER+JWpTrijYCwSEJxRm9 wqVslT6glO4FTTYHdOAM/ZLBqG1kRMNEN21iZ32huRNUlOlw8CZnMQ9NYDjZPk3S YlLsZNRKV2NtJsQRqD6Dncg3K//mapIqLdkSBujQrrN/q4bTRHVTeEbPII+cixMU glGtZs1qtrt5Lj1HMb4UEMF6BsRK9U0LqvdPu085JRTWK4tlin1T2AHHl03Je9dw YDwrlvPqGPDUx/9+/CYhQO9X3JU7pardcl3mmFGcQMQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=l8X5sA sYliYiJqTcndbVaPVaDUGAe7OIaTrD0eQYB4c=; b=m7drmgFpf8q1Au0xss7nii ri8GTin5dTiDerUaR2bkvSkTDnP76KCa6rby8jODOqE9puXE7KYAyjc0YxxNlA3M JrASVLTqTFrGpsiI7Q+ykClYRBc3HxlTxxcKuJm3wS1QrAP6nrbWZ9JMiHvdMzje 7hXo2qFtNI4r1nJp9HpFsHPn2HGm3rbmXCdqldSq2iJGgomjb0LxKj9cMqWniVjc IwM5474Xb562NpxtB683+kazPA8vSd+gMw71IVVIv5IDxMll1VEYZLJVdgQb6m09 mted2yDkuRLu0lrDtNHddK8sDuw3CQgdwMXQTz003MLzzIAsBjAS0ywhVRVNNSJQ == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduudcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedtnecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 6EDB81080063; Wed, 16 Dec 2020 02:52:44 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id fed1397d (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:52:44 +0000 (UTC) Date: Wed, 16 Dec 2020 08:52:42 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 1/8] git: add `--super-prefix` to usage string Message-ID: <470521e72865d7043fe0f1ce0f3e39a146fa2805.1608104755.git.ps@pks.im> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org When the `--super-prefix` option was implmented in 74866d7579 (git: make super-prefix option, 2016-10-07), its existence was only documented in the manpage but not in the command's own usage string. Given that the commit message didn't mention that this was done intentionally and given that it's documented in the manpage, this seems like an oversight. Add it to the usage string to fix the inconsistency. Signed-off-by: Patrick Steinhardt --- git.c | 1 + 1 file changed, 1 insertion(+) diff --git a/git.c b/git.c index a00a0a4d94..5a8ff12f87 100644 --- a/git.c +++ b/git.c @@ -29,6 +29,7 @@ const char git_usage_string[] = " [--exec-path[=]] [--html-path] [--man-path] [--info-path]\n" " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n" " [--git-dir=] [--work-tree=] [--namespace=]\n" + " [--super-prefix=]\n" " []"); const char git_more_info_string[] = From patchwork Wed Dec 16 07:52:47 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976893 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9886EC0018C for ; Wed, 16 Dec 2020 07:53:38 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4D15623356 for ; Wed, 16 Dec 2020 07:53:38 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725825AbgLPHxh (ORCPT ); Wed, 16 Dec 2020 02:53:37 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:55707 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725806AbgLPHxh (ORCPT ); Wed, 16 Dec 2020 02:53:37 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 725775C0108; Wed, 16 Dec 2020 02:52:50 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute1.internal (MEProxy); Wed, 16 Dec 2020 02:52:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=07YHmD6le/5VvIXUHrHbb1hlFbh 5i3RcLiaiDGl4wBA=; b=yE9H8kULMDWfGfxyWqr7GF5k2Mi6CCpqvenBYrrChLs bqf2TGgDsL3fCn2+3qUREsGybb/1UMyGL0UFvHA9iA0i7qezoL59RL3vf0gWiOUS Br/wcVnq1kpkcDdzzf2B93VIAWMLWCx599cbNcIqs/6bsUioXYJEoSVcq8Ys73ML 68GBIUjOPpv88LzCEz27lJJ2k6DfXr7GIyqN8jzzNYSkFizE9e8hKOssBorBMuiE ow19DrvMrcD1y/U/VGrMe82yJTu7hcwZmRkGoskih4kiLvSXdUyMbVlyh06N7IwH BKamAfgj4SobaZ96LG1rAArMYPa4CC7i/UrTyFWwo4A== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=07YHmD 6le/5VvIXUHrHbb1hlFbh5i3RcLiaiDGl4wBA=; b=bS8lPuAsBWEp8Ali5pjla4 EqSAM6Wkcgff1CwK4E73enRTUPtVWKAINYhDSTm/YJ1yfW+64ENZAyb9aALmNYtu SOnMmkRHBM6ozWw1l2E6idCNSbySPCRBdl+Y5cWwOqd+aRq/dBZOyRxE8RYjSzJC PrKVx6C/A0nmELGtUhrtB08tokqXY+mUXLu5BgMzxWa1iroKk3pdwmlDuT5OJjgZ SvpDGl34aS2uhqg8/pBO3iJe4NqlKSJYIZ4cJBSOKTdhLUk7W9Z7Dqgbr5wuP+un oZboluPV2vOsFI9//YJ3Amkc4mN2qYnHb8Nwhvd17oBUjV/+pLgImYE3Jiki8kcg == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduudcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedunecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 753321080059; Wed, 16 Dec 2020 02:52:49 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id 9bf4b233 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:52:48 +0000 (UTC) Date: Wed, 16 Dec 2020 08:52:47 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 2/8] config: add new way to pass config via `--config-env` Message-ID: <56c9221c4cc8c3e52823938938e3f65a3433f9bf.1608104755.git.ps@pks.im> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org While it's already possible to pass runtime configuration via `git -c =`, it may be undesirable to use when the value contains sensitive information. E.g. if one wants to set `http.extraHeader` to contain an authentication token, doing so via `-c` would trivially leak those credentials via e.g. ps(1), which typically also shows command arguments. To enable this usecase without leaking credentials, this commit introduces a new switch `--config-env==`. Instead of directly passing a value for the given key, it instead allows the user to specify the name of an environment variable. The value of that variable will then be used as value of the key. Co-authored-by: Jeff King Signed-off-by: Patrick Steinhardt --- Documentation/git.txt | 23 +++++++++++++++++++++- config.c | 21 ++++++++++++++++++++ config.h | 1 + git.c | 4 +++- t/t1300-config.sh | 45 +++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 92 insertions(+), 2 deletions(-) diff --git a/Documentation/git.txt b/Documentation/git.txt index c463b937a8..80fb8fab11 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -13,7 +13,7 @@ SYNOPSIS [--exec-path[=]] [--html-path] [--man-path] [--info-path] [-p|--paginate|-P|--no-pager] [--no-replace-objects] [--bare] [--git-dir=] [--work-tree=] [--namespace=] - [--super-prefix=] + [--super-prefix=] [--config-env =] [] DESCRIPTION @@ -80,6 +80,27 @@ config file). Including the equals but with an empty value (like `git -c foo.bar= ...`) sets `foo.bar` to the empty string which `git config --type=bool` will convert to `false`. +--config-env==:: + Like `-c =` except the value is the name of an + environment variable from which to retrieve the value. Unlike + `-c` there is no shortcut for directly setting the value to an + empty string, instead the environment variable itself must be + set to the empty strin. Errors if the `` does not exist + in the environment. `` may not contain an equals sign + to avoid ambiguity with ``s which contain one. + + This is useful for cases where you want to pass transitory + configuration options to git, but are doing so on OS's where + other processes might be able to read your cmdline + (e.g. `/proc/self/cmdline`), but not your environ + (e.g. `/proc/self/environ`). That behavior is the default on + Linux, but may not be on your system. + + Note that this might add security for variables such as + `http.extraHeader` where the sensitive information is part of + the value, but not e.g. `url.]:: Path to wherever your core Git programs are installed. This can also be controlled by setting the GIT_EXEC_PATH diff --git a/config.c b/config.c index 1137bd73af..cde3511110 100644 --- a/config.c +++ b/config.c @@ -345,6 +345,27 @@ void git_config_push_parameter(const char *text) strbuf_release(&env); } +void git_config_push_env(const char *spec) +{ + struct strbuf buf = STRBUF_INIT; + const char *env_name; + const char *env_value; + + env_name = strrchr(spec, '='); + if (!env_name) + die("invalid config format: %s", spec); + env_name++; + + env_value = getenv(env_name); + if (!env_value) + die("config variable missing for '%s'", env_name); + + strbuf_add(&buf, spec, env_name - spec); + strbuf_addstr(&buf, env_value); + git_config_push_parameter(buf.buf); + strbuf_release(&buf); +} + static inline int iskeychar(int c) { return isalnum(c) || c == '-'; diff --git a/config.h b/config.h index c1449bb790..19a9adbaa9 100644 --- a/config.h +++ b/config.h @@ -138,6 +138,7 @@ int git_config_from_mem(config_fn_t fn, int git_config_from_blob_oid(config_fn_t fn, const char *name, const struct object_id *oid, void *data); void git_config_push_parameter(const char *text); +void git_config_push_env(const char *spec); int git_config_from_parameters(config_fn_t fn, void *data); void read_early_config(config_fn_t cb, void *data); void read_very_early_config(config_fn_t cb, void *data); diff --git a/git.c b/git.c index 5a8ff12f87..b5f63d346b 100644 --- a/git.c +++ b/git.c @@ -29,7 +29,7 @@ const char git_usage_string[] = " [--exec-path[=]] [--html-path] [--man-path] [--info-path]\n" " [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--bare]\n" " [--git-dir=] [--work-tree=] [--namespace=]\n" - " [--super-prefix=]\n" + " [--super-prefix=] [--config-env==]\n" " []"); const char git_more_info_string[] = @@ -255,6 +255,8 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) git_config_push_parameter((*argv)[1]); (*argv)++; (*argc)--; + } else if (skip_prefix(cmd, "--config-env=", &cmd)) { + git_config_push_env(cmd); } else if (!strcmp(cmd, "--literal-pathspecs")) { setenv(GIT_LITERAL_PATHSPECS_ENVIRONMENT, "1", 1); if (envchanged) diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 97a04c6cc2..46a94814d5 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1316,6 +1316,51 @@ test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' ' git config --get-regexp "env.*" ' +test_expect_success 'git --config-env=key=envvar support' ' + cat >expect <<-\EOF && + value + value + false + EOF + { + env ENVVAR=value git --config-env=core.name=ENVVAR config core.name && + env ENVVAR=value git --config-env=foo.CamelCase=ENVVAR config foo.camelcase && + env ENVVAR= git --config-env=foo.flag=ENVVAR config --bool foo.flag + } >actual && + test_cmp expect actual +' + +test_expect_success 'git --config-env fails with invalid parameters' ' + test_must_fail git --config-env=foo.flag config --bool foo.flag 2>error && + test_i18ngrep "invalid config format" error && + test_must_fail git --config-env=foo.flag=NONEXISTENT config --bool foo.flag 2>error && + test_i18ngrep "config variable missing" error +' + +test_expect_success 'git -c and --config-env work together' ' + cat >expect <<-\EOF && + bar.cmd cmd-value + bar.env env-value + EOF + env ENVVAR=env-value git \ + -c bar.cmd=cmd-value \ + --config-env=bar.env=ENVVAR \ + config --get-regexp "^bar.*" >actual && + test_cmp expect actual +' + +test_expect_success 'git -c and --config-env override each other' ' + cat >expect <<-\EOF && + env + cmd + EOF + { + env ENVVAR=env git -c bar.bar=cmd --config-env=bar.bar=ENVVAR config bar.bar && + env ENVVAR=env git --config-env=bar.bar=ENVVAR -c bar.bar=cmd config bar.bar + } >actual && + test_cmp expect actual +' + test_expect_success 'git config --edit works' ' git config -f tmp test.value no && echo test.value=yes >expect && From patchwork Wed Dec 16 07:56:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976901 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0728AC0018C for ; Wed, 16 Dec 2020 07:58:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id C792023356 for ; Wed, 16 Dec 2020 07:58:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725807AbgLPH56 (ORCPT ); Wed, 16 Dec 2020 02:57:58 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:46239 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725766AbgLPH56 (ORCPT ); Wed, 16 Dec 2020 02:57:58 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id B8D9C5C00F3; Wed, 16 Dec 2020 02:56:51 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute4.internal (MEProxy); Wed, 16 Dec 2020 02:56:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=Y8skt/h+vU0SG+xVY01huWkoueF y0HN3e+AHyMaVz5k=; b=iBWhNFYFZTQJBpQ5exlmE9KMQegjH9flj6S5rEjmY6E PdzCIi8cXkooJXG5yMTQFHKuMME/UbCGLlvPDM1LehTqQyS7u5JS4gd63YnX/AJk y7lR6PEdSrCzDiG0PDa3RQwUb9P19ahL81y0rHziGP1Ox3yjNjFlveU0Rg6UAJ2V SSTELel2DeQSo5Rn+nZ9luW389bdd3a4PKtZbfiEJ8XLqWPj6SBHW+rLhQqr7nxl ol+7E+RAEKtk4Rx88CAYuqhhixXqS1Vp1axrz+s7ShZOPVUfMkE5fe9AW7X5Xj4B QIiIntKNGtZc/AhPH4rUB3PLwp6BSbR6T1lJkaxy85Q== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=Y8skt/ h+vU0SG+xVY01huWkoueFy0HN3e+AHyMaVz5k=; b=bonofKWFFjKHNyJ3GcEIUj gYa0qgxsJa1I0GOHpmeuqSsH2DuKpK5gtzciXWLFBG9pUEv38BZHyEDzw2kvGh1u YmbtrVneEEbWLDNVew0LhBjMneu0HzTVS8Qx2//Ii9RP+C1tHxRMTC2NPeWSo136 8BB/F8j6dEFweU48mFiXDwqtrb1cM/Aa1OU2Q+0MFQoFwXyMITD2oxW/BGlHQTL3 Mhm9r7qSFsVNx7V5rdop0lGMAJrzv9W7aJqOUlKUEluQuJ83/oBdaJyxXnL8X5Ch bzLSqXNhZ6C0OJo+g9FLPl0bzKdvfj/CtyG6SfOYJj48D+1KO5iwpGPJMSH3lfdg == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedvnecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 6280324005D; Wed, 16 Dec 2020 02:56:50 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id c8229289 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:56:49 +0000 (UTC) Date: Wed, 16 Dec 2020 08:56:48 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 3/8] quote: make sq_dequote_step() a public function Message-ID: <5729f5d406311ec139b1827fc2419255e296921a.1608104755.git.ps@pks.im> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Jeff King We provide a function for dequoting an entire string, as well as one for handling a space-separated list of quoted strings. But there's no way for a caller to parse a string like 'foo'='bar', even though it is easy to generate one using sq_quote_buf() or similar. Let's make the single-step function available to callers outside of quote.c. Note that we do need to adjust its implementation slightly: it insists on seeing whitespace between items, and we'd like to be more flexible than that. Since it only has a single caller, we can move that check (and slurping up any extra whitespace) into that caller. Signed-off-by: Jeff King --- quote.c | 15 ++++++++++----- quote.h | 18 ++++++++++++++++-- 2 files changed, 26 insertions(+), 7 deletions(-) diff --git a/quote.c b/quote.c index 69f4ca45da..8a3a5e39eb 100644 --- a/quote.c +++ b/quote.c @@ -116,7 +116,7 @@ void sq_append_quote_argv_pretty(struct strbuf *dst, const char **argv) } } -static char *sq_dequote_step(char *arg, char **next) +char *sq_dequote_step(char *arg, char **next) { char *dst = arg; char *src = arg; @@ -153,11 +153,8 @@ static char *sq_dequote_step(char *arg, char **next) } /* Fallthrough */ default: - if (!next || !isspace(*src)) + if (!next) return NULL; - do { - c = *++src; - } while (isspace(c)); *dst = 0; *next = src; return arg; @@ -182,6 +179,14 @@ static int sq_dequote_to_argv_internal(char *arg, char *dequoted = sq_dequote_step(next, &next); if (!dequoted) return -1; + if (next) { + char c; + if (!isspace(*next)) + return -1; + do { + c = *++next; + } while (isspace(c)); + } if (argv) { ALLOC_GROW(*argv, *nr + 1, *alloc); (*argv)[(*nr)++] = dequoted; diff --git a/quote.h b/quote.h index 4b72a583cf..768cc6338e 100644 --- a/quote.h +++ b/quote.h @@ -42,12 +42,26 @@ void sq_quote_buf_pretty(struct strbuf *, const char *src); void sq_quote_argv_pretty(struct strbuf *, const char **argv); void sq_append_quote_argv_pretty(struct strbuf *dst, const char **argv); -/* This unwraps what sq_quote() produces in place, but returns +/* + * This unwraps what sq_quote() produces in place, but returns * NULL if the input does not look like what sq_quote would have - * produced. + * produced (the full string must be a single quoted item). */ char *sq_dequote(char *); +/* + * Like sq_dequote(), but dequote a single item, and leave "next" pointing to + * the next character. E.g., in the string: + * + * 'one' 'two' 'three' + * + * after the first call, the return value would be the unquoted string "one", + * with "next" pointing to the space between "one" and "two"). The caller is + * responsible for advancing the pointer to the start of the next item before + * calling sq_dequote_step() again. + */ +char *sq_dequote_step(char *src, char **next); + /* * Same as the above, but can be used to unwrap many arguments in the * same string separated by space. Like sq_quote, it works in place, From patchwork Wed Dec 16 07:54:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976895 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5F5D5C4361B for ; Wed, 16 Dec 2020 07:55:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0A0C723356 for ; Wed, 16 Dec 2020 07:55:16 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726086AbgLPHzQ (ORCPT ); Wed, 16 Dec 2020 02:55:16 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:48789 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725806AbgLPHzQ (ORCPT ); Wed, 16 Dec 2020 02:55:16 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 178255C00E6; Wed, 16 Dec 2020 02:54:30 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Wed, 16 Dec 2020 02:54:30 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=TcxgDcvcIMp6dnvTQPIhL2nq8CL UXRflIDU3c2il5gE=; b=FfzvotNhLgBUqlbSRgJUJ2y0Er0En9cD1vtq64CZMfJ 93l7AHlJdfuAcyl3UUwho20h9BztA3u+nDkEXfqV0I/qW53YVr0aSx5ZrGw5RGgb QO5nAqNAtX4yYbn5Qj93W/Fxn3apj4YHQ5R29O3WlWLoEqoQld3oJ+/w7ooQ/Q3Q +VZBUbVbaimMIy7Vo95jdD86UICwOUYlMFFb9EpmFaw+Sd3K5Bb1xWQjZQ6hItB+ 5nizceLMK0CP2bJ/AV4TjImymPsWRs8HgiblnQiwCAV6+r7ywu9BWNzlemv3EcYo EPylE9qzgGL1NsTGaIk7h7MC/YGy9Zpdd4lD9NHX1lg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=TcxgDc vcIMp6dnvTQPIhL2nq8CLUXRflIDU3c2il5gE=; b=oJ6AoWZ3nk8XxTZET4Tnqz BSsRThrFH9wojr1nMzf9eJ2F3+fVoALE49C6lMdZDlG+j/UHEAMWtAqQXf0OgM+i wVUR2OwDrHGcyaGX/ABlx0NEnxdFOvfzAJ9ZZYofO5KITsZHFDcA4JZeHQfeok4M X9gDKeRD1+oJm6ad+US6D8hp2qol230+iEXc27s4oGaHtpLMOy9eNBjiMcS0QuSM XpIi9XfC/K4/2rJrrcraxiB04ibgWtR2vgD4IbajMgGZR0CYbaFQXEd+J3rrVbke u9m3apVnVneVcc0XfxPcEIkwYhZJVBcOknb4walekWTUovorTUmmBnq9SjaDkv5w == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedtnecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 53F1D240057; Wed, 16 Dec 2020 02:54:28 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id 9c28d087 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:54:27 +0000 (UTC) Date: Wed, 16 Dec 2020 08:54:26 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 4/8] config: extract function to parse config pairs Message-ID: <8c6cdd57a0f92442c3cbd5317af06586cda8d411.1608104755.git.ps@pks.im> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The function `git_config_parse_parameter` is responsible for parsing a `foo.bar=baz`-formatted configuration key, sanitizing the key and then processing it via the given callback function. Given that we're about to add a second user which is going to process keys which already has keys and values separated, this commit extracts a function `config_parse_pair` which only does the sanitization and processing part as a preparatory step. Signed-off-by: Patrick Steinhardt --- config.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/config.c b/config.c index cde3511110..151980e5c9 100644 --- a/config.c +++ b/config.c @@ -458,11 +458,26 @@ int git_config_key_is_valid(const char *key) return !git_config_parse_key_1(key, NULL, NULL, 1); } +static int config_parse_pair(const char *key, const char *value, + config_fn_t fn, void *data) +{ + char *canonical_name; + int ret; + + if (!strlen(key)) + return error(_("empty config key")); + if (git_config_parse_key(key, &canonical_name, NULL)) + return -1; + + ret = (fn(canonical_name, value, data) < 0) ? -1 : 0; + free(canonical_name); + return ret; +} + int git_config_parse_parameter(const char *text, config_fn_t fn, void *data) { const char *value; - char *canonical_name; struct strbuf **pair; int ret; @@ -483,12 +498,7 @@ int git_config_parse_parameter(const char *text, return error(_("bogus config parameter: %s"), text); } - if (git_config_parse_key(pair[0]->buf, &canonical_name, NULL)) { - ret = -1; - } else { - ret = (fn(canonical_name, value, data) < 0) ? -1 : 0; - free(canonical_name); - } + ret = config_parse_pair(pair[0]->buf, value, fn, data); strbuf_list_free(pair); return ret; } From patchwork Wed Dec 16 07:56:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976905 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2C67CC2BBCD for ; Wed, 16 Dec 2020 07:58:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E848F23357 for ; Wed, 16 Dec 2020 07:58:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725815AbgLPH6J (ORCPT ); Wed, 16 Dec 2020 02:58:09 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:41297 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725766AbgLPH6J (ORCPT ); Wed, 16 Dec 2020 02:58:09 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 5E2AB5C010C; Wed, 16 Dec 2020 02:57:02 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Wed, 16 Dec 2020 02:57:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=sFcvO5DAwuuNPMGf+HZb7wNbRmW 2t6VdsxgI0w+oOIw=; b=PA56ouJ0+MpiSIKMfuCUMGl3vC1vhRnOTToOu6kRJaz IcScT7mAHEcJam3QkirqFEcyyF/C4zK8YJIO6/SJX9ocm1Goe7T4SB5wElDxktkL lqOdM6Ef07tjsQNaO7YE3LeNdfDULjAUjg68vsbRJvPAPK7bppxfITyl32Zn134c Ho5W5krWb7527eat621m3z3b790IE9le+/FLaURunW1yUyruqpZauxm9SfCG05D0 ri4eEhPN/aIhgPp2UQbT6ur9GNrfAyKoXgJqg630L+qQ4P3e0etD/LpqDqd21d+F Y8G9F6KLcSUkfeXsuKYyXB9xcCOCmeUsPiWfVRTrxPQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=sFcvO5 DAwuuNPMGf+HZb7wNbRmW2t6VdsxgI0w+oOIw=; b=K5mo+u9bQTY8tL0u3xik1Q jQwVaiW0chEH5SyEzuCE643gyiC0FuuHAVeQ0DDtqfvl3c0izOz67GXd1vN0sgY7 ORGNyqzkpskRA18BPEl8utX3vlRq9MPwkauj9rQvvbvdCJmI4S6SDTdHpm1Xn+jp VT9KYzIpI8SKNweHwjldQvHYYjpanuriDY8BqfJtZgYVV1PdbLeWu1Awpw3lMz5u PQoLNNwbhyg6zDjmXs4cgUE3lnd7Ac8vdr6RE+k6uHakjhpA85BSbYWwliJwqAwQ islaevSb1vA8MSKbRllYXqpmUc7CFubip/Rt0C3as5fBQXhA+b5HRdsor1TtP8Dw == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedunecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 73EC024005A; Wed, 16 Dec 2020 02:57:00 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id 3832cef5 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:57:00 +0000 (UTC) Date: Wed, 16 Dec 2020 08:56:58 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 5/8] config: store "git -c" variables using more robust format Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Jeff King The previous commit added a new format for $GIT_CONFIG_PARAMETERS which is able to robustly handle subsections with "=" in them. Let's start writing the new format. Unfortunately, this does much less than you'd hope, because "git -c" itself has the same ambiguity problem! But it's still worth doing: - we've now pushed the problem from the inter-process communication into the "-c" command-line parser. This would free us up to later add an unambiguous format there (e.g., separate arguments like "git --config key value", etc). - for --config-env, the parser already disallows "=" in the environment variable name. So: git --config-env section.with=equals.key=ENVVAR will robustly set section.with=equals.key to the contents of $ENVVAR. The new test shows the improvement for --config-env. Signed-off-by: Jeff King --- config.c | 52 ++++++++++++++++++++++++++++++++++++++++------- t/t1300-config.sh | 8 ++++++++ 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/config.c b/config.c index 151980e5c9..53ed048689 100644 --- a/config.c +++ b/config.c @@ -332,7 +332,7 @@ int git_config_include(const char *var, const char *value, void *data) return ret; } -void git_config_push_parameter(const char *text) +static void git_config_push_split_parameter(const char *key, const char *value) { struct strbuf env = STRBUF_INIT; const char *old = getenv(CONFIG_DATA_ENVIRONMENT); @@ -340,30 +340,68 @@ void git_config_push_parameter(const char *text) strbuf_addstr(&env, old); strbuf_addch(&env, ' '); } - sq_quote_buf(&env, text); + sq_quote_buf(&env, key); + strbuf_addch(&env, '='); + if (value) + sq_quote_buf(&env, value); setenv(CONFIG_DATA_ENVIRONMENT, env.buf, 1); strbuf_release(&env); } +void git_config_push_parameter(const char *text) +{ + const char *value; + + /* + * When we see: + * + * section.subsection=with=equals.key=value + * + * we cannot tell if it means: + * + * [section "subsection=with=equals"] + * key = value + * + * or: + * + * [section] + * subsection = with=equals.key=value + * + * We parse left-to-right for the first "=", meaning we'll prefer to + * keep the value intact over the subsection. This is historical, but + * also sensible since values are more likely to contain odd or + * untrusted input than a section name. + * + * A missing equals is explicitly allowed (as a bool-only entry). + */ + value = strchr(text, '='); + if (value) { + char *key = xmemdupz(text, value - text); + git_config_push_split_parameter(key, value + 1); + free(key); + } else { + git_config_push_split_parameter(text, NULL); + } +} + void git_config_push_env(const char *spec) { - struct strbuf buf = STRBUF_INIT; + char *key; const char *env_name; const char *env_value; env_name = strrchr(spec, '='); if (!env_name) die("invalid config format: %s", spec); + key = xmemdupz(spec, env_name - spec); env_name++; env_value = getenv(env_name); if (!env_value) die("config variable missing for '%s'", env_name); - strbuf_add(&buf, spec, env_name - spec); - strbuf_addstr(&buf, env_value); - git_config_push_parameter(buf.buf); - strbuf_release(&buf); + git_config_push_split_parameter(key, env_value); + free(key); } static inline int iskeychar(int c) diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 46a94814d5..36a60879f6 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1361,6 +1361,14 @@ test_expect_success 'git -c and --config-env override each other' ' test_cmp expect actual ' +test_expect_success '--config-env handles keys with equals' ' + echo value=with=equals >expect && + ENVVAR=value=with=equals git \ + --config-env=section.subsection=with=equals.key=ENVVAR \ + config section.subsection=with=equals.key >actual && + test_cmp expect actual +' + test_expect_success 'git config --edit works' ' git config -f tmp test.value no && echo test.value=yes >expect && From patchwork Wed Dec 16 07:57:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976903 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E7F13C4361B for ; Wed, 16 Dec 2020 07:58:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9695623343 for ; Wed, 16 Dec 2020 07:58:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725806AbgLPH55 (ORCPT ); Wed, 16 Dec 2020 02:57:57 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:45813 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725287AbgLPH55 (ORCPT ); Wed, 16 Dec 2020 02:57:57 -0500 Received: from compute1.internal (compute1.nyi.internal [10.202.2.41]) by mailout.nyi.internal (Postfix) with ESMTP id 795315C00FD; Wed, 16 Dec 2020 02:57:10 -0500 (EST) Received: from mailfrontend1 ([10.202.2.162]) by compute1.internal (MEProxy); Wed, 16 Dec 2020 02:57:10 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=CSTjnqGa8LOTtUv/l8Ny2xg47Vi uOT81CxYypZ0yfo4=; b=nmLPGu4WB3uTXSR4Od54N4+aS4/MDertDtgIvw9Ioec 86buF2nCckjTFYXsnFJdsCzuUsTaCjvILUKMcccBDXyDTc0RNZNz52RMrNMgJ4Ly 55Nd8kON8wjECWOlp3WYemAAeb48eCnLnlmq+mM9P5xZoYOkaeKTLsYYTSmj/+M2 eVx/B6Ndy1+INGzDdaKgzrPRLmsDqxA2om9B0snGMqjSuK3ZwWyoceoeS3696aW0 0eCtYBQEXzxrRCtigB33Nhjk8IX/HL4TxEQ+JyGDiSYOJPCO0Glig9gsP+KSttu4 Eu7qkkxbPHCQ6FnIwnSEqmYABhKCEBJm4qaKOUXdn4g== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=CSTjnq Ga8LOTtUv/l8Ny2xg47ViuOT81CxYypZ0yfo4=; b=Up6diENlkZAjXFMzXOQtwV /FqT4V9uQSgOfuPMz/y9cYZdjGhWPlPCtYEhxIB9fz/RhZwe+3MoQHQCuvtKqmvi P9+jPff06D9VLGwlj4zCa0PxuC5glnLlxbBehMy0m1d7saMO4vo4EpKC+MCgqmnN Njlux/Wu8SI7NM8sLID8ByvL/DD0Zgv8KBaeKqaCcDLdsPWdTAB7cR/1MrpYHCrV TnRKlFeUc1FhAjjZh1lvB7BLMmuyeys8Om2+yPbdgsA6tjTG8AZfYife+Xm/X+f4 Gx+bNGeYO+lIeoQBB8K5EzpYjcCFMm8Gxig5VXSjSlg9xOuw0UP+ZHMsVdTBfKZw == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedvnecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 82B7A24005B; Wed, 16 Dec 2020 02:57:09 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id d4d41f2b (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:57:08 +0000 (UTC) Date: Wed, 16 Dec 2020 08:57:07 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 6/8] config: parse more robust format in GIT_CONFIG_PARAMETERS Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Jeff King When we stuff config options into GIT_CONFIG_PARAMETERS, we shell-quote each one as a single unit, like: 'section.one=value1' 'section.two=value2' On the reading side, we de-quote to get the individual strings, and then parse them by splitting on the first "=" we find. This format is ambiguous, because an "=" may appear in a subsection. So the config represented in a file by both: [section "subsection=with=equals"] key = value and: [section] subsection = with=equals.key=value ends up in this flattened format like: 'section.subsection=with=equals.key=value' and we can't tell which was desired. We have traditionally resolved this by taking the first "=" we see starting from the left, meaning that we allowed arbitrary content in the value, but not in the subsection. Let's make our environment format a bit more robust by separately quoting the key and value. That turns those examples into: 'section.subsection=with=equals.key'='value' and: 'section.subsection'='with=equals.key=value' respectively, and we can tell the difference between them. We can detect which format is in use for any given element of the list based on the presence of the unquoted "=". That means we can continue to allow the old format to work to support any callers which manually used the old format, and we can even intermingle the two formats. The old format wasn't documented, and nobody was supposed to be using it. But it's likely that such callers exist in the wild, so it's nice if we can avoid breaking them. Likewise, it may be possible to trigger an older version of "git -c" that runs a script that calls into a newer version of "git -c"; that new version would see the intermingled format. This does create one complication, which is that the obvious format in the new scheme for [section] some-bool is: 'section.some-bool' with no equals. We'd mistake that for an old-style variable. And it even has the same meaning in the old style, but: [section "with=equals"] some-bool does not. It would be: 'section.with=equals=some-bool' which we'd take to mean: [section] with = equals=some-bool in the old, ambiguous style. Likewise, we can't use: 'section.some-bool'='' because that's ambiguous with an actual empty string. Instead, we'll again use the shell-quoting to give us a hint, and use: 'section.some-bool'= to show that we have no value. Note that this commit just expands the reading side. We'll start writing the new format via "git -c" in a future patch. In the meantime, the existing "git -c" tests will make sure we didn't break reading the old format. But we'll also add some explicit coverage of the two formats to make sure we continue to handle the old one after we move the writing side over. And one final note: since we're now using the shell-quoting as a semantically meaningful hint, this closes the door to us ever allowing arbitrary shell quoting, like: 'a'shell'would'be'ok'with'this'.key=value But we have never supported that (only what sq_quote() would produce), and we are probably better off keeping things simple, robust, and backwards-compatible, than trying to make it easier for humans. We'll continue not to advertise the format of the variable to users, and instead keep "git -c" as the recommended mechanism for setting config (even if we are trying to be kind not to break users who may be relying on the current undocumented format). Signed-off-by: Jeff King --- config.c | 69 +++++++++++++++++++++++++++++++++++------------ t/t1300-config.sh | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+), 17 deletions(-) diff --git a/config.c b/config.c index 53ed048689..60a7261807 100644 --- a/config.c +++ b/config.c @@ -541,14 +541,62 @@ int git_config_parse_parameter(const char *text, return ret; } +static int parse_config_env_list(char *env, config_fn_t fn, void *data) +{ + char *cur = env; + while (cur && *cur) { + const char *key = sq_dequote_step(cur, &cur); + if (!key) + return error(_("bogus format in %s"), + CONFIG_DATA_ENVIRONMENT); + + if (!cur || isspace(*cur)) { + /* old-style 'key=value' */ + if (git_config_parse_parameter(key, fn, data) < 0) + return -1; + } + else if (*cur == '=') { + /* new-style 'key'='value' */ + const char *value; + + cur++; + if (*cur == '\'') { + /* quoted value */ + value = sq_dequote_step(cur, &cur); + if (!value || (cur && !isspace(*cur))) { + return error(_("bogus format in %s"), + CONFIG_DATA_ENVIRONMENT); + } + } else if (!*cur || isspace(*cur)) { + /* implicit bool: 'key'= */ + value = NULL; + } else { + return error(_("bogus format in %s"), + CONFIG_DATA_ENVIRONMENT); + } + + if (config_parse_pair(key, value, fn, data) < 0) + return -1; + } + else { + /* unknown format */ + return error(_("bogus format in %s"), + CONFIG_DATA_ENVIRONMENT); + } + + if (cur) { + while (isspace(*cur)) + cur++; + } + } + return 0; +} + int git_config_from_parameters(config_fn_t fn, void *data) { const char *env = getenv(CONFIG_DATA_ENVIRONMENT); int ret = 0; char *envw; - const char **argv = NULL; - int nr = 0, alloc = 0; - int i; struct config_source source; if (!env) @@ -561,21 +609,8 @@ int git_config_from_parameters(config_fn_t fn, void *data) /* sq_dequote will write over it */ envw = xstrdup(env); + ret = parse_config_env_list(envw, fn, data); - if (sq_dequote_to_argv(envw, &argv, &nr, &alloc) < 0) { - ret = error(_("bogus format in %s"), CONFIG_DATA_ENVIRONMENT); - goto out; - } - - for (i = 0; i < nr; i++) { - if (git_config_parse_parameter(argv[i], fn, data) < 0) { - ret = -1; - goto out; - } - } - -out: - free(argv); free(envw); cf = source.prev; return ret; diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 36a60879f6..35a1a6e8b1 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1294,6 +1294,58 @@ test_expect_success 'git -c is not confused by empty environment' ' GIT_CONFIG_PARAMETERS="" git -c x.one=1 config --list ' +test_expect_success 'GIT_CONFIG_PARAMETERS handles old-style entries' ' + v="${SQ}key.one=foo${SQ}" && + v="$v ${SQ}key.two=bar${SQ}" && + v="$v ${SQ}key.ambiguous=section.whatever=value${SQ}" && + GIT_CONFIG_PARAMETERS=$v git config --get-regexp "key.*" >actual && + cat >expect <<-EOF && + key.one foo + key.two bar + key.ambiguous section.whatever=value + EOF + test_cmp expect actual +' + +test_expect_success 'GIT_CONFIG_PARAMETERS handles new-style entries' ' + v="${SQ}key.one${SQ}=${SQ}foo${SQ}" && + v="$v ${SQ}key.two${SQ}=${SQ}bar${SQ}" && + v="$v ${SQ}key.ambiguous=section.whatever${SQ}=${SQ}value${SQ}" && + GIT_CONFIG_PARAMETERS=$v git config --get-regexp "key.*" >actual && + cat >expect <<-EOF && + key.one foo + key.two bar + key.ambiguous=section.whatever value + EOF + test_cmp expect actual +' + +test_expect_success 'old and new-style entries can mix' ' + v="${SQ}key.oldone=oldfoo${SQ}" && + v="$v ${SQ}key.newone${SQ}=${SQ}newfoo${SQ}" && + v="$v ${SQ}key.oldtwo=oldbar${SQ}" && + v="$v ${SQ}key.newtwo${SQ}=${SQ}newbar${SQ}" && + GIT_CONFIG_PARAMETERS=$v git config --get-regexp "key.*" >actual && + cat >expect <<-EOF && + key.oldone oldfoo + key.newone newfoo + key.oldtwo oldbar + key.newtwo newbar + EOF + test_cmp expect actual +' + +test_expect_success 'old and new bools with ambiguous subsection' ' + v="${SQ}key.with=equals.oldbool${SQ}" && + v="$v ${SQ}key.with=equals.newbool${SQ}=" && + GIT_CONFIG_PARAMETERS=$v git config --get-regexp "key.*" >actual && + cat >expect <<-EOF && + key.with equals.oldbool + key.with=equals.newbool + EOF + test_cmp expect actual +' + test_expect_success 'detect bogus GIT_CONFIG_PARAMETERS' ' cat >expect <<-\EOF && env.one one From patchwork Wed Dec 16 07:54:40 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976899 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0C6CC4361B for ; Wed, 16 Dec 2020 07:56:06 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 842AA23343 for ; Wed, 16 Dec 2020 07:56:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726124AbgLPHzu (ORCPT ); Wed, 16 Dec 2020 02:55:50 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:33567 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726111AbgLPHzu (ORCPT ); Wed, 16 Dec 2020 02:55:50 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 4E2D25C00CB; Wed, 16 Dec 2020 02:54:44 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Wed, 16 Dec 2020 02:54:44 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=SasF7DXemqhWwtoSG4fnpd0ZgKW mszrzsZcnYW7E7SI=; b=T8S5kmzHoEOgWs6ShC0SocWICVQfek+8pj1fmaz+k9D WU4EdGI0pwUXADh9V9wOUAjI5gYAfYkrAzDYzm4BctRAwjnlFRN3+E/9Fq5bhRGf Z14YGg3QS1bwwFbsvtuxlDXaJqGDijl1Ude9+BZP7Y9cMtYlBO6WyZrmBvBQmIwu nlwZJMEuJ+vZOlSvYgdTOGlSlZUaMjayIQvXBlPafL4Q2QEgR/JLTnpyXg0GqJra DciyE1z5yisBscEBfK2P5zgsO+PeCyHI8Lm7h4rZG77PVe/bIKKJSshW/mbdY7Eh Qan4q6bWl9EkowGrMkiv7R+mnLNrBix0A660XcmHeOg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=SasF7D XemqhWwtoSG4fnpd0ZgKWmszrzsZcnYW7E7SI=; b=oJHgNtHtEr6KNvr1uIkt70 K8zc8FZXJ3lVMglcpv97BUm/den1RecJWS6948zW+d/Vz/3ixPsDU61vo2lvMyMm CtYhvf8SkjSvZYeB0wnG1ZzAJYEW3td+JCrOk6sqoysLZSow7hxvkNtPMDZJvQB4 eVsrozne70/bPznJAsVcZx6VetSIIfGmn6wF9ZCJ7MvRZDa6sNuWa/aLw6miskwf LDMVfhizVO7MIx68xiPwNNkcxS2msE5UTWfT3j7hz7J/8XU/m5NijPnrARVmSDby edNd0kJuXpuh3Nf3sk72yzvRSYDOtHPqQnJuuFdGjDq0fPDKbupkk8gBlOYX8gxA == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedtnecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id 9996D108005C; Wed, 16 Dec 2020 02:54:42 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id eb65c6ef (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:54:41 +0000 (UTC) Date: Wed, 16 Dec 2020 08:54:40 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 7/8] environment: make `getenv_safe()` a public function Message-ID: <2f51a0c5fca7da1a6d563da6c9747f862ba0700a.1608104755.git.ps@pks.im> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The `getenv_safe()` helper function helps to safely retrieve multiple environment values without the need to depend on platform-specific behaviour for the return value's lifetime. We'll make use of this function in a following patch, so let's make it available by making it non-static and adding a declaration. Signed-off-by: Patrick Steinhardt --- environment.c | 7 ++----- environment.h | 12 ++++++++++++ 2 files changed, 14 insertions(+), 5 deletions(-) create mode 100644 environment.h diff --git a/environment.c b/environment.c index bb518c61cd..2234af462c 100644 --- a/environment.c +++ b/environment.c @@ -9,6 +9,7 @@ */ #include "cache.h" #include "branch.h" +#include "environment.h" #include "repository.h" #include "config.h" #include "refs.h" @@ -152,11 +153,7 @@ static char *expand_namespace(const char *raw_namespace) return strbuf_detach(&buf, NULL); } -/* - * Wrapper of getenv() that returns a strdup value. This value is kept - * in argv to be freed later. - */ -static const char *getenv_safe(struct strvec *argv, const char *name) +const char *getenv_safe(struct strvec *argv, const char *name) { const char *value = getenv(name); diff --git a/environment.h b/environment.h new file mode 100644 index 0000000000..d438b5c8f3 --- /dev/null +++ b/environment.h @@ -0,0 +1,12 @@ +#ifndef ENVIRONMENT_H +#define ENVIRONMENT_H + +#include "strvec.h" + +/* + * Wrapper of getenv() that returns a strdup value. This value is kept + * in argv to be freed later. + */ +const char *getenv_safe(struct strvec *argv, const char *name); + +#endif From patchwork Wed Dec 16 07:54:48 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Patrick Steinhardt X-Patchwork-Id: 11976897 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.8 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6B752C4361B for ; Wed, 16 Dec 2020 07:55:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 12BD423357 for ; Wed, 16 Dec 2020 07:55:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726089AbgLPHzi (ORCPT ); Wed, 16 Dec 2020 02:55:38 -0500 Received: from out3-smtp.messagingengine.com ([66.111.4.27]:47259 "EHLO out3-smtp.messagingengine.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726095AbgLPHzi (ORCPT ); Wed, 16 Dec 2020 02:55:38 -0500 Received: from compute4.internal (compute4.nyi.internal [10.202.2.44]) by mailout.nyi.internal (Postfix) with ESMTP id 82F2E5C019F; Wed, 16 Dec 2020 02:54:51 -0500 (EST) Received: from mailfrontend2 ([10.202.2.163]) by compute4.internal (MEProxy); Wed, 16 Dec 2020 02:54:51 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=pks.im; h=date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=fm2; bh=mjDMbyK9y+QDamh72Yv9WL633s+ MrLsdaYcmbqK1qbw=; b=vbDW1hq1htnNWq4anV8PncKvMyBFybglCI3Y7OYc10D FkMrXBDR3Pf+JyEBWe8Iy3kjRkj19MFEfnhXM7WWBVvvXDlv9cUknf1mnJvSWZj3 DvNix+ZBOcWj06LD5336SXUIm1O//69d6Bcgc0MS0DnLofdOFNLKS63RZCtF6Aaq KDccQqk//URVI/IiGx4+v1uHO0SKE4iPyLHOjNWeVu/m3u1ZMgOOejiCNlSOLoIL NCbKpjXZjNHUhFc9zxPuZb+m5bTAobB17v2C7rc+UjtYhWPezbX92bS0jEYvRVF9 70vK56bp85O18bgTALNtwRUd0dWOKesT3FpV3AEsdhQ== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to:x-me-proxy :x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm1; bh=mjDMby K9y+QDamh72Yv9WL633s+MrLsdaYcmbqK1qbw=; b=pVckOGDCOxroPdY84zF3v7 xdNUDHjNMXvgpPdhx2ksKi9RotYbVk+qV2KmriykcLW4g/mL2eqPHB+xChz7uxbR qqbY/AlQBQqQQoH7i5YaVhI0iFnRzU2GkAIfu30d5Eg3Lv+eVJ1W9vZw737Br5ol ECDWJMwDeYTD1ULFE2RtWD8bX6dxE1yEAoKbyE7nH2zOr74lIBFBLNyHd4HOabfd oZezY3ZYrGdAmQOaTDO3So5ulovZ8mP7r126CKl9M1MI4dNG4B2+I+mvrgBWH4hv uwjHIPVX5GfutrKC4JJjfuUApHZhGqTohBd0rnrBjN724G49j3dtSCng+Utmqkdw == X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgedujedrudeluddgudduvdcutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpqfgfvfdpuffrtefokffrpgfnqfgh necuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmd enucfjughrpeffhffvuffkfhggtggujgesghdtreertddtvdenucfhrhhomheprfgrthhr ihgtkhcuufhtvghinhhhrghrughtuceophhssehpkhhsrdhimheqnecuggftrfgrthhtvg hrnhepheeghfdtfeeuffehkefgffduleffjedthfdvjeektdfhhedvlefgtefgvdettdfh necukfhppeejkedrheehrddugedrudejheenucevlhhushhtvghrufhiiigvpedunecurf grrhgrmhepmhgrihhlfhhrohhmpehpshesphhkshdrihhm X-ME-Proxy: Received: from vm-mail.pks.im (dynamic-078-055-014-175.78.55.pool.telefonica.de [78.55.14.175]) by mail.messagingengine.com (Postfix) with ESMTPA id A52C0108005C; Wed, 16 Dec 2020 02:54:50 -0500 (EST) Received: from localhost (ncase [10.192.0.11]) by vm-mail.pks.im (OpenSMTPD) with ESMTPSA id efaf7c28 (TLSv1.3:TLS_AES_256_GCM_SHA384:256:NO); Wed, 16 Dec 2020 07:54:49 +0000 (UTC) Date: Wed, 16 Dec 2020 08:54:48 +0100 From: Patrick Steinhardt To: git@vger.kernel.org Cc: =?iso-8859-1?q?=C6var_Arnfj=F6r=F0?= Bjarmason , Junio C Hamano , Jeff King , "brian m. carlson" , Philip Oakley Subject: [PATCH v5 8/8] config: allow specifying config entries via envvar pairs Message-ID: References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org While we currently have the `GIT_CONFIG_PARAMETERS` environment variable which can be used to pass runtime configuration data to git processes, it's an internal implementation detail and not supposed to be used by end users. Next to being for internal use only, this way of passing config entries has a major downside: the config keys need to be parsed as they contain both key and value in a single variable. As such, it is left to the user to escape any potentially harmful characters in the value, which is quite hard to do if values are controlled by a third party. This commit thus adds a new way of adding config entries via the environment which gets rid of this shortcoming. If the user passes the `GIT_CONFIG_COUNT=$n` environment variable, Git will parse environment variable pairs `GIT_CONFIG_KEY_$i` and `GIT_CONFIG_VALUE_$i` for each `i` in `[0,n)`. While the same can be achieved with `git -c =`, one may wish to not do so for potentially sensitive information. E.g. if one wants to set `http.extraHeader` to contain an authentication token, doing so via `-c` would trivially leak those credentials via e.g. ps(1), which typically also shows command arguments. Signed-off-by: Patrick Steinhardt --- Documentation/git-config.txt | 16 +++++ cache.h | 1 + config.c | 67 +++++++++++++++++--- environment.c | 1 + t/t1300-config.sh | 115 ++++++++++++++++++++++++++++++++++- 5 files changed, 191 insertions(+), 9 deletions(-) diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 0e9351d3cb..72ccea4419 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -346,6 +346,22 @@ GIT_CONFIG_NOSYSTEM:: See also <>. +GIT_CONFIG_COUNT:: +GIT_CONFIG_KEY_:: +GIT_CONFIG_VALUE_:: + If GIT_CONFIG_COUNT is set to a positive number, all environment pairs + GIT_CONFIG_KEY_ and GIT_CONFIG_VALUE_ up to that number will be + added to the process's runtime configuration. The config pairs are + zero-indexed. Any missing key or value is treated as an error. An empty + GIT_CONFIG_COUNT is treated the same as GIT_CONFIG_COUNT=0, namely no + pairs are processed. These environment variables will override values + in configuration files, but will be overridden by any explicit options + passed via `git -c`. + + This is useful for cases where you want to spawn multiple git commands + with a common configuration but cannot depend on a configuration file, + for example when writing scripts. + [[EXAMPLES]] EXAMPLES diff --git a/cache.h b/cache.h index 8d279bc110..294841fca7 100644 --- a/cache.h +++ b/cache.h @@ -472,6 +472,7 @@ static inline enum object_type object_type(unsigned int mode) #define TEMPLATE_DIR_ENVIRONMENT "GIT_TEMPLATE_DIR" #define CONFIG_ENVIRONMENT "GIT_CONFIG" #define CONFIG_DATA_ENVIRONMENT "GIT_CONFIG_PARAMETERS" +#define CONFIG_COUNT_ENVIRONMENT "GIT_CONFIG_COUNT" #define EXEC_PATH_ENVIRONMENT "GIT_EXEC_PATH" #define CEILING_DIRECTORIES_ENVIRONMENT "GIT_CEILING_DIRECTORIES" #define NO_REPLACE_OBJECTS_ENVIRONMENT "GIT_NO_REPLACE_OBJECTS" diff --git a/config.c b/config.c index 60a7261807..1742aefa3e 100644 --- a/config.c +++ b/config.c @@ -8,6 +8,7 @@ #include "cache.h" #include "branch.h" #include "config.h" +#include "environment.h" #include "repository.h" #include "lockfile.h" #include "exec-cmd.h" @@ -594,23 +595,73 @@ static int parse_config_env_list(char *env, config_fn_t fn, void *data) int git_config_from_parameters(config_fn_t fn, void *data) { - const char *env = getenv(CONFIG_DATA_ENVIRONMENT); + const char *env; + struct strbuf envvar = STRBUF_INIT; + struct strvec to_free = STRVEC_INIT; int ret = 0; - char *envw; + char *envw = NULL; struct config_source source; - if (!env) - return 0; - memset(&source, 0, sizeof(source)); source.prev = cf; source.origin_type = CONFIG_ORIGIN_CMDLINE; cf = &source; - /* sq_dequote will write over it */ - envw = xstrdup(env); - ret = parse_config_env_list(envw, fn, data); + env = getenv(CONFIG_COUNT_ENVIRONMENT); + if (env) { + unsigned long count; + char *endp; + int i; + count = strtoul(env, &endp, 10); + if (*endp) { + ret = error(_("bogus count in %s"), CONFIG_COUNT_ENVIRONMENT); + goto out; + } + if (count > INT_MAX) { + ret = error(_("too many entries in %s"), CONFIG_COUNT_ENVIRONMENT); + goto out; + } + + for (i = 0; i < count; i++) { + const char *key, *value; + + strbuf_addf(&envvar, "GIT_CONFIG_KEY_%d", i); + key = getenv_safe(&to_free, envvar.buf); + if (!key) { + ret = error(_("missing config key %s"), envvar.buf); + goto out; + } + strbuf_reset(&envvar); + + strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%d", i); + value = getenv_safe(&to_free, envvar.buf); + if (!value) { + ret = error(_("missing config value %s"), envvar.buf); + goto out; + } + strbuf_reset(&envvar); + + if (config_parse_pair(key, value, fn, data) < 0) { + ret = -1; + goto out; + } + } + } + + env = getenv(CONFIG_DATA_ENVIRONMENT); + if (env) { + /* sq_dequote will write over it */ + envw = xstrdup(env); + if (parse_config_env_list(envw, fn, data) < 0) { + ret = -1; + goto out; + } + } + +out: + strbuf_release(&envvar); + strvec_clear(&to_free); free(envw); cf = source.prev; return ret; diff --git a/environment.c b/environment.c index 2234af462c..2f27008424 100644 --- a/environment.c +++ b/environment.c @@ -117,6 +117,7 @@ const char * const local_repo_env[] = { ALTERNATE_DB_ENVIRONMENT, CONFIG_ENVIRONMENT, CONFIG_DATA_ENVIRONMENT, + CONFIG_COUNT_ENVIRONMENT, DB_ENVIRONMENT, GIT_DIR_ENVIRONMENT, GIT_WORK_TREE_ENVIRONMENT, diff --git a/t/t1300-config.sh b/t/t1300-config.sh index 35a1a6e8b1..e06961767f 100755 --- a/t/t1300-config.sh +++ b/t/t1300-config.sh @@ -1421,6 +1421,117 @@ test_expect_success '--config-env handles keys with equals' ' test_cmp expect actual ' +test_expect_success 'git config handles environment config pairs' ' + GIT_CONFIG_COUNT=2 \ + GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="foo" \ + GIT_CONFIG_KEY_1="pair.two" GIT_CONFIG_VALUE_1="bar" \ + git config --get-regexp "pair.*" >actual && + cat >expect <<-EOF && + pair.one foo + pair.two bar + EOF + test_cmp expect actual +' + +test_expect_success 'git config ignores pairs without count' ' + test_must_fail env GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \ + git config pair.one 2>error && + test_must_be_empty error +' + +test_expect_success 'git config ignores pairs with zero count' ' + test_must_fail env \ + GIT_CONFIG_COUNT=0 \ + GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \ + git config pair.one +' + +test_expect_success 'git config ignores pairs exceeding count' ' + GIT_CONFIG_COUNT=1 \ + GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \ + GIT_CONFIG_KEY_1="pair.two" GIT_CONFIG_VALUE_1="value" \ + git config --get-regexp "pair.*" >actual && + cat >expect <<-EOF && + pair.one value + EOF + test_cmp expect actual +' + +test_expect_success 'git config ignores pairs with zero count' ' + test_must_fail env \ + GIT_CONFIG_COUNT=0 GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \ + git config pair.one >error && + test_must_be_empty error +' + +test_expect_success 'git config ignores pairs with empty count' ' + test_must_fail env \ + GIT_CONFIG_COUNT= GIT_CONFIG_KEY_0="pair.one" GIT_CONFIG_VALUE_0="value" \ + git config pair.one >error && + test_must_be_empty error +' + +test_expect_success 'git config fails with invalid count' ' + test_must_fail env GIT_CONFIG_COUNT=10a git config --list 2>error && + test_i18ngrep "bogus count" error && + test_must_fail env GIT_CONFIG_COUNT=9999999999999999 git config --list 2>error && + test_i18ngrep "too many entries" error +' + +test_expect_success 'git config fails with missing config key' ' + test_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_VALUE_0="value" \ + git config --list 2>error && + test_i18ngrep "missing config key" error +' + +test_expect_success 'git config fails with missing config value' ' + test_must_fail env GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0="pair.one" \ + git config --list 2>error && + test_i18ngrep "missing config value" error +' + +test_expect_success 'git config fails with invalid config pair key' ' + test_must_fail env GIT_CONFIG_COUNT=1 \ + GIT_CONFIG_KEY_0= GIT_CONFIG_VALUE_0=value \ + git config --list && + test_must_fail env GIT_CONFIG_COUNT=1 \ + GIT_CONFIG_KEY_0=missing-section GIT_CONFIG_VALUE_0=value \ + git config --list +' + +test_expect_success 'environment overrides config file' ' + test_when_finished "rm -f .git/config" && + cat >.git/config <<-EOF && + [pair] + one = value + EOF + GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=pair.one GIT_CONFIG_VALUE_0=override \ + git config pair.one >actual && + cat >expect <<-EOF && + override + EOF + test_cmp expect actual +' + +test_expect_success 'GIT_CONFIG_PARAMETERS overrides environment config' ' + GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=pair.one GIT_CONFIG_VALUE_0=value \ + GIT_CONFIG_PARAMETERS="${SQ}pair.one=override${SQ}" \ + git config pair.one >actual && + cat >expect <<-EOF && + override + EOF + test_cmp expect actual +' + +test_expect_success 'command line overrides environment config' ' + GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=pair.one GIT_CONFIG_VALUE_0=value \ + git -c pair.one=override config pair.one >actual && + cat >expect <<-EOF && + override + EOF + test_cmp expect actual +' + test_expect_success 'git config --edit works' ' git config -f tmp test.value no && echo test.value=yes >expect && @@ -1766,9 +1877,11 @@ test_expect_success '--show-origin with --list' ' file:.git/config user.override=local file:.git/config include.path=../include/relative.include file:.git/../include/relative.include user.relative=include + command line: user.environ=true command line: user.cmdline=true EOF - git -c user.cmdline=true config --list --show-origin >output && + GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=user.environ GIT_CONFIG_VALUE_0=true\ + git -c user.cmdline=true config --list --show-origin >output && test_cmp expect output '