server_supports_v2(): use a separate function for die_on_error

The server_supports_v2() helper lets a caller find out if the server
supports a feature, and will optionally die if it's not supported. This
makes the return value confusing, as it's only meaningful when the
function is not asked to die.

Coverity flagged a new call like:

  /* check that we support "foo" */
  server_supports_v2("foo", 1);

complaining that we usually checked the return value, but this time we
didn't. But this call is correct, and other ones that did:

  if (server_supports_v2("foo", 1))
          do_something_with_foo();

are "wrong", in the sense that we know the conditional will always be
true (but there's no bug; the code is simply misleading).

Let's split the "die" behavior into its own function which returns void,
and modify each caller to use the correct one.

Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King 2022-12-13 05:52:58 -05:00 committed by Junio C Hamano
parent 8706a59933
commit a31cfe3283
3 changed files with 21 additions and 17 deletions

View File

@ -66,7 +66,7 @@ static NORETURN void die_initial_contact(int unexpected)
} }
/* Checks if the server supports the capability 'c' */ /* Checks if the server supports the capability 'c' */
int server_supports_v2(const char *c, int die_on_error) int server_supports_v2(const char *c)
{ {
int i; int i;
@ -76,13 +76,15 @@ int server_supports_v2(const char *c, int die_on_error)
(!*out || *out == '=')) (!*out || *out == '='))
return 1; return 1;
} }
if (die_on_error)
die(_("server doesn't support '%s'"), c);
return 0; return 0;
} }
void ensure_server_supports_v2(const char *c)
{
if (!server_supports_v2(c))
die(_("server doesn't support '%s'"), c);
}
int server_feature_v2(const char *c, const char **v) int server_feature_v2(const char *c, const char **v)
{ {
int i; int i;
@ -477,7 +479,7 @@ static void send_capabilities(int fd_out, struct packet_reader *reader)
{ {
const char *hash_name; const char *hash_name;
if (server_supports_v2("agent", 0)) if (server_supports_v2("agent"))
packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized()); packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized());
if (server_feature_v2("object-format", &hash_name)) { if (server_feature_v2("object-format", &hash_name)) {
@ -504,17 +506,18 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader,
&transport_options->unborn_head_target : NULL; &transport_options->unborn_head_target : NULL;
*list = NULL; *list = NULL;
if (server_supports_v2("ls-refs", 1)) ensure_server_supports_v2("ls-refs");
packet_write_fmt(fd_out, "command=ls-refs\n"); packet_write_fmt(fd_out, "command=ls-refs\n");
/* Send capabilities */ /* Send capabilities */
send_capabilities(fd_out, reader); send_capabilities(fd_out, reader);
if (server_options && server_options->nr && if (server_options && server_options->nr) {
server_supports_v2("server-option", 1)) ensure_server_supports_v2("server-option");
for (i = 0; i < server_options->nr; i++) for (i = 0; i < server_options->nr; i++)
packet_write_fmt(fd_out, "server-option=%s", packet_write_fmt(fd_out, "server-option=%s",
server_options->items[i].string); server_options->items[i].string);
}
packet_delim(fd_out); packet_delim(fd_out);
/* When pushing we don't want to request the peeled tags */ /* When pushing we don't want to request the peeled tags */

View File

@ -20,7 +20,8 @@ enum protocol_version discover_version(struct packet_reader *reader);
int server_supports_hash(const char *desired, int *feature_supported); int server_supports_hash(const char *desired, int *feature_supported);
const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp, int *offset); const char *parse_feature_value(const char *feature_list, const char *feature, int *lenp, int *offset);
int server_supports_v2(const char *c, int die_on_error); int server_supports_v2(const char *c);
void ensure_server_supports_v2(const char *c);
int server_feature_v2(const char *c, const char **v); int server_feature_v2(const char *c, const char **v);
int server_supports_feature(const char *c, const char *feature, int server_supports_feature(const char *c, const char *feature,
int die_on_error); int die_on_error);

View File

@ -1317,15 +1317,15 @@ static void write_fetch_command_and_capabilities(struct strbuf *req_buf,
{ {
const char *hash_name; const char *hash_name;
if (server_supports_v2("fetch", 1)) ensure_server_supports_v2("fetch");
packet_buf_write(req_buf, "command=fetch"); packet_buf_write(req_buf, "command=fetch");
if (server_supports_v2("agent", 0)) if (server_supports_v2("agent"))
packet_buf_write(req_buf, "agent=%s", git_user_agent_sanitized()); packet_buf_write(req_buf, "agent=%s", git_user_agent_sanitized());
if (advertise_sid && server_supports_v2("session-id", 0)) if (advertise_sid && server_supports_v2("session-id"))
packet_buf_write(req_buf, "session-id=%s", trace2_session_id()); packet_buf_write(req_buf, "session-id=%s", trace2_session_id());
if (server_options && server_options->nr && if (server_options && server_options->nr) {
server_supports_v2("server-option", 1)) {
int i; int i;
ensure_server_supports_v2("server-option");
for (i = 0; i < server_options->nr; i++) for (i = 0; i < server_options->nr; i++)
packet_buf_write(req_buf, "server-option=%s", packet_buf_write(req_buf, "server-option=%s",
server_options->items[i].string); server_options->items[i].string);