]> git.ipfire.org Git - thirdparty/git.git/commitdiff
submodule--helper: check repo{_submodule,}_init() return values
authorÆvar Arnfjörð Bjarmason <avarab@gmail.com>
Wed, 31 Aug 2022 23:18:12 +0000 (01:18 +0200)
committerJunio C Hamano <gitster@pobox.com>
Fri, 2 Sep 2022 16:16:24 +0000 (09:16 -0700)
Fix code added in ce125d431aa (submodule: extract path to submodule
gitdir func, 2021-09-15) and a77c3fcb5ec (submodule--helper: get
remote names from any repository, 2022-03-04) which failed to check
the return values of repo_init() and repo_submodule_init(). If we
failed to initialize the repository or submodule we could segfault
when trying to access the invalid repository structs.

Let's also check that these were the only such logic errors in the
codebase by making use of the "warn_unused_result" attribute. This is
valid as of GCC 3.4.0 (and clang will catch it via its faking of
__GNUC__ ).

As the comment being added to git-compat-util.h we're piggy-backing on
the LAST_ARG_MUST_BE_NULL version check out of lazyness. See
9fe3edc47f1 (Add the LAST_ARG_MUST_BE_NULL macro, 2013-07-18) for its
addition. The marginal benefit of covering gcc 3.4.0..4.0.0 is
near-zero (or zero) at this point. It mostly matters that we catch
this somewhere.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Reviewed-by: Glen Choo <chooglen@google.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/submodule--helper.c
git-compat-util.h
repository.h

index bfcc8e2c9951db9c4058a0de5f1c1f1b7e899d98..7f0a39286fb4ac8e765cc95eeef29d768d841b06 100644 (file)
@@ -63,7 +63,10 @@ static char *get_default_remote_submodule(const char *module_path)
 {
        struct repository subrepo;
 
-       repo_submodule_init(&subrepo, the_repository, module_path, null_oid());
+       if (repo_submodule_init(&subrepo, the_repository, module_path,
+                               null_oid()) < 0)
+               die(_("could not get a repository handle for submodule '%s'"),
+                   module_path);
        return repo_get_default_remote(&subrepo);
 }
 
@@ -1480,7 +1483,9 @@ static int add_possible_reference_from_superproject(
                struct strbuf err = STRBUF_INIT;
                strbuf_add(&sb, odb->path, len);
 
-               repo_init(&alternate, sb.buf, NULL);
+               if (repo_init(&alternate, sb.buf, NULL) < 0)
+                       die(_("could not get a repository handle for gitdir '%s'"),
+                           sb.buf);
 
                /*
                 * We need to end the new path with '/' to mark it as a dir,
index 58d7708296b614dbb6fd0bd9feb403d2a8c473ce..3eb7785bddb1324d561134fde33433cb5575967b 100644 (file)
@@ -565,8 +565,11 @@ static inline int git_has_dir_sep(const char *path)
 /* The sentinel attribute is valid from gcc version 4.0 */
 #if defined(__GNUC__) && (__GNUC__ >= 4)
 #define LAST_ARG_MUST_BE_NULL __attribute__((sentinel))
+/* warn_unused_result exists as of gcc 3.4.0, but be lazy and check 4.0 */
+#define RESULT_MUST_BE_USED __attribute__ ((warn_unused_result))
 #else
 #define LAST_ARG_MUST_BE_NULL
+#define RESULT_MUST_BE_USED
 #endif
 
 #define MAYBE_UNUSED __attribute__((__unused__))
index 6cc661e5a43b82022ca171a43c015db2f278116e..17c45ae096248478abb6e4ffe0d3479fccc6bbf4 100644 (file)
@@ -1,6 +1,7 @@
 #ifndef REPOSITORY_H
 #define REPOSITORY_H
 
+#include "git-compat-util.h"
 #include "path.h"
 
 struct config_set;
@@ -185,6 +186,7 @@ void repo_set_gitdir(struct repository *repo, const char *root,
 void repo_set_worktree(struct repository *repo, const char *path);
 void repo_set_hash_algo(struct repository *repo, int algo);
 void initialize_the_repository(void);
+RESULT_MUST_BE_USED
 int repo_init(struct repository *r, const char *gitdir, const char *worktree);
 
 /*
@@ -196,6 +198,7 @@ int repo_init(struct repository *r, const char *gitdir, const char *worktree);
  * Return 0 upon success and a non-zero value upon failure.
  */
 struct object_id;
+RESULT_MUST_BE_USED
 int repo_submodule_init(struct repository *subrepo,
                        struct repository *superproject,
                        const char *path,