Commit eb398797c (connect: advertized capability is not a ref, 2016-09-09) taught 'get_remote_heads()' to recognize that the 'capabilities^{}' line isn't a ref but required that the 'capabilities^{}' line came during the first response from the server. A future patch will introduce a version string sent by the server during its first response which can then cause a client to unnecessarily die if a 'capabilities^{}' line sent as the first ref. Teach 'get_remote_heads()' to instead die if a 'capabilities^{}' line is sent after a ref. Reported-by: Miguel Alcon <malcon@xxxxxxxxxx> Signed-off-by: Brandon Williams <bmwill@xxxxxxxxxx> --- This is a fix to the bug we found when internally deploying this series. It just makes it so that a capability line wont cause a client to error out if its not the first response, because it won't be the first response come protocol v1. connect.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/connect.c b/connect.c index df56c0cbf..af5096ec6 100644 --- a/connect.c +++ b/connect.c @@ -124,10 +124,11 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, * response does not necessarily mean an ACL problem, though. */ int saw_response; + int seen_ref; int got_dummy_ref_with_capabilities_declaration = 0; *list = NULL; - for (saw_response = 0; ; saw_response = 1) { + for (saw_response = 0, seen_ref = 0; ; saw_response = 1) { struct ref *ref; struct object_id old_oid; char *name; @@ -165,6 +166,8 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, name_len = strlen(name); if (len != name_len + GIT_SHA1_HEXSZ + 1) { + if (seen_ref) + ; /* NEEDSWORK: Error out for multiple capabilities lines? */ free(server_capabilities); server_capabilities = xstrdup(name + name_len + 1); } @@ -175,7 +178,7 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, } if (!strcmp(name, "capabilities^{}")) { - if (saw_response) + if (seen_ref) die("protocol error: unexpected capabilities^{}"); if (got_dummy_ref_with_capabilities_declaration) die("protocol error: multiple capabilities^{}"); @@ -193,6 +196,7 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, oidcpy(&ref->old_oid, &old_oid); *list = ref; list = &ref->next; + seen_ref = 1; } annotate_refs_with_symref_info(*orig_list); -- 2.14.1.821.g8fa685d3b7-goog