commit 1b796c3fa88f0d3101f3dd979d9f8b511fd93086 from: Stefan Sperling date: Sat Sep 11 08:06:47 2021 UTC fix a null-pointer deref in 'got fetch -d'; reported by Omar Polo commit - 678d8c1fe20f1eab5a3568135b24f00c9d22c33c commit + 1b796c3fa88f0d3101f3dd979d9f8b511fd93086 blob - 5f3984d14029304bc35fa0a2ae1caeff8de74a69 blob + b1b444cf1fc04c7930365cd15df8871bd7a5ee3d --- got/got.c +++ got/got.c @@ -2020,8 +2020,11 @@ delete_missing_refs(struct got_pathlist_head *their_re TAILQ_FOREACH(re, &my_refs, entry) { const char *refname = got_ref_get_name(re->ref); + const char *their_refname; - if (!remote->mirror_references) { + if (remote->mirror_references) { + their_refname = refname; + } else { if (strncmp(refname, remote_namespace, strlen(remote_namespace)) == 0) { if (strcmp(refname + strlen(remote_namespace), @@ -2034,17 +2037,19 @@ delete_missing_refs(struct got_pathlist_head *their_re } } else if (strncmp(refname, "refs/tags/", 10) != 0) continue; - } + their_refname = local_refname; + } + TAILQ_FOREACH(pe, their_refs, entry) { - if (strcmp(local_refname, pe->path) == 0) + if (strcmp(their_refname, pe->path) == 0) break; } if (pe != NULL) continue; TAILQ_FOREACH(pe, their_symrefs, entry) { - if (strcmp(local_refname, pe->path) == 0) + if (strcmp(their_refname, pe->path) == 0) break; } if (pe != NULL) blob - e0587383f411d35c4be341e74b562fba63fbfbf8 blob + 5b536e8cfc092fb0ac4d203d6360716d2f94ff5b --- regress/cmdline/fetch.sh +++ regress/cmdline/fetch.sh @@ -508,7 +508,103 @@ test_fetch_delete_branch() { test_done "$testroot" "$ret" } + +test_fetch_delete_branch_mirror() { + local testroot=`test_init fetch_delete_branch_mirror` + local testurl=ssh://127.0.0.1/$testroot + local commit_id=`git_show_head $testroot/repo` + + got branch -r $testroot/repo -c $commit_id foo + got ref -r $testroot/repo -c $commit_id refs/hoo/boo/zoo + got tag -r $testroot/repo -c $commit_id -m tag "1.0" >/dev/null + local tag_id=`got ref -r $testroot/repo -l \ + | grep "^refs/tags/$tag" | tr -d ' ' | cut -d: -f2` + + got clone -a -m -q $testurl/repo $testroot/repo-clone + ret="$?" + if [ "$ret" != "0" ]; then + echo "got clone command failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + got ref -l -r $testroot/repo-clone > $testroot/stdout + + echo "HEAD: refs/heads/master" > $testroot/stdout.expected + echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected + echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected + # refs/hoo/boo/zoo is missing because it is outside of refs/heads + echo "refs/tags/1.0: $tag_id" >> $testroot/stdout.expected + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + got branch -r $testroot/repo -d foo >/dev/null + + got fetch -q -r $testroot/repo-clone + ret="$?" + if [ "$ret" != "0" ]; then + echo "got fetch command failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + got ref -l -r $testroot/repo-clone > $testroot/stdout + + echo "HEAD: refs/heads/master" > $testroot/stdout.expected + echo "refs/heads/foo: $commit_id" >> $testroot/stdout.expected + echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected + # refs/hoo/boo/zoo is missing because it is outside of refs/heads + echo "refs/tags/1.0: $tag_id" >> $testroot/stdout.expected + + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + got fetch -d -q -r $testroot/repo-clone > $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + echo "got fetch command failed unexpectedly" >&2 + test_done "$testroot" "$ret" + return 1 + fi + + echo -n > $testroot/stdout.expected + + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + got ref -l -r $testroot/repo-clone > $testroot/stdout + + echo "HEAD: refs/heads/master" > $testroot/stdout.expected + # refs/heads/foo is now deleted + echo "refs/heads/master: $commit_id" >> $testroot/stdout.expected + # refs/hoo/boo/zoo is missing because it is outside of refs/heads + echo "refs/tags/1.0: $tag_id" >> $testroot/stdout.expected + + cmp -s $testroot/stdout $testroot/stdout.expected + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + fi + test_done "$testroot" "$ret" + +} + test_fetch_update_tag() { local testroot=`test_init fetch_update_tag` local testurl=ssh://127.0.0.1/$testroot @@ -1191,6 +1287,7 @@ run_test test_fetch_branch run_test test_fetch_all run_test test_fetch_empty_packfile run_test test_fetch_delete_branch +run_test test_fetch_delete_branch_mirror run_test test_fetch_update_tag run_test test_fetch_reference run_test test_fetch_replace_symref