summaryrefslogtreecommitdiff
path: root/builtin
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-11-15 23:02:57 -0800
committerJunio C Hamano <gitster@pobox.com>2025-11-25 08:43:20 -0800
commitdd8e8c786efdfb3ba588d807bfb0dc0d5196c343 (patch)
tree9a748dd74255dcbc30ec68992dbd5de1cde014d3 /builtin
parentbb5c624209fcaebd60b9572b2cc8c61086e39b57 (diff)
submodule add: sanity check existing .gitmodules
"git submodule add" tries to find if a submodule with the same name already exists at a different path, by looking up an entry in the .gitmodules file. If the entry in the file is incomplete, e.g., when the submodule.<name>.something variable is defined but there is no definition of submodule.<name>.path variable, it accesses the missing .path member of the submodule structure and triggers a segfault. A brief audit was done to make sure that the code does not assume members other than those that are absolutely certain to exist: a submodule obtained by submodule_from_name() should have .name member, while a submodule obtained by submodule_from_path() should also have .path as well as .name member, and we cannot assume anything else. Luckily, the module_add() codepath was the only problematic one. It is fairly recent code that comes from 1fa06ced (submodule: prevent overwriting .gitmodules on path reuse, 2025-07-24). A helper used by update_submodule() seems to assume that its call to submodule_from_path() always yields a submodule object without a failure, which seems to rely on the caller making sure it is the case. Leave an assert() with a NEEDSWORK comment there for future developers to make sure the assumption actually holds. Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'builtin')
-rw-r--r--builtin/submodule--helper.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c
index 07a1935cbe..1a1043cdab 100644
--- a/builtin/submodule--helper.c
+++ b/builtin/submodule--helper.c
@@ -1913,6 +1913,13 @@ static int determine_submodule_update_strategy(struct repository *r,
const char *val;
int ret;
+ /*
+ * NEEDSWORK: audit and ensure that update_submodule() has right
+ * to assume that submodule_from_path() above will always succeed.
+ */
+ if (!sub)
+ BUG("update_submodule assumes a submodule exists at path (%s)",
+ path);
key = xstrfmt("submodule.%s.update", sub->name);
if (update) {
@@ -3537,14 +3544,15 @@ static int module_add(int argc, const char **argv, const char *prefix,
}
}
- if(!add_data.sm_name)
+ if (!add_data.sm_name)
add_data.sm_name = add_data.sm_path;
existing = submodule_from_name(the_repository,
null_oid(the_hash_algo),
add_data.sm_name);
- if (existing && strcmp(existing->path, add_data.sm_path)) {
+ if (existing && existing->path &&
+ strcmp(existing->path, add_data.sm_path)) {
if (!force) {
die(_("submodule name '%s' already used for path '%s'"),
add_data.sm_name, existing->path);