"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Stefan Sperling <stsp@stsp.name>
Subject:
fix got clone url with trailing slash
To:
gameoftrees@openbsd.org
Date:
Mon, 7 Mar 2022 09:47:43 +0100

Download raw body.

Thread
Attempting to clone a repository URL which has a trailing slash currently
fails with an error:

$ got clone -l ssh://git@github.com/openbsd/src.git/
got: failed to parse uri

The reason for this error is the trailing slash.

This patch makes the URI parser tolerate trailing slashes at the end
of the input URI and adds a few additional sanity checks for empty
URI components found during parsing.

ok?

diff d802d72265281c9200c722522d463710c2e40160 456f032ded164edd13735eb90268950619f02c22
blob - 6c0be0af379525b0196b72464d3a886e439077d7
blob + 2e29508e51eb4534e7588561c727f6b6cf352503
--- lib/dial.c
+++ lib/dial.c
@@ -83,7 +83,6 @@ got_dial_parse_uri(char **proto, char **host, char **p
 {
 	const struct got_error *err = NULL;
 	char *s, *p, *q;
-	int n;
 
 	*proto = *host = *port = *server_path = *repo_name = NULL;
 
@@ -112,6 +111,10 @@ got_dial_parse_uri(char **proto, char **host, char **p
 			err = got_error_from_errno("strndup");
 			goto done;
 		}
+		if ((*host)[0] == '\0') {
+			err = got_error(GOT_ERR_PARSE_URI);
+			goto done;
+		}
 		p = q + 1;
 	} else {
 		*proto = strndup(uri, p - uri);
@@ -134,17 +137,29 @@ got_dial_parse_uri(char **proto, char **host, char **p
 				err = got_error_from_errno("strndup");
 				goto done;
 			}
+			if ((*host)[0] == '\0') {
+				err = got_error(GOT_ERR_PARSE_URI);
+				goto done;
+			}
 			*port = strndup(q + 1, p - (q + 1));
 			if (*port == NULL) {
 				err = got_error_from_errno("strndup");
 				goto done;
 			}
+			if ((*port)[0] == '\0') {
+				err = got_error(GOT_ERR_PARSE_URI);
+				goto done;
+			}
 		} else {
 			*host = strndup(s, p - s);
 			if (*host == NULL) {
 				err = got_error_from_errno("strndup");
 				goto done;
 			}
+			if ((*host)[0] == '\0') {
+				err = got_error(GOT_ERR_PARSE_URI);
+				goto done;
+			}
 		}
 	}
 
@@ -156,25 +171,18 @@ got_dial_parse_uri(char **proto, char **host, char **p
 		goto done;
 	}
 	got_path_strip_trailing_slashes(*server_path);
+	if ((*server_path)[0] == '\0') {
+		err = got_error(GOT_ERR_PARSE_URI);
+		goto done;
+	}
 
-	p = strrchr(p, '/');
-	if (!p || strlen(p) <= 1) {
-		err = got_error(GOT_ERR_PARSE_URI);
+	err = got_path_basename(repo_name, *server_path);
+	if (err)
 		goto done;
-	}
-	p++;
-	n = strlen(p);
-	if (n == 0) {
+	if (hassuffix(*repo_name, ".git"))
+		(*repo_name)[strlen(*repo_name) - 4] = '\0';
+	if ((*repo_name)[0] == '\0')
 		err = got_error(GOT_ERR_PARSE_URI);
-		goto done;
-	}
-	if (hassuffix(p, ".git"))
-		n -= 4;
-	*repo_name = strndup(p, (p + n) - p);
-	if (*repo_name == NULL) {
-		err = got_error_from_errno("strndup");
-		goto done;
-	}
 done:
 	if (err) {
 		free(*proto);
blob - 66452392324de31782617407a330a0cf27630880
blob + 4afec393aaf467cb872d53e452b471df35ae6c9b
--- regress/fetch/fetch_test.c
+++ regress/fetch/fetch_test.c
@@ -78,7 +78,7 @@ fetch_parse_uri(void)
 		{ "git://localhost////",
 		    NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI },
 		{ "git://127.0.0.1/git/",
-		    NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI },
+		    "git", "127.0.0.1", NULL, "/git", "git", GOT_ERR_OK },
 		{ "git:///127.0.0.1/git/",
 		    NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI },
 		{ "/127.0.0.1:/git/",