Commit Diff


commit - 532314d10e3c028a2b6d79e0a23714baef90cfba
commit + 0ef3ddaa20b027c211debfaffe4c5b9e454f23b3
blob - 2f1b2189449fcc425f84391d4ebdc1e96ae22e0a
blob + 4a59325762dbfcb7188bdd14018f9086b94717de
--- gotd/repo_write.c
+++ gotd/repo_write.c
@@ -1503,6 +1503,51 @@ protect_refs_from_deletion(void)
 }
 
 static const struct got_error *
+protect_refs_from_moving(void)
+{
+	const struct got_error *err = NULL;
+	struct repo_write_client *client = &repo_write_client;
+	struct gotd_ref_update *ref_update;
+	struct got_pathlist_entry *pe;
+	const char *refname;
+
+	STAILQ_FOREACH(ref_update, &client->ref_updates, entry) {
+		if (ref_update->delete_ref)
+			continue;
+
+		if (got_object_id_cmp(&ref_update->old_id,
+		    &ref_update->new_id) == 0)
+			continue;
+
+		refname = got_ref_get_name(ref_update->ref);
+
+		RB_FOREACH(pe, got_pathlist_head,
+		    repo_write.protected_tag_namespaces) {
+			err = protect_ref_namespace(refname, pe->path);
+			if (err)
+				return err;
+		}
+
+		RB_FOREACH(pe, got_pathlist_head,
+		    repo_write.protected_branch_namespaces) {
+			err = protect_ref_namespace(refname, pe->path);
+			if (err)
+				return err;
+		}
+
+		RB_FOREACH(pe, got_pathlist_head, repo_write.protected_branches)
+		{
+			if (strcmp(refname, pe->path) == 0) {
+				return got_error_fmt(GOT_ERR_REF_PROTECTED,
+				    "%s", refname);
+			}
+		}
+	}
+
+	return NULL;
+}
+
+static const struct got_error *
 install_packfile(struct gotd_imsgev *iev)
 {
 	struct repo_write_client *client = &repo_write_client;
@@ -2249,6 +2294,14 @@ repo_write_dispatch_session(int fd, short event, void 
 				 */
 				repo_write.repo->pack_path_mtime.tv_sec = 0;
 				repo_write.repo->pack_path_mtime.tv_nsec = 0;
+			} else {
+				/*
+				 * Clients sending empty pack files might be
+				 * attempting to move a protected reference.
+				 */
+				err = protect_refs_from_moving();
+				if (err)
+					break;
 			}
 			err = update_refs(iev);
 			if (err) {
blob - ea1abadcdca2ecec752031ec65bd64a5796ddc1e
blob + d1e70129d2724139bccbc574d043f24c9ec5c7cd
--- regress/gotd/repo_write_protected.sh
+++ regress/gotd/repo_write_protected.sh
@@ -199,7 +199,7 @@ test_modify_protected_branch() {
 
 	got checkout $testroot/repo-clone $testroot/wt >/dev/null
 
-	for i in 1 2 3; do
+	for i in 1 2; do
 		echo "more alpha" >> $testroot/wt/alpha
 		(cd $testroot/wt && got commit -m "more" >/dev/null)
 	done