diff options
Diffstat (limited to 't')
| -rwxr-xr-x | t/t0003-attributes.sh | 59 | ||||
| -rwxr-xr-x | t/t0066-dir-iterator.sh | 27 | ||||
| -rwxr-xr-x | t/t1091-sparse-checkout-builtin.sh | 11 | ||||
| -rwxr-xr-x | t/t1450-fsck.sh | 24 | ||||
| -rwxr-xr-x | t/t3104-ls-tree-format.sh | 6 | ||||
| -rwxr-xr-x | t/t3204-branch-name-interpretation.sh | 10 | ||||
| -rwxr-xr-x | t/t3920-crlf-messages.sh | 2 | ||||
| -rwxr-xr-x | t/t4023-diff-rename-typechange.sh | 12 | ||||
| -rwxr-xr-x | t/t4045-diff-relative.sh | 29 | ||||
| -rwxr-xr-x | t/t4115-apply-symlink.sh | 81 | ||||
| -rwxr-xr-x | t/t4205-log-pretty-formats.sh | 78 | ||||
| -rwxr-xr-x | t/t4211-line-log.sh | 22 | ||||
| -rwxr-xr-x | t/t5314-pack-cycle-detection.sh | 17 | ||||
| -rwxr-xr-x | t/t5604-clone-reference.sh | 16 | ||||
| -rwxr-xr-x | t/t5619-clone-local-ambiguous-transport.sh | 70 | ||||
| -rwxr-xr-x | t/t6020-bundle-misc.sh | 7 | ||||
| -rwxr-xr-x | t/t7600-merge.sh | 2 |
17 files changed, 455 insertions, 18 deletions
diff --git a/t/t0003-attributes.sh b/t/t0003-attributes.sh index f7ee2f2ff0..d0284fe2d7 100755 --- a/t/t0003-attributes.sh +++ b/t/t0003-attributes.sh @@ -376,4 +376,63 @@ test_expect_success SYMLINKS 'symlinks not respected in-tree' ' test_i18ngrep "unable to access.*gitattributes" err ' +test_expect_success 'large attributes line ignored in tree' ' + test_when_finished "rm .gitattributes" && + printf "path %02043d" 1 >.gitattributes && + git check-attr --all path >actual 2>err && + echo "warning: ignoring overly long attributes line 1" >expect && + test_cmp expect err && + test_must_be_empty actual +' + +test_expect_success 'large attributes line ignores trailing content in tree' ' + test_when_finished "rm .gitattributes" && + # older versions of Git broke lines at 2048 bytes; the 2045 bytes + # of 0-padding here is accounting for the three bytes of "a 1", which + # would knock "trailing" to the "next" line, where it would be + # erroneously parsed. + printf "a %02045dtrailing attribute\n" 1 >.gitattributes && + git check-attr --all trailing >actual 2>err && + echo "warning: ignoring overly long attributes line 1" >expect && + test_cmp expect err && + test_must_be_empty actual +' + +test_expect_success EXPENSIVE 'large attributes file ignored in tree' ' + test_when_finished "rm .gitattributes" && + dd if=/dev/zero of=.gitattributes bs=101M count=1 2>/dev/null && + git check-attr --all path >/dev/null 2>err && + echo "warning: ignoring overly large gitattributes file ${SQ}.gitattributes${SQ}" >expect && + test_cmp expect err +' + +test_expect_success 'large attributes line ignored in index' ' + test_when_finished "git update-index --remove .gitattributes" && + blob=$(printf "path %02043d" 1 | git hash-object -w --stdin) && + git update-index --add --cacheinfo 100644,$blob,.gitattributes && + git check-attr --cached --all path >actual 2>err && + echo "warning: ignoring overly long attributes line 1" >expect && + test_cmp expect err && + test_must_be_empty actual +' + +test_expect_success 'large attributes line ignores trailing content in index' ' + test_when_finished "git update-index --remove .gitattributes" && + blob=$(printf "a %02045dtrailing attribute\n" 1 | git hash-object -w --stdin) && + git update-index --add --cacheinfo 100644,$blob,.gitattributes && + git check-attr --cached --all trailing >actual 2>err && + echo "warning: ignoring overly long attributes line 1" >expect && + test_cmp expect err && + test_must_be_empty actual +' + +test_expect_success EXPENSIVE 'large attributes file ignored in index' ' + test_when_finished "git update-index --remove .gitattributes" && + blob=$(dd if=/dev/zero bs=101M count=1 2>/dev/null | git hash-object -w --stdin) && + git update-index --add --cacheinfo 100644,$blob,.gitattributes && + git check-attr --cached --all path >/dev/null 2>err && + echo "warning: ignoring overly large gitattributes blob ${SQ}.gitattributes${SQ}" >expect && + test_cmp expect err +' + test_done diff --git a/t/t0066-dir-iterator.sh b/t/t0066-dir-iterator.sh index 63a1a45cd3..04b811622b 100755 --- a/t/t0066-dir-iterator.sh +++ b/t/t0066-dir-iterator.sh @@ -110,7 +110,9 @@ test_expect_success SYMLINKS 'setup dirs with symlinks' ' mkdir -p dir5/a/c && ln -s ../c dir5/a/b/d && ln -s ../ dir5/a/b/e && - ln -s ../../ dir5/a/b/f + ln -s ../../ dir5/a/b/f && + + ln -s dir4 dir6 ' test_expect_success SYMLINKS 'dir-iterator should not follow symlinks by default' ' @@ -146,4 +148,27 @@ test_expect_success SYMLINKS 'dir-iterator should follow symlinks w/ follow flag test_cmp expected-follow-sorted-output actual-follow-sorted-output ' +test_expect_success SYMLINKS 'dir-iterator does not resolve top-level symlinks' ' + test_must_fail test-tool dir-iterator ./dir6 >out && + + grep "ENOTDIR" out +' + +test_expect_success SYMLINKS 'dir-iterator resolves top-level symlinks w/ follow flag' ' + cat >expected-follow-sorted-output <<-EOF && + [d] (a) [a] ./dir6/a + [d] (a/f) [f] ./dir6/a/f + [d] (a/f/c) [c] ./dir6/a/f/c + [d] (b) [b] ./dir6/b + [d] (b/c) [c] ./dir6/b/c + [f] (a/d) [d] ./dir6/a/d + [f] (a/e) [e] ./dir6/a/e + EOF + + test-tool dir-iterator --follow-symlinks ./dir6 >out && + sort out >actual-follow-sorted-output && + + test_cmp expected-follow-sorted-output actual-follow-sorted-output +' + test_done diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index b563d6c263..627267be15 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -238,7 +238,7 @@ test_expect_success 'cone mode: match patterns' ' test_expect_success 'cone mode: warn on bad pattern' ' test_when_finished mv sparse-checkout repo/.git/info/ && cp repo/.git/info/sparse-checkout . && - echo "!/deep/deeper/*" >>repo/.git/info/sparse-checkout && + echo "!/deep/deeper/*/" >>repo/.git/info/sparse-checkout && git -C repo read-tree -mu HEAD 2>err && test_i18ngrep "unrecognized negative pattern" err ' @@ -667,6 +667,15 @@ test_expect_success 'pattern-checks: starting "*"' ' check_read_tree_errors repo "a deep" "disabling cone pattern matching" ' +test_expect_success 'pattern-checks: non directory pattern' ' + cat >repo/.git/info/sparse-checkout <<-\EOF && + /deep/deeper1/a + EOF + check_read_tree_errors repo deep "disabling cone pattern matching" && + check_files repo/deep deeper1 && + check_files repo/deep/deeper1 a +' + test_expect_success 'pattern-checks: contained glob characters' ' for c in "[a]" "\\" "?" "*" do diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index ace4556788..de0f6d5e7f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -999,4 +999,28 @@ test_expect_success 'fsck error and recovery on invalid object type' ' ) ' +test_expect_success 'fsck error on gitattributes with excessive line lengths' ' + blob=$(printf "pattern %02048d" 1 | git hash-object -w --stdin) && + test_when_finished "remove_object $blob" && + tree=$(printf "100644 blob %s\t%s\n" $blob .gitattributes | git mktree) && + test_when_finished "remove_object $tree" && + cat >expected <<-EOF && + error in blob $blob: gitattributesLineLength: .gitattributes has too long lines to parse + EOF + test_must_fail git fsck --no-dangling >actual 2>&1 && + test_cmp expected actual +' + +test_expect_success 'fsck error on gitattributes with excessive size' ' + blob=$(test-tool genzeros $((100 * 1024 * 1024 + 1)) | git hash-object -w --stdin) && + test_when_finished "remove_object $blob" && + tree=$(printf "100644 blob %s\t%s\n" $blob .gitattributes | git mktree) && + test_when_finished "remove_object $tree" && + cat >expected <<-EOF && + error in blob $blob: gitattributesLarge: .gitattributes too large to parse + EOF + test_must_fail git fsck --no-dangling >actual 2>&1 && + test_cmp expected actual +' + test_done diff --git a/t/t3104-ls-tree-format.sh b/t/t3104-ls-tree-format.sh index 383896667b..805b30f403 100755 --- a/t/t3104-ls-tree-format.sh +++ b/t/t3104-ls-tree-format.sh @@ -36,6 +36,12 @@ test_ls_tree_format () { ' } +test_expect_success "ls-tree --format='%(path) %(path) %(path)' HEAD top-file" ' + git ls-tree --format="%(path) %(path) %(path)" HEAD top-file.t >actual && + echo top-file.t top-file.t top-file.t >expect && + test_cmp expect actual +' + test_ls_tree_format \ "%(objectmode) %(objecttype) %(objectname)%x09%(path)" \ "" diff --git a/t/t3204-branch-name-interpretation.sh b/t/t3204-branch-name-interpretation.sh index 793bf4d269..3399344f25 100755 --- a/t/t3204-branch-name-interpretation.sh +++ b/t/t3204-branch-name-interpretation.sh @@ -57,6 +57,16 @@ test_expect_success 'create branch with pseudo-qualified name' ' expect_branch refs/heads/refs/heads/qualified two ' +test_expect_success 'force-copy a branch to itself via @{-1} is no-op' ' + git branch -t copiable main && + git checkout copiable && + git checkout - && + git branch -C @{-1} copiable && + git config --get-all branch.copiable.merge >actual && + echo refs/heads/main >expect && + test_cmp expect actual +' + test_expect_success 'delete branch via @{-1}' ' git branch previous-del && diff --git a/t/t3920-crlf-messages.sh b/t/t3920-crlf-messages.sh index 4c661d4d54..67fd2345af 100755 --- a/t/t3920-crlf-messages.sh +++ b/t/t3920-crlf-messages.sh @@ -12,7 +12,7 @@ create_crlf_ref () { cat >.crlf-orig-$branch.txt && cat .crlf-orig-$branch.txt | append_cr >.crlf-message-$branch.txt && grep 'Subject' .crlf-orig-$branch.txt | tr '\n' ' ' | sed 's/[ ]*$//' | tr -d '\n' >.crlf-subject-$branch.txt && - grep 'Body' .crlf-message-$branch.txt >.crlf-body-$branch.txt || true && + grep 'Body' .crlf-orig-$branch.txt | append_cr >.crlf-body-$branch.txt && LIB_CRLF_BRANCHES="${LIB_CRLF_BRANCHES} ${branch}" && test_tick && hash=$(git commit-tree HEAD^{tree} -p HEAD -F .crlf-message-${branch}.txt) && diff --git a/t/t4023-diff-rename-typechange.sh b/t/t4023-diff-rename-typechange.sh index 7cb9909293..787605ce3f 100755 --- a/t/t4023-diff-rename-typechange.sh +++ b/t/t4023-diff-rename-typechange.sh @@ -52,8 +52,8 @@ test_expect_success setup ' ' test_expect_success 'cross renames to be detected for regular files' ' - - git diff-tree five six -r --name-status -B -M | sort >actual && + git diff-tree five six -r --name-status -B -M >out && + sort out >actual && { echo "R100 foo bar" && echo "R100 bar foo" @@ -63,8 +63,8 @@ test_expect_success 'cross renames to be detected for regular files' ' ' test_expect_success 'cross renames to be detected for typechange' ' - - git diff-tree one two -r --name-status -B -M | sort >actual && + git diff-tree one two -r --name-status -B -M >out && + sort out >actual && { echo "R100 foo bar" && echo "R100 bar foo" @@ -74,8 +74,8 @@ test_expect_success 'cross renames to be detected for typechange' ' ' test_expect_success 'moves and renames' ' - - git diff-tree three four -r --name-status -B -M | sort >actual && + git diff-tree three four -r --name-status -B -M >out && + sort out >actual && { # see -B -M (#6) in t4008 echo "C100 foo bar" && diff --git a/t/t4045-diff-relative.sh b/t/t4045-diff-relative.sh index fab351b48a..5e1bbb57e7 100755 --- a/t/t4045-diff-relative.sh +++ b/t/t4045-diff-relative.sh @@ -162,6 +162,35 @@ check_diff_relative_option subdir file2 true --no-relative --relative check_diff_relative_option . file2 false --no-relative --relative=subdir check_diff_relative_option . file2 true --no-relative --relative=subdir +test_expect_success 'external diff with --relative' ' + test_when_finished "git reset --hard" && + echo changed >file1 && + echo changed >subdir/file2 && + + write_script mydiff <<-\EOF && + # hacky pretend diff; the goal here is just to make sure we got + # passed sensible input that we _could_ diff, without relying on + # the specific output of a system diff tool. + echo "diff a/$1 b/$1" && + echo "--- a/$1" && + echo "+++ b/$1" && + echo "@@ -1 +0,0 @@" && + sed "s/^/-/" "$2" && + sed "s/^/+/" "$5" + EOF + + cat >expect <<-\EOF && + diff a/file2 b/file2 + --- a/file2 + +++ b/file2 + @@ -1 +0,0 @@ + -other content + +changed + EOF + GIT_EXTERNAL_DIFF=./mydiff git diff --relative=subdir >actual && + test_cmp expect actual +' + test_expect_success 'setup diff --relative unmerged' ' test_commit zero file0 && test_commit base subdir/file0 && diff --git a/t/t4115-apply-symlink.sh b/t/t4115-apply-symlink.sh index d0f3edef54..65ac7df2d7 100755 --- a/t/t4115-apply-symlink.sh +++ b/t/t4115-apply-symlink.sh @@ -45,4 +45,85 @@ test_expect_success 'apply --index symlink patch' ' ' +test_expect_success 'symlink setup' ' + ln -s .git symlink && + git add symlink && + git commit -m "add symlink" +' + +test_expect_success SYMLINKS 'symlink escape when creating new files' ' + test_when_finished "git reset --hard && git clean -dfx" && + + cat >patch <<-EOF && + diff --git a/symlink b/renamed-symlink + similarity index 100% + rename from symlink + rename to renamed-symlink + -- + diff --git /dev/null b/renamed-symlink/create-me + new file mode 100644 + index 0000000..039727e + --- /dev/null + +++ b/renamed-symlink/create-me + @@ -0,0 +1,1 @@ + +busted + EOF + + test_must_fail git apply patch 2>stderr && + cat >expected_stderr <<-EOF && + error: affected file ${SQ}renamed-symlink/create-me${SQ} is beyond a symbolic link + EOF + test_cmp expected_stderr stderr && + ! test_path_exists .git/create-me +' + +test_expect_success SYMLINKS 'symlink escape when modifying file' ' + test_when_finished "git reset --hard && git clean -dfx" && + touch .git/modify-me && + + cat >patch <<-EOF && + diff --git a/symlink b/renamed-symlink + similarity index 100% + rename from symlink + rename to renamed-symlink + -- + diff --git a/renamed-symlink/modify-me b/renamed-symlink/modify-me + index 1111111..2222222 100644 + --- a/renamed-symlink/modify-me + +++ b/renamed-symlink/modify-me + @@ -0,0 +1,1 @@ + +busted + EOF + + test_must_fail git apply patch 2>stderr && + cat >expected_stderr <<-EOF && + error: renamed-symlink/modify-me: No such file or directory + EOF + test_cmp expected_stderr stderr && + test_must_be_empty .git/modify-me +' + +test_expect_success SYMLINKS 'symlink escape when deleting file' ' + test_when_finished "git reset --hard && git clean -dfx && rm .git/delete-me" && + touch .git/delete-me && + + cat >patch <<-EOF && + diff --git a/symlink b/renamed-symlink + similarity index 100% + rename from symlink + rename to renamed-symlink + -- + diff --git a/renamed-symlink/delete-me b/renamed-symlink/delete-me + deleted file mode 100644 + index 1111111..0000000 100644 + EOF + + test_must_fail git apply patch 2>stderr && + cat >expected_stderr <<-EOF && + error: renamed-symlink/delete-me: No such file or directory + EOF + test_cmp expected_stderr stderr && + test_path_is_file .git/delete-me +' + test_done diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index e448ef2928..3e7ad9d5de 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -156,7 +156,7 @@ test_expect_success 'NUL termination with --reflog --pretty=oneline' ' for r in $revs do git show -s --pretty=oneline "$r" >raw && - cat raw | lf_to_nul || exit 1 + cat raw | lf_to_nul || return 1 done >expect && # the trailing NUL is already produced so we do not need to # output another one @@ -1018,4 +1018,80 @@ test_expect_success '%(describe:abbrev=...) vs git describe --abbrev=...' ' test_cmp expect actual ' +test_expect_success 'log --pretty with space stealing' ' + printf mm0 >expect && + git log -1 --pretty="format:mm%>>|(1)%x30" >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty with invalid padding format' ' + printf "%s%%<(20" "$(git rev-parse HEAD)" >expect && + git log -1 --pretty="format:%H%<(20" >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty with magical wrapping directives' ' + commit_id=$(git commit-tree HEAD^{tree} -m "describe me") && + git tag describe-me $commit_id && + printf "\n(tag:\ndescribe-me)%%+w(2)" >expect && + git log -1 --pretty="format:%w(1)%+d%+w(2)" $commit_id >actual && + test_cmp expect actual +' + +test_expect_success SIZE_T_IS_64BIT 'log --pretty with overflowing wrapping directive' ' + printf "%%w(2147483649,1,1)0" >expect && + git log -1 --pretty="format:%w(2147483649,1,1)%x30" >actual && + test_cmp expect actual && + printf "%%w(1,2147483649,1)0" >expect && + git log -1 --pretty="format:%w(1,2147483649,1)%x30" >actual && + test_cmp expect actual && + printf "%%w(1,1,2147483649)0" >expect && + git log -1 --pretty="format:%w(1,1,2147483649)%x30" >actual && + test_cmp expect actual +' + +test_expect_success SIZE_T_IS_64BIT 'log --pretty with overflowing padding directive' ' + printf "%%<(2147483649)0" >expect && + git log -1 --pretty="format:%<(2147483649)%x30" >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty with padding and preceding control chars' ' + printf "\20\20 0" >expect && + git log -1 --pretty="format:%x10%x10%>|(4)%x30" >actual && + test_cmp expect actual +' + +test_expect_success 'log --pretty truncation with control chars' ' + test_commit "$(printf "\20\20\20\20xxxx")" file contents commit-with-control-chars && + printf "\20\20\20\20x.." >expect && + git log -1 --pretty="format:%<(3,trunc)%s" commit-with-control-chars >actual && + test_cmp expect actual +' + +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' ' + # We only assert that this command does not crash. This needs to be + # executed with the address sanitizer to demonstrate failure. + git log -1 --pretty="format:%>(2147483646)%x41%41%>(2147483646)%x41" >/dev/null +' + +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'set up huge commit' ' + test-tool genzeros 2147483649 | tr "\000" "1" >expect && + huge_commit=$(git commit-tree -F expect HEAD^{tree}) +' + +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message' ' + git log -1 --format="%B%<(1)%x30" $huge_commit >actual && + echo 0 >>expect && + test_cmp expect actual +' + +test_expect_success EXPENSIVE,SIZE_T_IS_64BIT 'log --pretty with huge commit message does not cause allocation failure' ' + test_must_fail git log -1 --format="%<(1)%B" $huge_commit 2>error && + cat >expect <<-EOF && + fatal: number too large to represent as int on this platform: 2147483649 + EOF + test_cmp expect error +' + test_done diff --git a/t/t4211-line-log.sh b/t/t4211-line-log.sh index ac9e4d0928..c6540e822f 100755 --- a/t/t4211-line-log.sh +++ b/t/t4211-line-log.sh @@ -315,4 +315,26 @@ test_expect_success 'line-log with --before' ' test_cmp expect actual ' +test_expect_success 'setup tests for zero-width regular expressions' ' + cat >expect <<-EOF + Modify func1() in file.c + Add func1() and func2() in file.c + EOF +' + +test_expect_success 'zero-width regex $ matches any function name' ' + git log --format="%s" --no-patch "-L:$:file.c" >actual && + test_cmp expect actual +' + +test_expect_success 'zero-width regex ^ matches any function name' ' + git log --format="%s" --no-patch "-L:^:file.c" >actual && + test_cmp expect actual +' + +test_expect_success 'zero-width regex .* matches any function name' ' + git log --format="%s" --no-patch "-L:.*:file.c" >actual && + test_cmp expect actual +' + test_done diff --git a/t/t5314-pack-cycle-detection.sh b/t/t5314-pack-cycle-detection.sh index 73a241743a..82734b9a3c 100755 --- a/t/t5314-pack-cycle-detection.sh +++ b/t/t5314-pack-cycle-detection.sh @@ -63,13 +63,16 @@ TEST_PASSES_SANITIZE_LEAK=true # Note that the two variants of "file" must be similar enough to convince git # to create the delta. make_pack () { - { - printf '%s\n' "-$(git rev-parse $2)" - printf '%s dummy\n' "$(git rev-parse $1:dummy)" - printf '%s file\n' "$(git rev-parse $1:file)" - } | - git pack-objects --stdout | - git index-pack --stdin --fix-thin + ln1=$(git rev-parse "$2") && + ln2=$(git rev-parse "$1:dummy") && + ln3=$(git rev-parse "$1:file") && + cat >list <<-EOF + -$ln1 + $ln2 dummy + $ln3 file + EOF + git pack-objects --stdout <list >pack && + git index-pack --stdin --fix-thin <pack } test_expect_success 'setup' ' diff --git a/t/t5604-clone-reference.sh b/t/t5604-clone-reference.sh index 2734e37e88..7ccebb40c3 100755 --- a/t/t5604-clone-reference.sh +++ b/t/t5604-clone-reference.sh @@ -344,4 +344,20 @@ test_expect_success SYMLINKS 'clone repo with symlinked or unknown files at obje test_must_be_empty T--shared.objects-symlinks.raw ' +test_expect_success SYMLINKS 'clone repo with symlinked objects directory' ' + test_when_finished "rm -fr sensitive malicious" && + + mkdir -p sensitive && + echo "secret" >sensitive/file && + + git init malicious && + rm -fr malicious/.git/objects && + ln -s "$(pwd)/sensitive" ./malicious/.git/objects && + + test_must_fail git clone --local malicious clone 2>err && + + test_path_is_missing clone && + grep "failed to start iterator over" err +' + test_done diff --git a/t/t5619-clone-local-ambiguous-transport.sh b/t/t5619-clone-local-ambiguous-transport.sh new file mode 100755 index 0000000000..cce62bf78d --- /dev/null +++ b/t/t5619-clone-local-ambiguous-transport.sh @@ -0,0 +1,70 @@ +#!/bin/sh + +test_description='test local clone with ambiguous transport' + +. ./test-lib.sh +. "$TEST_DIRECTORY/lib-httpd.sh" + +if ! test_have_prereq SYMLINKS +then + skip_all='skipping test, symlink support unavailable' + test_done +fi + +start_httpd + +REPO="$HTTPD_DOCUMENT_ROOT_PATH/sub.git" +URI="$HTTPD_URL/dumb/sub.git" + +test_expect_success 'setup' ' + mkdir -p sensitive && + echo "secret" >sensitive/secret && + + git init --bare "$REPO" && + test_commit_bulk -C "$REPO" --ref=main 1 && + + git -C "$REPO" update-ref HEAD main && + git -C "$REPO" update-server-info && + + git init malicious && + ( + cd malicious && + + git submodule add "$URI" && + + mkdir -p repo/refs && + touch repo/refs/.gitkeep && + printf "ref: refs/heads/a" >repo/HEAD && + ln -s "$(cd .. && pwd)/sensitive" repo/objects && + + mkdir -p "$HTTPD_URL/dumb" && + ln -s "../../../.git/modules/sub/../../../repo/" "$URI" && + + git add . && + git commit -m "initial commit" + ) && + + # Delete all of the references in our malicious submodule to + # avoid the client attempting to checkout any objects (which + # will be missing, and thus will cause the clone to fail before + # we can trigger the exploit). + git -C "$REPO" for-each-ref --format="delete %(refname)" >in && + git -C "$REPO" update-ref --stdin <in && + git -C "$REPO" update-server-info +' + +test_expect_success 'ambiguous transport does not lead to arbitrary file-inclusion' ' + git clone malicious clone && + test_must_fail git -C clone submodule update --init 2>err && + + test_path_is_missing clone/.git/modules/sub/objects/secret && + # We would actually expect "transport .file. not allowed" here, + # but due to quirks of the URL detection in Git, we mis-parse + # the absolute path as a bogus URL and die before that step. + # + # This works for now, and if we ever fix the URL detection, it + # is OK to change this to detect the transport error. + grep "protocol .* is not supported" err +' + +test_done diff --git a/t/t6020-bundle-misc.sh b/t/t6020-bundle-misc.sh index 833205125a..3a1cf30b1d 100755 --- a/t/t6020-bundle-misc.sh +++ b/t/t6020-bundle-misc.sh @@ -11,6 +11,13 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh . "$TEST_DIRECTORY"/lib-bundle.sh +for cmd in create verify list-heads unbundle +do + test_expect_success "usage: git bundle $cmd needs an argument" ' + test_expect_code 129 git bundle $cmd + ' +done + # Create a commit or tag and set the variable with the object ID. test_commit_setvar () { notick= diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 7c3f6ed994..060e145957 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -105,7 +105,7 @@ verify_mergeheads () { test_write_lines "$@" >mergehead.expected && while read sha1 rest do - git rev-parse $sha1 + git rev-parse $sha1 || return 1 done <.git/MERGE_HEAD >mergehead.actual && test_cmp mergehead.expected mergehead.actual } |
