summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/checkout.c6
-rw-r--r--src/common.h27
-rw-r--r--src/config.c2
-rw-r--r--src/config_file.c4
-rw-r--r--src/diff.c6
-rw-r--r--src/diff.h1
-rw-r--r--src/diff_output.c2
-rw-r--r--src/diff_tform.c5
-rw-r--r--src/notes.c1
-rw-r--r--src/odb.c2
-rw-r--r--src/odb_loose.c1
-rw-r--r--src/odb_pack.c2
-rw-r--r--src/remote.c8
-rw-r--r--src/repository.c5
-rw-r--r--src/reset.c3
-rw-r--r--src/signature.c2
-rw-r--r--src/stash.c12
-rw-r--r--src/status.c14
-rw-r--r--src/submodule.c6
-rw-r--r--src/transports/local.c5
-rw-r--r--src/transports/smart.c1
21 files changed, 79 insertions, 36 deletions
diff --git a/src/checkout.c b/src/checkout.c
index 8e5de0a7f..33de7adf3 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -232,7 +232,7 @@ static void normalize_options(
assert(normalized);
if (!proposed)
- memset(normalized, 0, sizeof(git_checkout_opts));
+ GIT_INIT_STRUCTURE(normalized, GIT_CHECKOUT_OPTS_VERSION);
else
memmove(normalized, proposed, sizeof(git_checkout_opts));
@@ -611,7 +611,7 @@ int git_checkout_index(
git_checkout_opts *opts)
{
git_diff_list *diff = NULL;
- git_diff_options diff_opts = {0};
+ git_diff_options diff_opts = GIT_DIFF_OPTIONS_INIT;
git_checkout_opts checkout_opts;
checkout_diff_data data;
git_buf workdir = GIT_BUF_INIT;
@@ -621,6 +621,8 @@ int git_checkout_index(
assert(repo);
+ GITERR_CHECK_VERSION(opts, GIT_CHECKOUT_OPTS_VERSION, "git_checkout_opts");
+
if ((error = git_repository__ensure_not_bare(repo, "checkout")) < 0)
return error;
diff --git a/src/common.h b/src/common.h
index b3b551508..3152669df 100644
--- a/src/common.h
+++ b/src/common.h
@@ -65,6 +65,33 @@ void giterr_set(int error_class, const char *string, ...);
*/
int giterr_set_regex(const regex_t *regex, int error_code);
+/**
+ * Check a versioned structure for validity
+ */
+GIT_INLINE(bool) giterr__check_version(const void *structure, unsigned int expected_max, const char *name)
+{
+ if (!structure)
+ return true;
+
+ unsigned int actual = *(const unsigned int*)structure;
+ if (actual > 0 && actual <= expected_max)
+ return true;
+
+ giterr_set(GITERR_INVALID, "Invalid version %d on %s", actual, name);
+ return false;
+}
+#define GITERR_CHECK_VERSION(S,V,N) if (!giterr__check_version(S,V,N)) return -1
+
+/**
+ * Initialize a structure with a version.
+ */
+GIT_INLINE(void) git__init_structure(void *structure, size_t len, unsigned int version)
+{
+ memset(structure, 0, len);
+ *((int*)structure) = version;
+}
+#define GIT_INIT_STRUCTURE(S,V) git__init_structure(S, sizeof(*S), V)
+
/* NOTE: other giterr functions are in the public errors.h header file */
#include "util.h"
diff --git a/src/config.c b/src/config.c
index 6347f7df7..d422447cf 100644
--- a/src/config.c
+++ b/src/config.c
@@ -259,6 +259,8 @@ int git_config_add_backend(
assert(cfg && file);
+ GITERR_CHECK_VERSION(file, GIT_CONFIG_BACKEND_VERSION, "git_config_backend");
+
if ((result = file->open(file, level)) < 0)
return result;
diff --git a/src/config_file.c b/src/config_file.c
index 354a91986..6e29832d4 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -545,10 +545,10 @@ int git_config_file__ondisk(git_config_backend **out, const char *path)
{
diskfile_backend *backend;
- backend = git__malloc(sizeof(diskfile_backend));
+ backend = git__calloc(1, sizeof(diskfile_backend));
GITERR_CHECK_ALLOC(backend);
- memset(backend, 0x0, sizeof(diskfile_backend));
+ backend->parent.version = GIT_CONFIG_BACKEND_VERSION;
backend->file_path = git__strdup(path);
GITERR_CHECK_ALLOC(backend->file_path);
diff --git a/src/diff.c b/src/diff.c
index 86f76f9c0..46d96bb96 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -755,14 +755,14 @@ fail:
return error;
}
-
#define DIFF_FROM_ITERATORS(MAKE_FIRST, MAKE_SECOND) do { \
git_iterator *a = NULL, *b = NULL; \
char *pfx = opts ? git_pathspec_prefix(&opts->pathspec) : NULL; \
- if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
+ GITERR_CHECK_VERSION(opts, GIT_DIFF_OPTIONS_VERSION, "git_diff_options"); \
+ if (!(error = MAKE_FIRST) && !(error = MAKE_SECOND)) \
error = diff_from_iterators(diff, repo, a, b, opts); \
git__free(pfx); git_iterator_free(a); git_iterator_free(b); \
- } while (0)
+} while (0)
int git_diff_tree_to_tree(
git_diff_list **diff,
diff --git a/src/diff.h b/src/diff.h
index 1e3be7593..f93bab18d 100644
--- a/src/diff.h
+++ b/src/diff.h
@@ -61,5 +61,6 @@ extern bool git_diff_delta__should_skip(
extern int git_diff__oid_for_file(
git_repository *, const char *, uint16_t, git_off_t, git_oid *);
+
#endif
diff --git a/src/diff_output.c b/src/diff_output.c
index e137fd0f2..b18255d58 100644
--- a/src/diff_output.c
+++ b/src/diff_output.c
@@ -1266,6 +1266,8 @@ int git_diff_blobs(
git_diff_delta delta;
git_diff_patch patch;
+ GITERR_CHECK_VERSION(options, GIT_DIFF_OPTIONS_VERSION, "git_diff_options");
+
if (options && (options->flags & GIT_DIFF_REVERSE)) {
git_blob *swap = old_blob;
old_blob = new_blob;
diff --git a/src/diff_tform.c b/src/diff_tform.c
index 987d4b8e6..0c588594a 100644
--- a/src/diff_tform.c
+++ b/src/diff_tform.c
@@ -187,7 +187,8 @@ static int normalize_find_opts(
if (given != NULL)
memcpy(opts, given, sizeof(*opts));
else {
- memset(opts, 0, sizeof(*opts));
+ git_diff_find_options init = GIT_DIFF_FIND_OPTIONS_INIT;
+ memmove(opts, &init, sizeof(init));
opts->flags = GIT_DIFF_FIND_RENAMES;
@@ -198,6 +199,8 @@ static int normalize_find_opts(
opts->flags = GIT_DIFF_FIND_RENAMES | GIT_DIFF_FIND_COPIES;
}
+ GITERR_CHECK_VERSION(opts, GIT_DIFF_FIND_OPTIONS_VERSION, "git_diff_find_options");
+
/* some flags imply others */
if (opts->flags & GIT_DIFF_FIND_RENAMES_FROM_REWRITES)
diff --git a/src/notes.c b/src/notes.c
index dd36cc2fe..f96b5b139 100644
--- a/src/notes.c
+++ b/src/notes.c
@@ -11,6 +11,7 @@
#include "refs.h"
#include "config.h"
#include "iterator.h"
+#include "signature.h"
static int find_subtree_in_current_level(
git_tree **out,
diff --git a/src/odb.c b/src/odb.c
index 63b68284a..b6d1f798d 100644
--- a/src/odb.c
+++ b/src/odb.c
@@ -369,6 +369,8 @@ static int add_backend_internal(git_odb *odb, git_odb_backend *backend, int prio
assert(odb && backend);
+ GITERR_CHECK_VERSION(backend, GIT_ODB_BACKEND_VERSION, "git_odb_backend");
+
/* Check if the backend is already owned by another ODB */
assert(!backend->odb || backend->odb == odb);
diff --git a/src/odb_loose.c b/src/odb_loose.c
index e2f1aec32..df86d903e 100644
--- a/src/odb_loose.c
+++ b/src/odb_loose.c
@@ -915,6 +915,7 @@ int git_odb_backend_loose(
backend = git__calloc(1, sizeof(loose_backend));
GITERR_CHECK_ALLOC(backend);
+ backend->parent.version = GIT_ODB_BACKEND_VERSION;
backend->objects_dir = git__strdup(objects_dir);
GITERR_CHECK_ALLOC(backend->objects_dir);
diff --git a/src/odb_pack.c b/src/odb_pack.c
index fc282dd14..b1a46c9ed 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -569,6 +569,7 @@ int git_odb_backend_one_pack(git_odb_backend **backend_out, const char *idx)
backend = git__calloc(1, sizeof(struct pack_backend));
GITERR_CHECK_ALLOC(backend);
+ backend->parent.version = GIT_ODB_BACKEND_VERSION;
if (git_vector_init(&backend->packs, 1, NULL) < 0)
goto on_error;
@@ -601,6 +602,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
backend = git__calloc(1, sizeof(struct pack_backend));
GITERR_CHECK_ALLOC(backend);
+ backend->parent.version = GIT_ODB_BACKEND_VERSION;
if (git_vector_init(&backend->packs, 8, packfile_sort__cb) < 0 ||
git_buf_joinpath(&path, objects_dir, "pack") < 0)
diff --git a/src/remote.c b/src/remote.c
index dc8d9681c..5b75e510c 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -1000,10 +1000,12 @@ 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)
+int git_remote_set_callbacks(git_remote *remote, git_remote_callbacks *callbacks)
{
assert(remote && callbacks);
+ GITERR_CHECK_VERSION(callbacks, GIT_REMOTE_CALLBACKS_VERSION, "git_remote_callbacks");
+
memcpy(&remote->callbacks, callbacks, sizeof(git_remote_callbacks));
if (remote->transport && remote->transport->set_callbacks)
@@ -1011,6 +1013,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(
@@ -1026,6 +1030,8 @@ int git_remote_set_transport(git_remote *remote, git_transport *transport)
{
assert(remote && transport);
+ GITERR_CHECK_VERSION(transport, GIT_TRANSPORT_VERSION, "git_transport");
+
if (remote->transport) {
giterr_set(GITERR_NET, "A transport is already bound to this remote");
return -1;
diff --git a/src/repository.c b/src/repository.c
index b49b49b7a..10ed12b64 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -1151,9 +1151,8 @@ static int repo_init_create_origin(git_repository *repo, const char *url)
int git_repository_init(
git_repository **repo_out, const char *path, unsigned is_bare)
{
- git_repository_init_options opts;
+ git_repository_init_options opts = GIT_REPOSITORY_INIT_OPTIONS_INIT;
- memset(&opts, 0, sizeof(opts));
opts.flags = GIT_REPOSITORY_INIT_MKPATH; /* don't love this default */
if (is_bare)
opts.flags |= GIT_REPOSITORY_INIT_BARE;
@@ -1171,6 +1170,8 @@ int git_repository_init_ext(
assert(out && given_repo && opts);
+ GITERR_CHECK_VERSION(opts, GIT_REPOSITORY_INIT_OPTIONS_VERSION, "git_repository_init_options");
+
error = repo_init_directories(&repo_path, &wd_path, given_repo, opts);
if (error < 0)
goto cleanup;
diff --git a/src/reset.c b/src/reset.c
index d410a8806..17b4b900c 100644
--- a/src/reset.c
+++ b/src/reset.c
@@ -69,7 +69,7 @@ int git_reset(
git_index *index = NULL;
git_tree *tree = NULL;
int error = -1;
- git_checkout_opts opts;
+ git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
assert(repo && target);
assert(reset_type == GIT_RESET_SOFT
@@ -136,7 +136,6 @@ int git_reset(
goto cleanup;
}
- memset(&opts, 0, sizeof(opts));
opts.checkout_strategy = GIT_CHECKOUT_FORCE;
if (git_checkout_index(repo, NULL, &opts) < 0) {
diff --git a/src/signature.c b/src/signature.c
index 0159488a4..7d043e6cf 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -264,7 +264,7 @@ int git_signature__parse(git_signature *sig, const char **buffer_out,
const char *line_end, *name_end, *email_end, *tz_start, *time_start;
int error = 0;
- memset(sig, 0x0, sizeof(git_signature));
+ memset(sig, 0, sizeof(git_signature));
if ((line_end = memchr(buffer, ender, buffer_end - buffer)) == NULL)
return signature_error("no newline given");
diff --git a/src/stash.c b/src/stash.c
index 107cbe3ca..e32d8fa31 100644
--- a/src/stash.c
+++ b/src/stash.c
@@ -14,6 +14,7 @@
#include "git2/stash.h"
#include "git2/status.h"
#include "git2/checkout.h"
+#include "signature.h"
static int create_error(int error, const char *msg)
{
@@ -229,7 +230,7 @@ static int build_untracked_tree(
{
git_tree *i_tree = NULL;
git_diff_list *diff = NULL;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
struct cb_data data = {0};
int error = -1;
@@ -315,7 +316,7 @@ static int build_workdir_tree(
git_repository *repo = git_index_owner(index);
git_tree *b_tree = NULL;
git_diff_list *diff = NULL, *diff2 = NULL;
- git_diff_options opts = {0};
+ git_diff_options opts = GIT_DIFF_OPTIONS_INIT;
struct cb_data data = {0};
int error = -1;
@@ -471,9 +472,8 @@ static int ensure_there_are_changes_to_stash(
bool include_ignored_files)
{
int error;
- git_status_options opts;
+ git_status_options opts = GIT_STATUS_OPTIONS_INIT;
- memset(&opts, 0, sizeof(opts));
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
if (include_untracked_files)
opts.flags = GIT_STATUS_OPT_INCLUDE_UNTRACKED |
@@ -498,9 +498,7 @@ static int reset_index_and_workdir(
git_commit *commit,
bool remove_untracked)
{
- git_checkout_opts opts;
-
- memset(&opts, 0, sizeof(git_checkout_opts));
+ git_checkout_opts opts = GIT_CHECKOUT_OPTS_INIT;
opts.checkout_strategy =
GIT_CHECKOUT_UPDATE_MODIFIED | GIT_CHECKOUT_UPDATE_UNTRACKED;
diff --git a/src/status.c b/src/status.c
index c7dea2c71..1ad835adb 100644
--- a/src/status.c
+++ b/src/status.c
@@ -108,7 +108,7 @@ int git_status_foreach_ext(
void *payload)
{
int err = 0;
- git_diff_options diffopt;
+ git_diff_options diffopt = GIT_DIFF_OPTIONS_INIT;
git_diff_list *idx2head = NULL, *wd2idx = NULL;
git_tree *head = NULL;
git_status_show_t show =
@@ -117,6 +117,8 @@ int git_status_foreach_ext(
assert(show <= GIT_STATUS_SHOW_INDEX_THEN_WORKDIR);
+ GITERR_CHECK_VERSION(opts, GIT_STATUS_OPTIONS_VERSION, "git_status_options");
+
if (show != GIT_STATUS_SHOW_INDEX_ONLY &&
(err = git_repository__ensure_not_bare(repo, "status")) < 0)
return err;
@@ -126,7 +128,6 @@ int git_status_foreach_ext(
!(err == GIT_ENOTFOUND || err == GIT_EORPHANEDHEAD))
return err;
- memset(&diffopt, 0, sizeof(diffopt));
memcpy(&diffopt.pathspec, &opts->pathspec, sizeof(diffopt.pathspec));
diffopt.flags = GIT_DIFF_INCLUDE_TYPECHANGE;
@@ -181,9 +182,8 @@ int git_status_foreach(
git_status_cb callback,
void *payload)
{
- git_status_options opts;
+ git_status_options opts = GIT_STATUS_OPTIONS_INIT;
- memset(&opts, 0, sizeof(opts));
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
GIT_STATUS_OPT_INCLUDE_UNTRACKED |
@@ -224,16 +224,14 @@ int git_status_file(
const char *path)
{
int error;
- git_status_options opts;
- struct status_file_info sfi;
+ git_status_options opts = GIT_STATUS_OPTIONS_INIT;
+ struct status_file_info sfi = {0};
assert(status_flags && repo && path);
- memset(&sfi, 0, sizeof(sfi));
if ((sfi.expected = git__strdup(path)) == NULL)
return -1;
- memset(&opts, 0, sizeof(opts));
opts.show = GIT_STATUS_SHOW_INDEX_AND_WORKDIR;
opts.flags = GIT_STATUS_OPT_INCLUDE_IGNORED |
GIT_STATUS_OPT_INCLUDE_UNTRACKED |
diff --git a/src/submodule.c b/src/submodule.c
index c117255d4..21a1875c2 100644
--- a/src/submodule.c
+++ b/src/submodule.c
@@ -205,7 +205,7 @@ int git_submodule_add_setup(
git_config_backend *mods = NULL;
git_submodule *sm;
git_buf name = GIT_BUF_INIT, real_url = GIT_BUF_INIT;
- git_repository_init_options initopt;
+ git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT;
git_repository *subrepo = NULL;
assert(repo && url && path);
@@ -275,7 +275,6 @@ int git_submodule_add_setup(
* Old style: sub-repo goes directly into repo/<name>/.git/
*/
- memset(&initopt, 0, sizeof(initopt));
initopt.flags = GIT_REPOSITORY_INIT_MKPATH |
GIT_REPOSITORY_INIT_NO_REINIT;
initopt.origin_url = real_url.ptr;
@@ -1439,7 +1438,7 @@ static int submodule_wd_status(unsigned int *status, git_submodule *sm)
if (sm_repo != NULL) {
git_tree *sm_head;
- git_diff_options opt;
+ git_diff_options opt = GIT_DIFF_OPTIONS_INIT;
git_diff_list *diff;
/* the diffs below could be optimized with an early termination
@@ -1452,7 +1451,6 @@ static int submodule_wd_status(unsigned int *status, git_submodule *sm)
if ((error = git_repository_head_tree(&sm_head, sm_repo)) < 0)
return error;
- memset(&opt, 0, sizeof(opt));
if (sm->ignore == GIT_SUBMODULE_IGNORE_NONE)
opt.flags |= GIT_DIFF_INCLUDE_UNTRACKED;
diff --git a/src/transports/local.c b/src/transports/local.c
index 62e8024b5..768daf3a8 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -403,11 +403,10 @@ int git_transport_local(git_transport **out, git_remote *owner, void *param)
GIT_UNUSED(param);
- t = git__malloc(sizeof(transport_local));
+ t = git__calloc(1, sizeof(transport_local));
GITERR_CHECK_ALLOC(t);
- memset(t, 0x0, sizeof(transport_local));
-
+ t->parent.version = GIT_TRANSPORT_VERSION;
t->parent.connect = local_connect;
t->parent.negotiate_fetch = local_negotiate_fetch;
t->parent.download_pack = local_download_pack;
diff --git a/src/transports/smart.c b/src/transports/smart.c
index 94d389b52..5300a47c8 100644
--- a/src/transports/smart.c
+++ b/src/transports/smart.c
@@ -303,6 +303,7 @@ int git_transport_smart(git_transport **out, git_remote *owner, void *param)
t = git__calloc(sizeof(transport_smart), 1);
GITERR_CHECK_ALLOC(t);
+ t->parent.version = GIT_TRANSPORT_VERSION;
t->parent.set_callbacks = git_smart__set_callbacks;
t->parent.connect = git_smart__connect;
t->parent.close = git_smart__close;