diff --git a/examples/network/fetch.c b/examples/network/fetch.c index e341d2d6c..8048fd67a 100644 --- a/examples/network/fetch.c +++ b/examples/network/fetch.c @@ -70,7 +70,7 @@ int fetch(git_repository *repo, int argc, char **argv) const git_transfer_progress *stats; pthread_t worker; struct dl_data data; - git_remote_callbacks callbacks; + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; argc = argc; // Figure out whether it's a named remote or a URL @@ -81,7 +81,6 @@ int fetch(git_repository *repo, int argc, char **argv) } // Set up the callbacks (only update_tips for now) - memset(&callbacks, 0, sizeof(callbacks)); callbacks.update_tips = &update_cb; callbacks.progress = &progress_cb; git_remote_set_callbacks(remote, &callbacks); diff --git a/include/git2/remote.h b/include/git2/remote.h index e5b60b951..3e22004a1 100644 --- a/include/git2/remote.h +++ b/include/git2/remote.h @@ -356,8 +356,9 @@ struct git_remote_callbacks { * * @param remote the remote to configure * @param callbacks a pointer to the user's callback settings + * @return 0 or an error code */ -GIT_EXTERN(void) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); +GIT_EXTERN(int) git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks); /** * Get the statistics structure that is filled in by the fetch operation. diff --git a/src/remote.c b/src/remote.c index c84911aa1..d516d07fb 100644 --- a/src/remote.c +++ b/src/remote.c @@ -985,10 +985,25 @@ void git_remote_check_cert(git_remote *remote, int check) remote->check_cert = check; } -void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks) +static bool callbacks_have_valid_version(git_remote_callbacks *callbacks) +{ + if (!callbacks) + return true; + + if (callbacks->version > 0 && callbacks->version <= GIT_REMOTE_CALLBACKS_VERSION) + return true; + + giterr_set(GITERR_INVALID, "Invalid version %d for git_remote_callbacks", callbacks->version); + return false; +} + +int git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks) { assert(remote && callbacks); + if (!callbacks_have_valid_version(callbacks)) + return -1; + memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks)); if (remote->transport && remote->transport->set_callbacks) @@ -996,6 +1011,8 @@ void git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callback remote->callbacks.progress, NULL, remote->callbacks.payload); + + return 0; } void git_remote_set_cred_acquire_cb( diff --git a/tests-clar/network/fetch.c b/tests-clar/network/fetch.c index 26937c608..859479e6e 100644 --- a/tests-clar/network/fetch.c +++ b/tests-clar/network/fetch.c @@ -36,10 +36,9 @@ static void progress(const git_transfer_progress *stats, void *payload) static void do_fetch(const char *url, git_remote_autotag_option_t flag, int n) { git_remote *remote; - git_remote_callbacks callbacks; + git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT; size_t bytes_received = 0; - memset(&callbacks, 0, sizeof(git_remote_callbacks)); callbacks.update_tips = update_tips; counter = 0; diff --git a/tests-clar/network/push_util.h b/tests-clar/network/push_util.h index 2f4dffce4..759122aa6 100644 --- a/tests-clar/network/push_util.h +++ b/tests-clar/network/push_util.h @@ -11,7 +11,8 @@ extern const git_oid OID_ZERO; * record data in a record_callbacks_data instance. * @param data pointer to a record_callbacks_data instance */ -#define RECORD_CALLBACKS_INIT(data) { NULL, NULL, record_update_tips_cb, data } +#define RECORD_CALLBACKS_INIT(data) \ + { GIT_REMOTE_CALLBACKS_VERSION, NULL, NULL, record_update_tips_cb, data } typedef struct { char *name;