Skip to content

Commit 7e4ada0

Browse files
committed
receive-pack: fix crash on out-of-namespace symref
`check_aliased_update_internal()` detects when a symbolic ref and its target are being updated in the same push. It does this by building a list of ref names without the optional namespace prefix. When a symbolic ref within a namespace points to a ref outside the namespace, `strip_namespace()` returns NULL which leads to a segfault. A NULL check preventing this particular issue was repurposed in ded8393. Rather than reintroducing it, we can instead build a list of fully qualified ref names. This prevents the crash, preserves the consistency check from da3efdb, and allows updates to all symbolic refs. Signed-off-by: Troels Thomsen <troels@thomsen.io>
1 parent 66ce5f8 commit 7e4ada0

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

builtin/receive-pack.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,7 +1685,6 @@ static void check_aliased_update_internal(struct command *cmd,
16851685
cmd->error_string = "broken symref";
16861686
return;
16871687
}
1688-
dst_name = strip_namespace(dst_name);
16891688

16901689
if (!(item = string_list_lookup(list, dst_name)))
16911690
return;
@@ -1730,10 +1729,13 @@ static void check_aliased_updates(struct command *commands)
17301729
{
17311730
struct command *cmd;
17321731
struct string_list ref_list = STRING_LIST_INIT_NODUP;
1732+
struct strbuf ref_name = STRBUF_INIT;
17331733

17341734
for (cmd = commands; cmd; cmd = cmd->next) {
1735-
struct string_list_item *item =
1736-
string_list_append(&ref_list, cmd->ref_name);
1735+
struct string_list_item *item;
1736+
strbuf_reset(&ref_name);
1737+
strbuf_addf(&ref_name, "%s%s", get_git_namespace(), cmd->ref_name);
1738+
item = string_list_append(&ref_list, ref_name.buf);
17371739
item->util = (void *)cmd;
17381740
}
17391741
string_list_sort(&ref_list);
@@ -1743,6 +1745,7 @@ static void check_aliased_updates(struct command *commands)
17431745
check_aliased_update(cmd, &ref_list);
17441746
}
17451747

1748+
strbuf_release(&ref_name);
17461749
string_list_clear(&ref_list, 0);
17471750
}
17481751

t/t5509-fetch-push-namespaces.sh

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,4 +175,17 @@ test_expect_success 'denyCurrentBranch and unborn branch with ref namespace' '
175175
)
176176
'
177177

178+
test_expect_success 'pushing to symref pointing outside the namespace' '
179+
(
180+
cd pushee &&
181+
git symbolic-ref refs/namespaces/namespace/refs/heads/main refs/heads/main &&
182+
cd ../original &&
183+
git push pushee-namespaced main &&
184+
git ls-remote pushee-unnamespaced refs/heads/main >actual &&
185+
printf "$commit1\trefs/heads/main\n" >expected &&
186+
printf "$commit1\trefs/namespaces/namespace/refs/heads/main\n" >>expected &&
187+
test_cmp expected actual
188+
)
189+
'
190+
178191
test_done

0 commit comments

Comments
 (0)