Commit 33d0ad9c by Edward Thomson

remote: refactor insteadof application

Using the insteadof helper would leak memory when we didn't really want
the pushInsteadOf configuration.  Refactor the choice into the function
that allocates memory (or now, not) and use a more idiomatic `int`
return code.
parent 86e5003d
...@@ -30,7 +30,7 @@ ...@@ -30,7 +30,7 @@
static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs); static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs);
static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name); static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name);
char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction); static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty);
static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch) static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch)
{ {
...@@ -210,9 +210,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem ...@@ -210,9 +210,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
git_str var = GIT_STR_INIT; git_str var = GIT_STR_INIT;
git_str specbuf = GIT_STR_INIT; git_str specbuf = GIT_STR_INIT;
const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT; const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT;
char *tmp;
int error = -1; int error = -1;
bool matched;
GIT_ASSERT_ARG(out); GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG(url); GIT_ASSERT_ARG(url);
...@@ -247,16 +245,13 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem ...@@ -247,16 +245,13 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
goto on_error; goto on_error;
if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) { if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) {
remote->url = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH); if ((error = apply_insteadof(&remote->url, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH, true)) < 0 ||
tmp = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH); (error = apply_insteadof(&remote->pushurl, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH, false)) < 0)
if (matched) { goto on_error;
remote->pushurl = tmp;
GIT_ERROR_CHECK_ALLOC(remote->pushurl);
}
} else { } else {
remote->url = git__strdup(canonical_url.ptr); remote->url = git__strdup(canonical_url.ptr);
GIT_ERROR_CHECK_ALLOC(remote->url);
} }
GIT_ERROR_CHECK_ALLOC(remote->url);
if (opts->name != NULL) { if (opts->name != NULL) {
remote->name = git__strdup(opts->name); remote->name = git__strdup(opts->name);
...@@ -464,9 +459,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) ...@@ -464,9 +459,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
git_remote *remote = NULL; git_remote *remote = NULL;
git_str buf = GIT_STR_INIT; git_str buf = GIT_STR_INIT;
const char *val; const char *val;
char *tmp;
int error = 0; int error = 0;
bool matched;
git_config *config; git_config *config;
struct refspec_cb_data data = { NULL }; struct refspec_cb_data data = { NULL };
bool optional_setting_found = false, found; bool optional_setting_found = false, found;
...@@ -507,13 +500,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) ...@@ -507,13 +500,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO; remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
if (found && strlen(val) > 0) { if (found && strlen(val) > 0) {
remote->url = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH); if ((error = apply_insteadof(&remote->url, config, val, GIT_DIRECTION_FETCH, true)) < 0 ||
GIT_ERROR_CHECK_ALLOC(remote->url); (error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_PUSH, false)) < 0)
tmp = apply_insteadof(&matched, config, val, GIT_DIRECTION_PUSH); goto cleanup;
if (matched) {
remote->pushurl = tmp;
GIT_ERROR_CHECK_ALLOC(remote->pushurl);
}
} }
val = NULL; val = NULL;
...@@ -532,11 +521,11 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name) ...@@ -532,11 +521,11 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
} }
if (found && strlen(val) > 0) { if (found && strlen(val) > 0) {
if (remote->pushurl) { if (remote->pushurl)
git__free(remote->pushurl); git__free(remote->pushurl);
}
remote->pushurl = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH); if ((error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_FETCH, true)) < 0)
GIT_ERROR_CHECK_ALLOC(remote->pushurl); goto cleanup;
} }
data.remote = remote; data.remote = remote;
...@@ -2736,7 +2725,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_ ...@@ -2736,7 +2725,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
#define SUFFIX_FETCH "insteadof" #define SUFFIX_FETCH "insteadof"
#define SUFFIX_PUSH "pushinsteadof" #define SUFFIX_PUSH "pushinsteadof"
char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction) static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty)
{ {
size_t match_length, prefix_length, suffix_length; size_t match_length, prefix_length, suffix_length;
char *replacement = NULL; char *replacement = NULL;
...@@ -2746,11 +2735,10 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di ...@@ -2746,11 +2735,10 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
git_config_entry *entry; git_config_entry *entry;
git_config_iterator *iter; git_config_iterator *iter;
GIT_ASSERT_ARG_WITH_RETVAL(config, NULL); GIT_ASSERT_ARG(out);
GIT_ASSERT_ARG_WITH_RETVAL(url, NULL); GIT_ASSERT_ARG(config);
GIT_ASSERT_ARG_WITH_RETVAL(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH, NULL); GIT_ASSERT_ARG(url);
GIT_ASSERT_ARG_WITH_RETVAL(matched, NULL); GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
*matched = 0;
/* Add 1 to prefix/suffix length due to the additional escaped dot */ /* Add 1 to prefix/suffix length due to the additional escaped dot */
prefix_length = strlen(PREFIX) + 1; prefix_length = strlen(PREFIX) + 1;
...@@ -2763,7 +2751,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di ...@@ -2763,7 +2751,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
} }
if (git_config_iterator_glob_new(&iter, config, regexp) < 0) if (git_config_iterator_glob_new(&iter, config, regexp) < 0)
return NULL; return -1;
match_length = 0; match_length = 0;
while (git_config_next(&entry, iter) == 0) { while (git_config_next(&entry, iter) == 0) {
...@@ -2772,6 +2760,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di ...@@ -2772,6 +2760,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
/* Check if entry value is a prefix of URL */ /* Check if entry value is a prefix of URL */
if (git__prefixcmp(url, entry->value)) if (git__prefixcmp(url, entry->value))
continue; continue;
/* Check if entry value is longer than previous /* Check if entry value is longer than previous
* prefixes */ * prefixes */
if ((n = strlen(entry->value)) <= match_length) if ((n = strlen(entry->value)) <= match_length)
...@@ -2789,15 +2778,20 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di ...@@ -2789,15 +2778,20 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
git_config_iterator_free(iter); git_config_iterator_free(iter);
if (match_length == 0) if (match_length == 0 && use_default_if_empty) {
return git__strdup(url); *out = git__strdup(url);
return *out ? 0 : -1;
} else if (match_length == 0) {
*out = NULL;
return 0;
}
git_str_printf(&result, "%s%s", replacement, url + match_length); git_str_printf(&result, "%s%s", replacement, url + match_length);
git__free(replacement); git__free(replacement);
*matched = 1; *out = git_str_detach(&result);
return result.ptr; return 0;
} }
/* Deprecated functions */ /* Deprecated functions */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment