From: Brandon Williams <bmwill@google.com>
To: git@vger.kernel.org
Cc: bturner@atlassian.com, git@jeffhostetler.com, gitster@pobox.com,
jonathantanmy@google.com, jrnieder@gmail.com, peff@peff.net,
sbeller@google.com, Brandon Williams <bmwill@google.com>
Subject: [PATCH v3 01/10] connect: in ref advertisement, shallows are last
Date: Tue, 3 Oct 2017 13:14:58 -0700 [thread overview]
Message-ID: <20171003201507.3589-2-bmwill@google.com> (raw)
In-Reply-To: <20171003201507.3589-1-bmwill@google.com>
From: Jonathan Tan <jonathantanmy@google.com>
Currently, get_remote_heads() parses the ref advertisement in one loop,
allowing refs and shallow lines to intersperse, despite this not being
allowed by the specification. Refactor get_remote_heads() to use two
loops instead, enforcing that refs come first, and then shallows.
This also makes it easier to teach get_remote_heads() to interpret other
lines in the ref advertisement, which will be done in a subsequent
patch.
As part of this change, this patch interprets capabilities only on the
first line in the ref advertisement, printing a warning message when
encountering capabilities on other lines.
Signed-off-by: Jonathan Tan <jonathantanmy@google.com>
Signed-off-by: Brandon Williams <bmwill@google.com>
---
connect.c | 189 ++++++++++++++++++++++++++++++++++++++++----------------------
1 file changed, 123 insertions(+), 66 deletions(-)
diff --git a/connect.c b/connect.c
index df56c0cbf..8e2e276b6 100644
--- a/connect.c
+++ b/connect.c
@@ -11,6 +11,7 @@
#include "string-list.h"
#include "sha1-array.h"
#include "transport.h"
+#include "strbuf.h"
static char *server_capabilities;
static const char *parse_feature_value(const char *, const char *, int *);
@@ -107,6 +108,104 @@ static void annotate_refs_with_symref_info(struct ref *ref)
string_list_clear(&symref, 0);
}
+/*
+ * Read one line of a server's ref advertisement into packet_buffer.
+ */
+static int read_remote_ref(int in, char **src_buf, size_t *src_len,
+ int *responded)
+{
+ int len = packet_read(in, src_buf, src_len,
+ packet_buffer, sizeof(packet_buffer),
+ PACKET_READ_GENTLE_ON_EOF |
+ PACKET_READ_CHOMP_NEWLINE);
+ const char *arg;
+ if (len < 0)
+ die_initial_contact(*responded);
+ if (len > 4 && skip_prefix(packet_buffer, "ERR ", &arg))
+ die("remote error: %s", arg);
+
+ *responded = 1;
+
+ return len;
+}
+
+#define EXPECTING_FIRST_REF 0
+#define EXPECTING_REF 1
+#define EXPECTING_SHALLOW 2
+
+static void process_capabilities(int *len)
+{
+ int nul_location = strlen(packet_buffer);
+ if (nul_location == *len)
+ return;
+ server_capabilities = xstrdup(packet_buffer + nul_location + 1);
+ *len = nul_location;
+}
+
+static int process_dummy_ref(void)
+{
+ struct object_id oid;
+ const char *name;
+
+ if (parse_oid_hex(packet_buffer, &oid, &name))
+ return 0;
+ if (*name != ' ')
+ return 0;
+ name++;
+
+ return !oidcmp(&null_oid, &oid) && !strcmp(name, "capabilities^{}");
+}
+
+static void check_no_capabilities(int len)
+{
+ if (strlen(packet_buffer) != len)
+ warning("Ignoring capabilities after first line '%s'",
+ packet_buffer + strlen(packet_buffer));
+}
+
+static int process_ref(int len, struct ref ***list, unsigned int flags,
+ struct oid_array *extra_have)
+{
+ struct object_id old_oid;
+ const char *name;
+
+ if (parse_oid_hex(packet_buffer, &old_oid, &name))
+ return 0;
+ if (*name != ' ')
+ return 0;
+ name++;
+
+ if (extra_have && !strcmp(name, ".have")) {
+ oid_array_append(extra_have, &old_oid);
+ } else if (!strcmp(name, "capabilities^{}")) {
+ die("protocol error: unexpected capabilities^{}");
+ } else if (check_ref(name, flags)) {
+ struct ref *ref = alloc_ref(name);
+ oidcpy(&ref->old_oid, &old_oid);
+ **list = ref;
+ *list = &ref->next;
+ }
+ check_no_capabilities(len);
+ return 1;
+}
+
+static int process_shallow(int len, struct oid_array *shallow_points)
+{
+ const char *arg;
+ struct object_id old_oid;
+
+ if (!skip_prefix(packet_buffer, "shallow ", &arg))
+ return 0;
+
+ if (get_oid_hex(arg, &old_oid))
+ die("protocol error: expected shallow sha-1, got '%s'", arg);
+ if (!shallow_points)
+ die("repository on the other end cannot be shallow");
+ oid_array_append(shallow_points, &old_oid);
+ check_no_capabilities(len);
+ return 1;
+}
+
/*
* Read all the refs from the other end
*/
@@ -123,76 +222,34 @@ struct ref **get_remote_heads(int in, char *src_buf, size_t src_len,
* willing to talk to us. A hang-up before seeing any
* response does not necessarily mean an ACL problem, though.
*/
- int saw_response;
- int got_dummy_ref_with_capabilities_declaration = 0;
+ int responded = 0;
+ int len;
+ int state = EXPECTING_FIRST_REF;
*list = NULL;
- for (saw_response = 0; ; saw_response = 1) {
- struct ref *ref;
- struct object_id old_oid;
- char *name;
- int len, name_len;
- char *buffer = packet_buffer;
- const char *arg;
-
- len = packet_read(in, &src_buf, &src_len,
- packet_buffer, sizeof(packet_buffer),
- PACKET_READ_GENTLE_ON_EOF |
- PACKET_READ_CHOMP_NEWLINE);
- if (len < 0)
- die_initial_contact(saw_response);
-
- if (!len)
- break;
-
- if (len > 4 && skip_prefix(buffer, "ERR ", &arg))
- die("remote error: %s", arg);
-
- if (len == GIT_SHA1_HEXSZ + strlen("shallow ") &&
- skip_prefix(buffer, "shallow ", &arg)) {
- if (get_oid_hex(arg, &old_oid))
- die("protocol error: expected shallow sha-1, got '%s'", arg);
- if (!shallow_points)
- die("repository on the other end cannot be shallow");
- oid_array_append(shallow_points, &old_oid);
- continue;
- }
- if (len < GIT_SHA1_HEXSZ + 2 || get_oid_hex(buffer, &old_oid) ||
- buffer[GIT_SHA1_HEXSZ] != ' ')
- die("protocol error: expected sha/ref, got '%s'", buffer);
- name = buffer + GIT_SHA1_HEXSZ + 1;
-
- name_len = strlen(name);
- if (len != name_len + GIT_SHA1_HEXSZ + 1) {
- free(server_capabilities);
- server_capabilities = xstrdup(name + name_len + 1);
- }
-
- if (extra_have && !strcmp(name, ".have")) {
- oid_array_append(extra_have, &old_oid);
- continue;
- }
-
- if (!strcmp(name, "capabilities^{}")) {
- if (saw_response)
- die("protocol error: unexpected capabilities^{}");
- if (got_dummy_ref_with_capabilities_declaration)
- die("protocol error: multiple capabilities^{}");
- got_dummy_ref_with_capabilities_declaration = 1;
- continue;
+ while ((len = read_remote_ref(in, &src_buf, &src_len, &responded))) {
+ switch (state) {
+ case EXPECTING_FIRST_REF:
+ process_capabilities(&len);
+ if (process_dummy_ref()) {
+ state = EXPECTING_SHALLOW;
+ break;
+ }
+ state = EXPECTING_REF;
+ /* fallthrough */
+ case EXPECTING_REF:
+ if (process_ref(len, &list, flags, extra_have))
+ break;
+ state = EXPECTING_SHALLOW;
+ /* fallthrough */
+ case EXPECTING_SHALLOW:
+ if (process_shallow(len, shallow_points))
+ break;
+ die("protocol error: unexpected '%s'", packet_buffer);
+ default:
+ die("unexpected state %d", state);
}
-
- if (!check_ref(name, flags))
- continue;
-
- if (got_dummy_ref_with_capabilities_declaration)
- die("protocol error: unexpected ref after capabilities^{}");
-
- ref = alloc_ref(buffer + GIT_SHA1_HEXSZ + 1);
- oidcpy(&ref->old_oid, &old_oid);
- *list = ref;
- list = &ref->next;
}
annotate_refs_with_symref_info(*orig_list);
--
2.14.2.920.gcf0c67979c-goog
next prev parent reply other threads:[~2017-10-03 20:15 UTC|newest]
Thread overview: 161+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-13 21:54 [PATCH 0/8] protocol transition Brandon Williams
2017-09-13 21:54 ` [PATCH 1/8] pkt-line: add packet_write function Brandon Williams
2017-09-13 21:54 ` [PATCH 2/8] protocol: introduce protocol extention mechanisms Brandon Williams
2017-09-13 22:27 ` Stefan Beller
2017-09-18 17:02 ` Brandon Williams
2017-09-18 18:34 ` Stefan Beller
2017-09-18 19:58 ` Brandon Williams
2017-09-18 20:06 ` Stefan Beller
2017-09-13 21:54 ` [PATCH 3/8] daemon: recognize hidden request arguments Brandon Williams
2017-09-13 22:31 ` Stefan Beller
2017-09-18 16:56 ` Brandon Williams
2017-09-21 0:24 ` Jonathan Tan
2017-09-21 0:31 ` Jonathan Tan
2017-09-21 21:55 ` Brandon Williams
2017-09-13 21:54 ` [PATCH 4/8] upload-pack, receive-pack: introduce protocol version 1 Brandon Williams
2017-09-13 21:54 ` [PATCH 5/8] connect: teach client to recognize v1 server response Brandon Williams
2017-09-13 21:54 ` [PATCH 6/8] connect: tell server that the client understands v1 Brandon Williams
2017-09-13 21:54 ` [PATCH 7/8] http: " Brandon Williams
2017-09-13 21:54 ` [PATCH 8/8] i5700: add interop test for protocol transition Brandon Williams
2017-09-20 18:48 ` [PATCH 1.5/8] connect: die when a capability line comes after a ref Brandon Williams
2017-09-20 19:14 ` Jeff King
2017-09-20 20:06 ` Brandon Williams
2017-09-20 20:48 ` Jonathan Nieder
2017-09-21 3:02 ` Junio C Hamano
2017-09-21 20:45 ` [PATCH] connect: in ref advertisement, shallows are last Jonathan Tan
2017-09-21 23:45 ` [PATCH v2] " Jonathan Tan
2017-09-22 0:00 ` Brandon Williams
2017-09-22 0:08 ` [PATCH v3] " Jonathan Tan
2017-09-22 1:06 ` Junio C Hamano
2017-09-22 1:39 ` Junio C Hamano
2017-09-22 16:45 ` Brandon Williams
2017-09-22 20:15 ` [PATCH v4] " Jonathan Tan
2017-09-22 21:01 ` Brandon Williams
2017-09-22 22:16 ` Jonathan Tan
2017-09-24 0:52 ` Junio C Hamano
2017-09-26 18:21 ` [PATCH v5] " Jonathan Tan
2017-09-26 18:31 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 0/9] protocol transition Brandon Williams
2017-09-26 23:56 ` [PATCH v2 1/9] connect: in ref advertisement, shallows are last Brandon Williams
2017-09-26 23:56 ` [PATCH v2 2/9] pkt-line: add packet_write function Brandon Williams
2017-09-26 23:56 ` [PATCH v2 3/9] protocol: introduce protocol extention mechanisms Brandon Williams
2017-09-27 5:17 ` Junio C Hamano
2017-09-27 11:23 ` Junio C Hamano
2017-09-29 21:20 ` Brandon Williams
2017-09-28 21:58 ` Brandon Williams
2017-09-27 6:30 ` Stefan Beller
2017-09-28 21:04 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 4/9] daemon: recognize hidden request arguments Brandon Williams
2017-09-27 5:20 ` Junio C Hamano
2017-09-27 21:22 ` Brandon Williams
2017-09-28 16:57 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 5/9] upload-pack, receive-pack: introduce protocol version 1 Brandon Williams
2017-09-27 5:23 ` Junio C Hamano
2017-09-27 21:29 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 6/9] connect: teach client to recognize v1 server response Brandon Williams
2017-09-27 1:07 ` Junio C Hamano
2017-09-27 17:34 ` Brandon Williams
2017-09-27 5:29 ` Junio C Hamano
2017-09-28 22:08 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 7/9] connect: tell server that the client understands v1 Brandon Williams
2017-09-27 6:21 ` Junio C Hamano
2017-09-27 6:29 ` Junio C Hamano
2017-09-29 21:32 ` Brandon Williams
2017-09-28 22:20 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 8/9] http: " Brandon Williams
2017-09-27 6:24 ` Junio C Hamano
2017-09-27 21:36 ` Brandon Williams
2017-09-26 23:56 ` [PATCH v2 9/9] i5700: add interop test for protocol transition Brandon Williams
2017-10-03 20:14 ` [PATCH v3 00/10] " Brandon Williams
2017-10-03 20:14 ` Brandon Williams [this message]
2017-10-10 18:14 ` [PATCH v3 01/10] connect: in ref advertisement, shallows are last Jonathan Tan
2017-10-03 20:14 ` [PATCH v3 02/10] pkt-line: add packet_write function Brandon Williams
2017-10-10 18:15 ` Jonathan Tan
2017-10-03 20:15 ` [PATCH v3 03/10] protocol: introduce protocol extention mechanisms Brandon Williams
2017-10-06 9:09 ` Simon Ruderich
2017-10-06 9:40 ` Junio C Hamano
2017-10-06 11:11 ` Martin Ågren
2017-10-06 12:09 ` Junio C Hamano
2017-10-06 19:42 ` Martin Ågren
2017-10-06 20:27 ` Stefan Beller
2017-10-08 14:24 ` Martin Ågren
2017-10-10 21:00 ` Brandon Williams
2017-10-10 21:17 ` Jonathan Nieder
2017-10-10 21:32 ` Stefan Beller
2017-10-11 0:39 ` Junio C Hamano
2017-10-13 22:46 ` Brandon Williams
2017-10-09 4:05 ` Martin Ågren
2017-10-10 19:51 ` Jonathan Tan
2017-10-03 20:15 ` [PATCH v3 04/10] daemon: recognize hidden request arguments Brandon Williams
2017-10-10 18:24 ` Jonathan Tan
2017-10-13 22:04 ` Brandon Williams
2017-10-03 20:15 ` [PATCH v3 05/10] upload-pack, receive-pack: introduce protocol version 1 Brandon Williams
2017-10-10 18:28 ` Jonathan Tan
2017-10-13 22:18 ` Brandon Williams
2017-10-03 20:15 ` [PATCH v3 06/10] connect: teach client to recognize v1 server response Brandon Williams
2017-10-03 20:15 ` [PATCH v3 07/10] connect: tell server that the client understands v1 Brandon Williams
2017-10-10 18:30 ` Jonathan Tan
2017-10-13 22:56 ` Brandon Williams
2017-10-03 20:15 ` [PATCH v3 08/10] http: " Brandon Williams
2017-10-03 20:15 ` [PATCH v3 09/10] i5700: add interop test for protocol transition Brandon Williams
2017-10-03 20:15 ` [PATCH v3 10/10] ssh: introduce a 'simple' ssh variant Brandon Williams
2017-10-03 21:42 ` Jonathan Nieder
2017-10-16 17:18 ` Brandon Williams
2017-10-23 21:28 ` [PATCH 0/5] Coping with unrecognized ssh wrapper scripts in GIT_SSH Jonathan Nieder
2017-10-23 21:29 ` [PATCH 1/5] connect: split git:// setup into a separate function Jonathan Nieder
2017-10-23 22:16 ` Stefan Beller
2017-10-24 0:09 ` [WIP PATCH] diff: add option to ignore whitespaces for move detection only Stefan Beller
2017-10-24 18:48 ` Brandon Williams
2017-10-25 1:25 ` Junio C Hamano
2017-10-25 1:26 ` Junio C Hamano
2017-10-25 18:58 ` Brandon Williams
2017-10-24 1:54 ` [PATCH 1/5] connect: split git:// setup into a separate function Junio C Hamano
2017-10-24 2:52 ` Stefan Beller
2017-10-23 21:30 ` [PATCH 2/5] connect: split ssh command line options into " Jonathan Nieder
2017-10-23 21:48 ` Stefan Beller
2017-10-23 21:31 ` [PATCH 3/5] ssh: 'auto' variant to select between 'ssh' and 'simple' Jonathan Nieder
2017-10-23 22:19 ` Jonathan Tan
2017-10-23 22:43 ` Jonathan Nieder
2017-10-23 22:51 ` Brandon Williams
2017-10-23 22:57 ` Jonathan Tan
2017-10-23 23:16 ` [PATCH v2 0/5] Coping with unrecognized ssh wrapper scripts in GIT_SSH Jonathan Nieder
2017-10-23 23:17 ` [PATCH 1/5] connect: split git:// setup into a separate function Jonathan Nieder
2017-10-24 1:44 ` Junio C Hamano
2017-11-15 20:25 ` Jonathan Nieder
2017-11-17 1:12 ` Junio C Hamano
2017-10-23 23:17 ` [PATCH 2/5] connect: split ssh command line options into " Jonathan Nieder
2017-10-24 2:01 ` Junio C Hamano
2017-10-23 23:18 ` [PATCH 3/5] ssh: 'auto' variant to select between 'ssh' and 'simple' Jonathan Nieder
2017-10-23 23:27 ` Brandon Williams
2017-10-23 23:33 ` Stefan Beller
2017-10-23 23:19 ` [PATCH 4/5] ssh: 'simple' variant does not support -4/-6 Jonathan Nieder
2017-10-23 23:19 ` [PATCH 5/5] ssh: 'simple' variant does not support --port Jonathan Nieder
2017-10-24 2:22 ` [PATCH v2 0/5] Coping with unrecognized ssh wrapper scripts in GIT_SSH Junio C Hamano
2017-10-23 23:12 ` [PATCH 3/5] ssh: 'auto' variant to select between 'ssh' and 'simple' Jonathan Nieder
2017-10-23 22:33 ` Stefan Beller
2017-10-23 22:54 ` Jonathan Nieder
2017-10-24 2:16 ` Junio C Hamano
2017-10-25 12:51 ` Johannes Schindelin
2017-10-25 16:18 ` Stefan Beller
2017-10-25 16:32 ` Jonathan Nieder
2017-10-30 0:40 ` Junio C Hamano
2017-10-30 12:37 ` Johannes Schindelin
2017-10-23 21:32 ` [PATCH 4/5] ssh: 'simple' variant does not support -4/-6 Jonathan Nieder
2017-10-23 21:33 ` [PATCH 5/5] ssh: 'simple' variant does not support --port Jonathan Nieder
2017-10-23 22:37 ` Stefan Beller
2017-10-04 6:20 ` [PATCH v3 00/10] protocol transition Junio C Hamano
2017-10-10 19:39 ` [PATCH] Documentation: document Extra Parameters Jonathan Tan
2017-10-13 22:26 ` Brandon Williams
2017-10-16 17:55 ` [PATCH v4 00/11] protocol transition Brandon Williams
2017-10-16 17:55 ` [PATCH v4 01/11] connect: in ref advertisement, shallows are last Brandon Williams
2017-10-16 17:55 ` [PATCH v4 02/11] pkt-line: add packet_write function Brandon Williams
2017-10-16 17:55 ` [PATCH v4 03/11] protocol: introduce protocol extension mechanisms Brandon Williams
2017-10-16 21:25 ` Kevin Daudt
2017-10-16 17:55 ` [PATCH v4 04/11] daemon: recognize hidden request arguments Brandon Williams
2017-10-16 17:55 ` [PATCH v4 05/11] upload-pack, receive-pack: introduce protocol version 1 Brandon Williams
2017-10-16 17:55 ` [PATCH v4 06/11] connect: teach client to recognize v1 server response Brandon Williams
2017-10-16 17:55 ` [PATCH v4 07/11] connect: tell server that the client understands v1 Brandon Williams
2017-10-16 17:55 ` [PATCH v4 08/11] http: " Brandon Williams
2017-10-16 17:55 ` [PATCH v4 09/11] i5700: add interop test for protocol transition Brandon Williams
2017-10-16 17:55 ` [PATCH v4 10/11] ssh: introduce a 'simple' ssh variant Brandon Williams
2017-10-16 17:55 ` [PATCH v4 11/11] Documentation: document Extra Parameters Brandon Williams
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171003201507.3589-2-bmwill@google.com \
--to=bmwill@google.com \
--cc=bturner@atlassian.com \
--cc=git@jeffhostetler.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=jonathantanmy@google.com \
--cc=jrnieder@gmail.com \
--cc=peff@peff.net \
--cc=sbeller@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.