Thread (11 messages) 11 messages, 5 authors, 2023-05-24

Re: [PATCH v2] builtin/submodule--helper.c: handle missing submodule URLs

From: Eric Sunshine <hidden>
Date: 2023-05-24 18:49:14

On Wed, May 24, 2023 at 12:40 PM Taylor Blau [off-list ref] wrote:
In e0a862fdaf (submodule helper: convert relative URL to absolute URL if
needed, 2018-10-16), `prepare_to_clone_next_submodule()` lost the
ability to handle URL-less submodules, due to a change from:

    if (repo_get_config_string_const(the_repostiory, sb.buf, &url))
        url = sub->url;

to

    if (repo_get_config_string_const(the_repostiory, sb.buf, &url)) {
        if (starts_with_dot_slash(sub->url) ||
            starts_with_dot_dot_slash(sub->url)) {
                /* ... */
            }
    }

, which will segfault when `sub->url` is NULL, since both
`starts_with_dot_slash()` does not guard its arguments as non-NULL.

Guard the checks to both of the above functions by first whether
s/first/first checking/
quoted hunk ↗ jump to hunk
`sub->url` is non-NULL. There is no need to check whether `sub` itself
is NULL, since we already perform this check earlier in
`prepare_to_clone_next_submodule()`.

By adding a NULL-ness check on `sub->url`, we'll fall into the 'else'
branch, setting `url` to `sub->url` (which is NULL). Before attempting
to invoke `git submodule--helper clone`, check whether `url` is NULL,
and die() if it is.

Reported-by: Tribo Dar <redacted>
Signed-off-by: Taylor Blau <redacted>
---
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
@@ -2024,14 +2024,17 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
-               if (starts_with_dot_slash(sub->url) ||
-                   starts_with_dot_dot_slash(sub->url)) {
+               if (sub->url && (starts_with_dot_slash(sub->url) ||
+                                starts_with_dot_dot_slash(sub->url))) {
                        url = resolve_relative_url(sub->url, NULL, 0);
                        need_free_url = 1;
                } else
                        url = sub->url;
        }

+       if (!url)
+               die(_("cannot clone submodule '%s' without a URL"), sub->name);
Good. The first version of this patch was more difficult to reason
about due to its "error-at-a-distance" approach. This version is much
cleaner and obvious.
quoted hunk ↗ jump to hunk
@@ -2065,11 +2068,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce,
                strvec_pushf(&child->args, "--filter=%s",
                             expand_list_objects_filter_spec(suc->update_data->filter_options));
+       strvec_pushl(&child->args, "--url", url, NULL);
        if (suc->update_data->require_init)
                strvec_push(&child->args, "--require-init");
        strvec_pushl(&child->args, "--path", sub->path, NULL);
        strvec_pushl(&child->args, "--name", sub->name, NULL);
-       strvec_pushl(&child->args, "--url", url, NULL);
This change is unnecessary now, isn't it? Or is there something
nonobvious going on here?
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help