diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/checkout.c | 6 | ||||
-rw-r--r-- | src/common.h | 27 | ||||
-rw-r--r-- | src/config.c | 2 | ||||
-rw-r--r-- | src/config_file.c | 4 | ||||
-rw-r--r-- | src/diff.c | 6 | ||||
-rw-r--r-- | src/diff.h | 1 | ||||
-rw-r--r-- | src/diff_output.c | 2 | ||||
-rw-r--r-- | src/diff_tform.c | 5 | ||||
-rw-r--r-- | src/notes.c | 1 | ||||
-rw-r--r-- | src/odb.c | 2 | ||||
-rw-r--r-- | src/odb_loose.c | 1 | ||||
-rw-r--r-- | src/odb_pack.c | 2 | ||||
-rw-r--r-- | src/remote.c | 8 | ||||
-rw-r--r-- | src/repository.c | 5 | ||||
-rw-r--r-- | src/reset.c | 3 | ||||
-rw-r--r-- | src/signature.c | 2 | ||||
-rw-r--r-- | src/stash.c | 12 | ||||
-rw-r--r-- | src/status.c | 14 | ||||
-rw-r--r-- | src/submodule.c | 6 | ||||
-rw-r--r-- | src/transports/local.c | 5 | ||||
-rw-r--r-- | src/transports/smart.c | 1 |
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, @@ -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; |