commit 64592dff718689c4fb441b52d2b38e8db90089ba from: Stefan Sperling via: Thomas Adam date: Thu Jun 08 19:48:48 2023 UTC fix a segfault in got diff when a root commit is passed to -c Problem reported by Alexander Arkhipov ok jamsek commit - c3ede3f63413760725d0f43389f476da4cc66d24 commit + 64592dff718689c4fb441b52d2b38e8db90089ba blob - 1724c65c05bba46e05b9ad4ee3bbfce7ad7b72fd blob + 96736bcee618adc7c0693f929dd038909bdeda1d --- lib/diff.c +++ lib/diff.c @@ -1098,15 +1098,18 @@ diff_paths(struct got_tree_object *tree1, struct got_t got_object_blob_close(blob2); blob2 = NULL; } - - err = got_object_tree_find_path(&id1, &mode1, repo, tree1, - pe->path); - if (err && err->code != GOT_ERR_NO_TREE_ENTRY) - goto done; - err = got_object_tree_find_path(&id2, &mode2, repo, tree2, - pe->path); - if (err && err->code != GOT_ERR_NO_TREE_ENTRY) - goto done; + if (tree1) { + err = got_object_tree_find_path(&id1, &mode1, repo, + tree1, pe->path); + if (err && err->code != GOT_ERR_NO_TREE_ENTRY) + goto done; + } + if (tree2) { + err = got_object_tree_find_path(&id2, &mode2, repo, + tree2, pe->path); + if (err && err->code != GOT_ERR_NO_TREE_ENTRY) + goto done; + } if (id1 == NULL && id2 == NULL) { err = got_error_path(pe->path, GOT_ERR_NO_TREE_ENTRY); goto done; blob - 82aab78d37c08ef751e9e73c8de8f1c9f772a4c3 blob + 03e05611a400a2ffc9c91e307d0d5c048fdc6cf3 --- regress/cmdline/diff.sh +++ regress/cmdline/diff.sh @@ -1961,7 +1961,67 @@ EOF fi test_done "$testroot" "$ret" } + +test_diff_path_in_root_commit() { + local testroot=`test_init diff_path_in_root_commit` + local commit_id=`git_show_head $testroot/repo` + local alpha_blobid=`get_blob_id $testroot/repo "" alpha` + + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + (cd $testroot/wt && got diff -c $commit_id alpha > $testroot/stdout) + + cat <$testroot/stdout.expected +diff /dev/null $commit_id +commit - /dev/null +commit + $commit_id +blob - /dev/null +blob + $alpha_blobid (mode 644) +--- /dev/null ++++ alpha +@@ -0,0 +1 @@ ++alpha +EOF + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + # diff non-existent path + (cd $testroot/wt && got diff -c $commit_id nonexistent \ + > $testroot/stdout 2> $testroot/stderr) + + echo -n > $testroot/stdout.expected + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + + echo "got: nonexistent: no such entry found in tree" \ + > $testroot/stderr.expected + cmp -s $testroot/stderr.expected $testroot/stderr + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stderr.expected $testroot/stderr + test_done "$testroot" "$ret" + return 1 + fi + + test_done "$testroot" "$ret" +} + test_parseargs "$@" run_test test_diff_basic run_test test_diff_shows_conflict @@ -1980,3 +2040,4 @@ run_test test_diff_commit_diffstat run_test test_diff_worktree_diffstat run_test test_diff_file_to_dir run_test test_diff_dir_to_file +run_test test_diff_path_in_root_commit