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@[email protected]: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://[email protected]@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 [email protected]

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

$ ./lg2 clone ssh://[email protected]: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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions