Skip to content

clone username with @ #6199

@albfan

Description

@albfan

Reproduction steps

I'm using libgit2 in gitg. I have a report of a fail to clone:

https://gitlab.gnome.org/GNOME/gitg/-/issues/356

Expected behavior

clone url

Actual behavior

malformed URL 'ssh://my.email.address@gmail.com@source.developers.google.com:2022/p/my-project/r/my-repository'

Version of libgit2 (release number or SHA1)

v1.0.0, but I tested main and still fails

Operating system(s) tested

linux

I use this patch to test http_parser_parse_url:

diff --git c/src/net.c i/src/net.c
index d42fce52d..612a6ea85 100644
--- c/src/net.c
+++ i/src/net.c
@@ -35,6 +35,10 @@ static const char *default_port_for_scheme(const char *scheme)
        return NULL;
 }
 
+char* bool_str(b) {
+  return b ? "true": "false";
+}
+
 int git_net_url_parse(git_net_url *url, const char *given)
 {
        struct http_parser_url u = {0};
@@ -48,10 +52,7 @@ int git_net_url_parse(git_net_url *url, const char *given)
                query = GIT_BUF_INIT;
        int error = GIT_EINVALIDSPEC;
 
-       if (http_parser_parse_url(given, strlen(given), false, &u)) {
-               git_error_set(GIT_ERROR_NET, "malformed URL '%s'", given);
-               goto done;
-       }
+       http_parser_parse_url(given, strlen(given), false, &u);
 
        has_scheme = !!(u.field_set & (1 << UF_SCHEMA));
        has_host = !!(u.field_set & (1 << UF_HOST));
@@ -60,9 +61,18 @@ int git_net_url_parse(git_net_url *url, const char *given)
        has_query = !!(u.field_set & (1 << UF_QUERY));
        has_userinfo = !!(u.field_set & (1 << UF_USERINFO));
 
+       printf("scheme:   %s\n", bool_str(has_scheme));
+       printf("host:     %s\n", bool_str(has_host));
+       printf("port:     %s\n", bool_str(has_port));
+       printf("path:     %s\n", bool_str(has_path));
+       printf("query:    %s\n", bool_str(has_query));
+       printf("userinfo: %s\n", bool_str(has_userinfo));
+       printf("\n");
+
        if (has_scheme) {
                const char *url_scheme = given + u.field_data[UF_SCHEMA].off;
                size_t url_scheme_len = u.field_data[UF_SCHEMA].len;
+               printf("scheme: %.*s\n", url_scheme_len, url_scheme);
                git_buf_put(&scheme, url_scheme, url_scheme_len);
                git__strntolower(scheme.ptr, scheme.size);
        } else {
@@ -73,12 +83,14 @@ int git_net_url_parse(git_net_url *url, const char *given)
        if (has_host) {
                const char *url_host = given + u.field_data[UF_HOST].off;
                size_t url_host_len = u.field_data[UF_HOST].len;
+               printf("host: %.*s\n", url_host_len, url_host);
                git_buf_decode_percent(&host, url_host, url_host_len);
        }
 
        if (has_port) {
                const char *url_port = given + u.field_data[UF_PORT].off;
                size_t url_port_len = u.field_data[UF_PORT].len;
+               printf("port: %.*s\n", url_port_len, url_port);
                git_buf_put(&port, url_port, url_port_len);
        } else {
                const char *default_port = default_port_for_scheme(scheme.ptr);
@@ -88,26 +100,31 @@ int git_net_url_parse(git_net_url *url, const char *given)
                        goto done;
                }
 
+               printf("port: %s\n", default_port);
                git_buf_puts(&port, default_port);
        }
 
        if (has_path) {
                const char *url_path = given + u.field_data[UF_PATH].off;
                size_t url_path_len = u.field_data[UF_PATH].len;
+               printf("path: %.*s\n", url_path_len, url_path);
                git_buf_put(&path, url_path, url_path_len);
        } else {
+               printf("path: %s\n", "/");
                git_buf_puts(&path, "/");
        }
 
        if (has_query) {
                const char *url_query = given + u.field_data[UF_QUERY].off;
                size_t url_query_len = u.field_data[UF_QUERY].len;
+               printf("query: %.*s\n", url_query_len, url_query);
                git_buf_decode_percent(&query, url_query, url_query_len);
        }
 
        if (has_userinfo) {
                const char *url_userinfo = given + u.field_data[UF_USERINFO].off;
                size_t url_userinfo_len = u.field_data[UF_USERINFO].len;
+               printf("userinfo: %.*s\n", url_userinfo_len, url_userinfo);
                const char *colon = memchr(url_userinfo, ':', url_userinfo_len);
 
                if (colon) {

the output was:

$ ./lg2 clone ssh://my.email.address@gmail.com@source.developers.google.com:2022/p/my-project/r/my-repository clone_dir
scheme:   true
host:     true
port:     false
path:     true
query:    false
userinfo: true

scheme: ssh
host: gmail.com
port: 22
path: /p/my-project/r/my-repository
userinfo: my.email.address

my understanding is that user is whole my.email.address@gmail.com

I tested with a usual url (without @ on username)

$ ./lg2 clone ssh://myuser@company.org:2222/dir/repo.git dir
scheme:   true
host:     true
port:     true
path:     true
query:    false
userinfo: true

scheme: ssh
host: company.org
port: 2222
path: /dir/repo.git
userinfo: myuser

Is it possible to modify username to accept @?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions