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

Re: [PATCH] upload-pack: fix broken if/else chain in config callback

From
Johannes Schindelin <johannes.schindelin@gmx.de>
Date
Oct 24, 2018, 08:50 UTC
Message-ID
<nycvar.QRO.7.76.6.1810241049200.4546@tvgsbejvaqbjf.bet>
In-Reply-To
<20181024072752.GA29717@sigill.intra.peff.net>
Hi Peff,
On Wed, 24 Oct 2018, Jeff King wrote:
Show 74 quoted lines
> The upload_pack_config() callback uses an if/else chain
> like:
> 
>   if (!strcmp(var, "a"))
>      ...
>   else if (!strcmp(var, "b"))
>      ...
>   etc
> 
> This works as long as the conditions are mutually exclusive,
> but one of them is not. 20b20a22f8 (upload-pack: provide a
> hook for running pack-objects, 2016-05-18) added:
> 
>   else if (current_config_scope() != CONFIG_SCOPE_REPO) {
>      ... check some more options ...
>   }
> 
> That was fine in that commit, because it came at the end of
> the chain.  But later, 10ac85c785 (upload-pack: add object
> filtering for partial clone, 2017-12-08) did this:
> 
>   else if (current_config_scope() != CONFIG_SCOPE_REPO) {
>      ... check some more options ...
>   } else if (!strcmp("uploadpack.allowfilter", var))
>      ...
> 
> We'd always check the scope condition first, meaning we'd
> _only_ respect allowfilter when it's in the repo config. You
> can see this with:
> 
>   git -c uploadpack.allowfilter=true upload-pack . | head -1
> 
> which will not advertise the filter capability (but will
> after this patch). We never noticed because:
> 
>   - our tests always set it in the repo config
> 
>   - in protocol v2, we use a different code path that
>     actually calls repo_config_get_bool() separately, so
>     that _does_ work. Real-world people experimenting with
>     this may be using v2.
> 
> The more recent uploadpack.allowrefinwant option is in the
> same boat.
> 
> There are a few possible fixes:
> 
>   1. Bump the scope conditional back to the bottom of the
>      chain. But that just means somebody else is likely to
>      make the same mistake later.
> 
>   2. Make the conditional more like the others. I.e.:
> 
>        else if (!current_config_scope() != CONFIG_SCOPE_REPO &&
>                 !strcmp(var, "uploadpack.notallowedinrepo"))
> 
>      This works, but the idea of the original structure was
>      that we may grow multiple sensitive options like this.
> 
>   3. Pull it out of the chain entirely. The chain mostly
>      serves to avoid extra strcmp() calls after we've found
>      a match. But it's not worth caring about those. In the
>      worst case, when there isn't a match, we're already
>      hitting every strcmp (and this happens regularly for
>      stuff like "core.bare", etc).
> 
> This patch does (3).
> 
> Signed-off-by: Jeff King <peff@peff.net>
> ---
> Phew. That was a lot of explanation for a small patch, but
> this was sufficiently subtle I thought it worth it. And
> also, I was really surprised the bug managed to exist for
> this long without anybody noticing.

Maybe a lot of explanation, but definitely a good one. The explanation and the patch look good to me.

Thanks, Dscho

Show 32 quoted lines
> 
>  upload-pack.c | 9 ++++++---
>  1 file changed, 6 insertions(+), 3 deletions(-)
> 
> diff --git a/upload-pack.c b/upload-pack.c
> index 540778d1dd..489c18e222 100644
> --- a/upload-pack.c
> +++ b/upload-pack.c
> @@ -1028,14 +1028,17 @@ static int upload_pack_config(const char *var, const char *value, void *unused)
>  		keepalive = git_config_int(var, value);
>  		if (!keepalive)
>  			keepalive = -1;
> -	} else if (current_config_scope() != CONFIG_SCOPE_REPO) {
> -		if (!strcmp("uploadpack.packobjectshook", var))
> -			return git_config_string(&pack_objects_hook, var, value);
>  	} else if (!strcmp("uploadpack.allowfilter", var)) {
>  		allow_filter = git_config_bool(var, value);
>  	} else if (!strcmp("uploadpack.allowrefinwant", var)) {
>  		allow_ref_in_want = git_config_bool(var, value);
>  	}
> +
> +	if (current_config_scope() != CONFIG_SCOPE_REPO) {
> +		if (!strcmp("uploadpack.packobjectshook", var))
> +			return git_config_string(&pack_objects_hook, var, value);
> +	}
> +
>  	return parse_hide_refs_config(var, value, "uploadpack");
>  }
>  
> -- 
> 2.19.1.1094.gd480080bf6
> 
Previous: Jeff KingNext: Josh Steadmon
Message 2 of 3 in “upload-pack: fix broken if/else chain in config callback”
  1. upload-pack: fix broken if/else chain in config callbackJeff King, Oct 24, 2018
  2. Johannes SchindelinOct 24, 2018
  3. Josh SteadmonOct 25, 2018

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

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