From: Stefan Sperling Subject: fix got clone url with trailing slash To: gameoftrees@openbsd.org Date: Mon, 7 Mar 2022 09:47:43 +0100 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/",