commit 9a682fbe2c64ce71685dc332f7d2758ede442224 from: Stefan Sperling date: Thu Mar 19 14:43:38 2020 UTC add support for Git's SCP style URLs to got_fetch_parse_uri() commit - f68a789010192e18ab34908cd5fde2d531c35fdc commit + 9a682fbe2c64ce71685dc332f7d2758ede442224 blob - c82af734662e46f71c8f251dae7e1932a3a1ce57 blob + 0d45d173276f8ac93d898c2c552e2430bdbb95eb --- lib/fetch.c +++ lib/fetch.c @@ -229,58 +229,78 @@ got_fetch_parse_uri(char **proto, char **host, char ** { const struct got_error *err = NULL; char *s, *p, *q; - int n, hasport; + int n; *proto = *host = *port = *server_path = *repo_name = NULL; p = strstr(uri, "://"); if (!p) { - return got_error(GOT_ERR_PARSE_URI); - } - *proto = strndup(uri, p - uri); - if (proto == NULL) { - err = got_error_from_errno("strndup"); - goto done; - } - - hasport = (strcmp(*proto, "git") == 0 || - strstr(*proto, "http") == *proto); - s = p + 3; - p = NULL; - if (!hasport) { - p = strstr(s, ":"); - if (p != NULL) - p++; - } - if (p == NULL) - p = strstr(s, "/"); - if (p == NULL || strlen(p) == 1) { - err = got_error(GOT_ERR_PARSE_URI); - goto done; - } - - q = memchr(s, ':', p - s); - if (q) { + /* Try parsing Git's "scp" style URL syntax. */ + *proto = strdup("ssh"); + if (proto == NULL) { + err = got_error_from_errno("strdup"); + goto done; + } + *port = strdup("22"); + if (*port == NULL) { + err = got_error_from_errno("strdup"); + goto done; + } + s = (char *)uri; + q = strchr(s, ':'); + if (q == NULL) { + err = got_error(GOT_ERR_PARSE_URI); + goto done; + } + /* No slashes allowed before first colon. */ + p = strchr(s, '/'); + if (p && q > p) { + err = got_error(GOT_ERR_PARSE_URI); + goto done; + } *host = strndup(s, q - s); if (*host == NULL) { err = got_error_from_errno("strndup"); goto done; } - *port = strndup(q + 1, p - (q + 1)); - if (*port == NULL) { - err = got_error_from_errno("strndup"); - goto done; - } + p = q + 1; } else { - *host = strndup(s, p - s); - if (*host == NULL) { + *proto = strndup(uri, p - uri); + if (proto == NULL) { err = got_error_from_errno("strndup"); goto done; } - if (asprintf(port, "%u", GOT_DEFAULT_GIT_PORT) == -1) { - err = got_error_from_errno("asprintf"); + s = p + 3; + + p = strstr(s, "/"); + if (p == NULL || strlen(p) == 1) { + err = got_error(GOT_ERR_PARSE_URI); goto done; } + + q = memchr(s, ':', p - s); + if (q) { + *host = strndup(s, q - s); + if (*host == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + *port = strndup(q + 1, p - (q + 1)); + if (*port == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + } else { + *host = strndup(s, p - s); + if (*host == NULL) { + err = got_error_from_errno("strndup"); + goto done; + } + if (asprintf(port, "%u", GOT_DEFAULT_GIT_PORT) == -1) { + err = got_error_from_errno("asprintf"); + goto done; + } + } } *server_path = strdup(p); @@ -289,13 +309,17 @@ got_fetch_parse_uri(char **proto, char **host, char ** goto done; } - p = strrchr(p, '/') + 1; - if (!p || strlen(p) == 0) { - //werrstr("missing repository in uri"); + p = strrchr(p, '/'); + if (!p || strlen(p) <= 1) { err = got_error(GOT_ERR_PARSE_URI); goto done; } + p++; n = strlen(p); + if (n == 0) { + err = got_error(GOT_ERR_PARSE_URI); + goto done; + } if (hassuffix(p, ".git")) n -= 4; *repo_name = strndup(p, (p + n) - p); blob - a43ae11cedd1948f4e7325fa76ffe35512c88ebc blob + ff64378ee31865853d76973f1ac1ecf6f4c31698 --- regress/fetch/fetch_test.c +++ regress/fetch/fetch_test.c @@ -79,6 +79,8 @@ fetch_parse_uri(void) NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI }, { "git:///127.0.0.1/git/", NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI }, + { "/127.0.0.1:/git/", + NULL, NULL, NULL, NULL, NULL, GOT_ERR_PARSE_URI }, { "git://127.0.0.1/git/myrepo", "git", "localhost", GOT_DEFAULT_GIT_PORT_STR, "git", @@ -100,6 +102,16 @@ fetch_parse_uri(void) "https", "localhost", GOT_DEFAULT_GIT_PORT_STR, "git/repos/foo/../bar", "myrepo", GOT_ERR_OK }, + { "git+ssh://127.0.0.1:22/git/myrepo", + "git+ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK }, + { "ssh://127.0.0.1:22/git/myrepo", + "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK }, + { "127.0.0.1:git/myrepo", + "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK }, + { "127.0.0.1:/git/myrepo", + "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK }, + { "127.0.0.1:22/git/myrepo", + "ssh", "localhost", "22", "git", "myrepo", GOT_ERR_OK }, }; int i;