[PATCHv4 03/10] Tighten rules for matching server capabilities in server_supports()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When using server_supports() to match a given "feature" against the server
capabilities, follow these rules:

 - "feature" must appear at the beginning of server_capabilities, or the
   byte immediately before the matched location in server_capabilities
   must be a SP; and

 - if "feature" does not end with an equal sign, it does not expect a
   value. The byte after the matched location in server_capabilities must
   be either the end of string or a SP. A feature that expects a value is
   checked with 'server_supports("feature=")' and the matched location in
   server_capabilities can be followed by anything (i.e. if at the end of
   string or a SP, it gets an empty string as the value, and otherwise it
   will get the stretch of bytes after the '=' up to the next SP).

Given the server_capabilities string "foo=ab bar=froboz boz",
this patch should make it behave as follows:

  server_supports("foo=") matches "foo=ab", returns "ab";

  server_supports("ab") does not match anything;

  server_supports("bar") does not match anything;

  server_supports("boz") matches (and returns "boz"), without failing
                         at the end of bar=froboz that comes earlier.

Suggested-by: Junio C Hamano <gitster@xxxxxxxxx>
Signed-off-by: Johan Herland <johan@xxxxxxxxxxx>
---
 cache.h   |    2 +-
 connect.c |   30 +++++++++++++++++++++++++++---
 2 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/cache.h b/cache.h
index 009b365..1a9338f 100644
--- a/cache.h
+++ b/cache.h
@@ -995,7 +995,7 @@ struct extra_have_objects {
 	unsigned char (*array)[20];
 };
 extern struct ref **get_remote_heads(int in, struct ref **list, int nr_match, char **match, unsigned int flags, struct extra_have_objects *);
-extern int server_supports(const char *feature);
+extern const char *server_supports(const char *feature);
 
 extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path);
 
diff --git a/connect.c b/connect.c
index 2119c3f..3c0a706 100644
--- a/connect.c
+++ b/connect.c
@@ -8,6 +8,7 @@
 #include "url.h"
 
 static char *server_capabilities;
+static size_t server_capabilities_len;
 
 static int check_ref(const char *name, int len, unsigned int flags)
 {
@@ -80,8 +81,16 @@ struct ref **get_remote_heads(int in, struct ref **list,
 
 		name_len = strlen(name);
 		if (len != name_len + 41) {
+			char *p;
 			free(server_capabilities);
 			server_capabilities = xstrdup(name + name_len + 1);
+			server_capabilities_len = strlen(server_capabilities);
+			/* split capabilities on SP */
+			for (p = server_capabilities;
+			     p < server_capabilities + server_capabilities_len;
+			     p++)
+				if (*p == ' ')
+					*p = '\0';
 		}
 
 		if (extra_have &&
@@ -102,10 +111,25 @@ struct ref **get_remote_heads(int in, struct ref **list,
 	return list;
 }
 
-int server_supports(const char *feature)
+const char *server_supports(const char *feature)
 {
-	return server_capabilities &&
-		strstr(server_capabilities, feature) != NULL;
+	const char *p = server_capabilities;
+	size_t feature_len = strlen(feature);
+	int need_value = feature[feature_len - 1] == '=';
+
+	if (!server_capabilities)
+		return NULL;
+
+	for (p = server_capabilities;
+	     p < server_capabilities + server_capabilities_len;
+	     p += strlen(p) + 1) {
+		if (need_value) {
+			if (!strncmp(p, feature, feature_len))
+				return p + feature_len;
+		} else if (!strcmp(p, feature))
+			return p;
+	}
+	return NULL;
 }
 
 int path_match(const char *path, int nr, char **match)
-- 
1.7.5.rc1.3.g4d7b

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]