[PATCH] upload-pack.c: treat want-ref relative to namespace

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



When 'upload-pack' runs within the context of a git namespace, treat any
'want-ref' lines the client sends as relative to that namespace.

Also check if the wanted ref is hidden via 'hideRefs', and respond with
an error otherwise. It was previously possible to request any ref, but
note that this is still the case unless 'hideRefs' is in effect.

Signed-off-by: Kim Altintop <kim@xxxxxxxxx>
---

Please excuse my newbie ness.

 t/t5703-upload-pack-ref-in-want.sh | 77 ++++++++++++++++++++++++++++++
 upload-pack.c                      | 15 +++---
 2 files changed, 86 insertions(+), 6 deletions(-)

diff --git a/t/t5703-upload-pack-ref-in-want.sh b/t/t5703-upload-pack-ref-in-want.sh
index e9e471621d..9fb16848bc 100755
--- a/t/t5703-upload-pack-ref-in-want.sh
+++ b/t/t5703-upload-pack-ref-in-want.sh
@@ -298,6 +298,83 @@ test_expect_success 'fetching with wildcard that matches multiple refs' '
 	grep "want-ref refs/heads/o/bar" log
 '

+REPO="$(pwd)/repo-ns"
+
+test_expect_success 'setup namespaced repo' '
+	(
+		git init -b main "$REPO" &&
+		cd "$REPO" &&
+		test_commit a &&
+		test_commit b &&
+		git checkout a &&
+		test_commit c &&
+		git checkout a &&
+		test_commit d &&
+		git update-ref refs/heads/ns-no b &&
+		git update-ref refs/namespaces/ns/refs/heads/ns-yes c &&
+		git update-ref refs/namespaces/ns/refs/heads/hidden d
+	) &&
+    git -C "$REPO" config uploadpack.allowRefInWant true &&
+    git -C "$REPO" config transfer.hideRefs refs/heads/hidden
+'
+
+test_expect_success 'want-ref with namespaces' '
+	oid=$(git -C "$REPO" rev-parse c) &&
+	cat >expected_refs <<-EOF &&
+	$oid refs/heads/ns-yes
+	EOF
+	>expected_commits &&
+
+	oid=$(git -C "$REPO" rev-parse c) &&
+	test-tool pkt-line pack >in <<-EOF &&
+	$(write_command fetch)
+	0001
+	no-progress
+	want-ref refs/heads/ns-yes
+	have $oid
+	done
+	0000
+	EOF
+
+	GIT_NAMESPACE=ns && export GIT_NAMESPACE &&
+	test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+	check_output
+'
+
+test_expect_success 'want-ref outside namespace' '
+	oid=$(git -C "$REPO" rev-parse c) &&
+	test-tool pkt-line pack >in <<-EOF &&
+	$(write_command fetch)
+	0001
+	no-progress
+	want-ref refs/heads/ns-no
+	have $oid
+	done
+	0000
+	EOF
+
+	GIT_NAMESPACE=ns && export GIT_NAMESPACE &&
+	test_must_fail test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+	grep "unknown ref" out
+'
+
+test_expect_success 'hideRefs with namespaces' '
+	oid=$(git -C "$REPO" rev-parse c) &&
+	test-tool pkt-line pack >in <<-EOF &&
+	$(write_command fetch)
+	0001
+	no-progress
+	want-ref refs/heads/hidden
+	have $oid
+	done
+	0000
+	EOF
+
+	GIT_NAMESPACE=ns && export GIT_NAMESPACE &&
+	test_must_fail test-tool -C "$REPO" serve-v2 --stateless-rpc >out <in &&
+	grep "unknown ref" out
+'
+
 . "$TEST_DIRECTORY"/lib-httpd.sh
 start_httpd

diff --git a/upload-pack.c b/upload-pack.c
index 297b76fcb4..008ac75125 100644
--- a/upload-pack.c
+++ b/upload-pack.c
@@ -1417,21 +1417,24 @@ static int parse_want_ref(struct packet_writer *writer, const char *line,
 			  struct string_list *wanted_refs,
 			  struct object_array *want_obj)
 {
-	const char *arg;
+	const char *refname_nons;
 	if (skip_prefix(line, "want-ref ", &arg)) {
 		struct object_id oid;
 		struct string_list_item *item;
 		struct object *o;
+		struct strbuf refname = STRBUF_INIT;

-		if (read_ref(arg, &oid)) {
-			packet_writer_error(writer, "unknown ref %s", arg);
-			die("unknown ref %s", arg);
+		strbuf_addf(&refname, "%s%s", get_git_namespace(), refname_nons);
+		if (ref_is_hidden(refname_nons, refname.buf) ||
+		    read_ref(refname.buf, &oid)) {
+			packet_writer_error(writer, "unknown ref %s", refname_nons);
+			die("unknown ref %s", refname.buf);
 		}

-		item = string_list_append(wanted_refs, arg);
+		item = string_list_append(wanted_refs, refname_nons);
 		item->util = oiddup(&oid);

-		o = parse_object_or_die(&oid, arg);
+		o = parse_object_or_die(&oid, refname);
 		if (!(o->flags & WANTED)) {
 			o->flags |= WANTED;
 			add_object_array(o, NULL, want_obj);
--
2.32.0






[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux