Skip to content

Commit f47182c

Browse files
committed
server_supports(): parse feature list more carefully
We have been carefully choosing feature names used in the protocol extensions so that the vocabulary does not contain a word that is a substring of another word, so it is not a real problem, but we have recently added "quiet" feature word, which would mean we cannot later add some other word with "quiet" (e.g. "quiet-push"), which is awkward. Let's make sure that we can eventually be able to do so by teaching the clients and servers that feature words consist of non whitespace letters. This parser also allows us to later add features with parameters e.g. "feature=1.5" (parameter values need to be quoted for whitespaces, but we will worry about the detauls when we do introduce them). Signed-off-by: Junio C Hamano <[email protected]> Signed-off-by: Clemens Buchacher <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent eac2d83 commit f47182c

File tree

4 files changed

+38
-13
lines changed

4 files changed

+38
-13
lines changed

builtin/receive-pack.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -731,9 +731,10 @@ static struct command *read_head_info(void)
731731
refname = line + 82;
732732
reflen = strlen(refname);
733733
if (reflen + 82 < len) {
734-
if (strstr(refname + reflen + 1, "report-status"))
734+
const char *feature_list = refname + reflen + 1;
735+
if (parse_feature_request(feature_list, "report-status"))
735736
report_status = 1;
736-
if (strstr(refname + reflen + 1, "side-band-64k"))
737+
if (parse_feature_request(feature_list, "side-band-64k"))
737738
use_sideband = LARGE_PACKET_MAX;
738739
}
739740
cmd = xcalloc(1, sizeof(struct command) + len - 80);

cache.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,6 +1037,7 @@ struct extra_have_objects {
10371037
};
10381038
extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *);
10391039
extern int server_supports(const char *feature);
1040+
extern const char *parse_feature_request(const char *features, const char *feature);
10401041

10411042
extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
10421043

connect.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,27 @@ struct ref **get_remote_heads(int in, struct ref **list,
101101

102102
int server_supports(const char *feature)
103103
{
104-
return server_capabilities &&
105-
strstr(server_capabilities, feature) != NULL;
104+
return !!parse_feature_request(server_capabilities, feature);
105+
}
106+
107+
const char *parse_feature_request(const char *feature_list, const char *feature)
108+
{
109+
int len;
110+
111+
if (!feature_list)
112+
return NULL;
113+
114+
len = strlen(feature);
115+
while (*feature_list) {
116+
const char *found = strstr(feature_list, feature);
117+
if (!found)
118+
return NULL;
119+
if ((feature_list == found || isspace(found[-1])) &&
120+
(!found[len] || isspace(found[len]) || found[len] == '='))
121+
return found;
122+
feature_list = found + 1;
123+
}
124+
return NULL;
106125
}
107126

108127
enum protocol {

upload-pack.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,7 @@ static void receive_needs(void)
585585
write_str_in_full(debug_fd, "#S\n");
586586
for (;;) {
587587
struct object *o;
588+
const char *features;
588589
unsigned char sha1_buf[20];
589590
len = packet_read_line(0, line, sizeof(line));
590591
reset_timeout();
@@ -616,23 +617,26 @@ static void receive_needs(void)
616617
get_sha1_hex(line+5, sha1_buf))
617618
die("git upload-pack: protocol error, "
618619
"expected to get sha, not '%s'", line);
619-
if (strstr(line+45, "multi_ack_detailed"))
620+
621+
features = line + 45;
622+
623+
if (parse_feature_request(features, "multi_ack_detailed"))
620624
multi_ack = 2;
621-
else if (strstr(line+45, "multi_ack"))
625+
else if (parse_feature_request(features, "multi_ack"))
622626
multi_ack = 1;
623-
if (strstr(line+45, "no-done"))
627+
if (parse_feature_request(features, "no-done"))
624628
no_done = 1;
625-
if (strstr(line+45, "thin-pack"))
629+
if (parse_feature_request(features, "thin-pack"))
626630
use_thin_pack = 1;
627-
if (strstr(line+45, "ofs-delta"))
631+
if (parse_feature_request(features, "ofs-delta"))
628632
use_ofs_delta = 1;
629-
if (strstr(line+45, "side-band-64k"))
633+
if (parse_feature_request(features, "side-band-64k"))
630634
use_sideband = LARGE_PACKET_MAX;
631-
else if (strstr(line+45, "side-band"))
635+
else if (parse_feature_request(features, "side-band"))
632636
use_sideband = DEFAULT_PACKET_MAX;
633-
if (strstr(line+45, "no-progress"))
637+
if (parse_feature_request(features, "no-progress"))
634638
no_progress = 1;
635-
if (strstr(line+45, "include-tag"))
639+
if (parse_feature_request(features, "include-tag"))
636640
use_include_tag = 1;
637641

638642
o = lookup_object(sha1_buf);

0 commit comments

Comments
 (0)