Skip to content

Commit 33d0ad9

Browse files
committed
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.
1 parent 86e5003 commit 33d0ad9

File tree

1 file changed

+28
-34
lines changed

1 file changed

+28
-34
lines changed

src/remote.c

Lines changed: 28 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030

3131
static int dwim_refspecs(git_vector *out, git_vector *refspecs, git_vector *refs);
3232
static int lookup_remote_prune_config(git_remote *remote, git_config *config, const char *name);
33-
char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction);
33+
static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty);
3434

3535
static int add_refspec_to(git_vector *vector, const char *string, bool is_fetch)
3636
{
@@ -210,9 +210,7 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
210210
git_str var = GIT_STR_INIT;
211211
git_str specbuf = GIT_STR_INIT;
212212
const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT;
213-
char *tmp;
214213
int error = -1;
215-
bool matched;
216214

217215
GIT_ASSERT_ARG(out);
218216
GIT_ASSERT_ARG(url);
@@ -247,16 +245,13 @@ int git_remote_create_with_opts(git_remote **out, const char *url, const git_rem
247245
goto on_error;
248246

249247
if (opts->repository && !(opts->flags & GIT_REMOTE_CREATE_SKIP_INSTEADOF)) {
250-
remote->url = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH);
251-
tmp = apply_insteadof(&matched, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH);
252-
if (matched) {
253-
remote->pushurl = tmp;
254-
GIT_ERROR_CHECK_ALLOC(remote->pushurl);
255-
}
248+
if ((error = apply_insteadof(&remote->url, config_ro, canonical_url.ptr, GIT_DIRECTION_FETCH, true)) < 0 ||
249+
(error = apply_insteadof(&remote->pushurl, config_ro, canonical_url.ptr, GIT_DIRECTION_PUSH, false)) < 0)
250+
goto on_error;
256251
} else {
257252
remote->url = git__strdup(canonical_url.ptr);
253+
GIT_ERROR_CHECK_ALLOC(remote->url);
258254
}
259-
GIT_ERROR_CHECK_ALLOC(remote->url);
260255

261256
if (opts->name != NULL) {
262257
remote->name = git__strdup(opts->name);
@@ -464,9 +459,7 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
464459
git_remote *remote = NULL;
465460
git_str buf = GIT_STR_INIT;
466461
const char *val;
467-
char *tmp;
468462
int error = 0;
469-
bool matched;
470463
git_config *config;
471464
struct refspec_cb_data data = { NULL };
472465
bool optional_setting_found = false, found;
@@ -507,13 +500,9 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
507500
remote->download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO;
508501

509502
if (found && strlen(val) > 0) {
510-
remote->url = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH);
511-
GIT_ERROR_CHECK_ALLOC(remote->url);
512-
tmp = apply_insteadof(&matched, config, val, GIT_DIRECTION_PUSH);
513-
if (matched) {
514-
remote->pushurl = tmp;
515-
GIT_ERROR_CHECK_ALLOC(remote->pushurl);
516-
}
503+
if ((error = apply_insteadof(&remote->url, config, val, GIT_DIRECTION_FETCH, true)) < 0 ||
504+
(error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_PUSH, false)) < 0)
505+
goto cleanup;
517506
}
518507

519508
val = NULL;
@@ -532,11 +521,11 @@ int git_remote_lookup(git_remote **out, git_repository *repo, const char *name)
532521
}
533522

534523
if (found && strlen(val) > 0) {
535-
if (remote->pushurl) {
524+
if (remote->pushurl)
536525
git__free(remote->pushurl);
537-
}
538-
remote->pushurl = apply_insteadof(&matched, config, val, GIT_DIRECTION_FETCH);
539-
GIT_ERROR_CHECK_ALLOC(remote->pushurl);
526+
527+
if ((error = apply_insteadof(&remote->pushurl, config, val, GIT_DIRECTION_FETCH, true)) < 0)
528+
goto cleanup;
540529
}
541530

542531
data.remote = remote;
@@ -2736,7 +2725,7 @@ int git_remote_push(git_remote *remote, const git_strarray *refspecs, const git_
27362725
#define SUFFIX_FETCH "insteadof"
27372726
#define SUFFIX_PUSH "pushinsteadof"
27382727

2739-
char *apply_insteadof(bool *matched, git_config *config, const char *url, int direction)
2728+
static int apply_insteadof(char **out, git_config *config, const char *url, int direction, bool use_default_if_empty)
27402729
{
27412730
size_t match_length, prefix_length, suffix_length;
27422731
char *replacement = NULL;
@@ -2746,11 +2735,10 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
27462735
git_config_entry *entry;
27472736
git_config_iterator *iter;
27482737

2749-
GIT_ASSERT_ARG_WITH_RETVAL(config, NULL);
2750-
GIT_ASSERT_ARG_WITH_RETVAL(url, NULL);
2751-
GIT_ASSERT_ARG_WITH_RETVAL(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH, NULL);
2752-
GIT_ASSERT_ARG_WITH_RETVAL(matched, NULL);
2753-
*matched = 0;
2738+
GIT_ASSERT_ARG(out);
2739+
GIT_ASSERT_ARG(config);
2740+
GIT_ASSERT_ARG(url);
2741+
GIT_ASSERT_ARG(direction == GIT_DIRECTION_FETCH || direction == GIT_DIRECTION_PUSH);
27542742

27552743
/* Add 1 to prefix/suffix length due to the additional escaped dot */
27562744
prefix_length = strlen(PREFIX) + 1;
@@ -2763,7 +2751,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
27632751
}
27642752

27652753
if (git_config_iterator_glob_new(&iter, config, regexp) < 0)
2766-
return NULL;
2754+
return -1;
27672755

27682756
match_length = 0;
27692757
while (git_config_next(&entry, iter) == 0) {
@@ -2772,6 +2760,7 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
27722760
/* Check if entry value is a prefix of URL */
27732761
if (git__prefixcmp(url, entry->value))
27742762
continue;
2763+
27752764
/* Check if entry value is longer than previous
27762765
* prefixes */
27772766
if ((n = strlen(entry->value)) <= match_length)
@@ -2789,15 +2778,20 @@ char *apply_insteadof(bool *matched, git_config *config, const char *url, int di
27892778

27902779
git_config_iterator_free(iter);
27912780

2792-
if (match_length == 0)
2793-
return git__strdup(url);
2781+
if (match_length == 0 && use_default_if_empty) {
2782+
*out = git__strdup(url);
2783+
return *out ? 0 : -1;
2784+
} else if (match_length == 0) {
2785+
*out = NULL;
2786+
return 0;
2787+
}
27942788

27952789
git_str_printf(&result, "%s%s", replacement, url + match_length);
27962790

27972791
git__free(replacement);
27982792

2799-
*matched = 1;
2800-
return result.ptr;
2793+
*out = git_str_detach(&result);
2794+
return 0;
28012795
}
28022796

28032797
/* Deprecated functions */

0 commit comments

Comments
 (0)