Files
git/t/t7416-submodule-dash-url.sh
Patrick Steinhardt 23e21a58d5 t: introduce PERL_TEST_HELPERS prerequisite
In the early days of Git, Perl was used quite prominently throughout the
project. This has changed significantly as almost all of the executables
we ship nowadays have eventually been rewritten in C. Only a handful of
subsystems remain that require Perl:

  - gitweb, a read-only web interface.

  - A couple of scripts that allow importing repositories from GNU Arch,
    CVS and Subversion.

  - git-send-email(1), which can be used to send mails.

  - git-request-pull(1), which is used to request somebody to pull from
    a URL by sending an email.

  - git-filter-branch(1), which uses Perl with the `--state-branch`
    option. This command is typically recommended against nowadays in
    favor of git-filter-repo(1).

  - Our Perl bindings for Git.

  - The netrc Git credential helper.

None of these subsystems can really be considered to be part of the
"core" of Git, and an installation without them is fully functional.
It is more likely than not that an end user wouldn't even notice that
any features are missing if those tools weren't installed. But while
Perl nowadays very much is an optional dependency of Git, there is a
significant limitation when Perl isn't available: developers cannot run
our test suite.

Preceding commits have started to lift this restriction by removing the
strict dependency on Perl in many central parts of the test library. But
there are still many tests that rely on small Perl helpers to do various
different things.

Introduce a new PERL_TEST_HELPERS prerequisite that guards all tests
that require Perl. This prerequisite is explicitly different than the
preexisting PERL prerequisite:

  - PERL records whether or not features depending on the Perl
    interpreter are built.

  - PERL_TEST_HELPERS records whether or not a Perl interpreter is
    available for our tests.

By having these two separate prerequisites we can thus distinguish
between tests that inherently depend on Perl because the underlying
feature does, and those tests that depend on Perl because the test
itself is using Perl.

Adapt all tests to set the PERL_TEST_HELPERS prerequisite as needed.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2025-04-07 14:47:37 -07:00

231 lines
6.6 KiB
Bash
Executable File

#!/bin/sh
test_description='check handling of disallowed .gitmodule urls'
. ./test-lib.sh
if ! test_have_prereq PERL_TEST_HELPERS
then
skip_all='skipping submodule dash URL tests; Perl not available'
test_done
fi
test_expect_success 'setup' '
git config --global protocol.file.allow always
'
test_expect_success 'create submodule with protected dash in url' '
git init upstream &&
git -C upstream commit --allow-empty -m base &&
mv upstream ./-upstream &&
git submodule add ./-upstream sub &&
git add sub .gitmodules &&
git commit -m submodule
'
test_expect_success 'clone can recurse submodule' '
test_when_finished "rm -rf dst" &&
git clone --recurse-submodules . dst &&
echo base >expect &&
git -C dst/sub log -1 --format=%s >actual &&
test_cmp expect actual
'
test_expect_success 'fsck accepts protected dash' '
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
git push dst HEAD
'
test_expect_success 'remove ./ protection from .gitmodules url' '
perl -i -pe "s{\./}{}" .gitmodules &&
git commit -am "drop protection"
'
test_expect_success 'clone rejects unprotected dash' '
test_when_finished "rm -rf dst" &&
test_must_fail git clone --recurse-submodules . dst 2>err &&
test_grep ignoring err
'
test_expect_success 'fsck rejects unprotected dash' '
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'trailing backslash is handled correctly' '
git init testmodule &&
test_commit -C testmodule c &&
git submodule add ./testmodule &&
: ensure that the name ends in a double backslash &&
sed -e "s|\\(submodule \"testmodule\\)\"|\\1\\\\\\\\\"|" \
-e "s|url = .*|url = \" --should-not-be-an-option\"|" \
<.gitmodules >.new &&
mv .new .gitmodules &&
git commit -am "Add testmodule" &&
test_must_fail git clone --verbose --recurse-submodules . dolly 2>err &&
test_grep ! "unknown option" err
'
test_expect_success 'fsck rejects missing URL scheme' '
git checkout --orphan missing-scheme &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = http::one.example.com/foo.git
EOF
git add .gitmodules &&
test_tick &&
git commit -m "gitmodules with missing URL scheme" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects relative URL resolving to missing scheme' '
git checkout --orphan relative-missing-scheme &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = "..\\../.\\../:one.example.com/foo.git"
EOF
git add .gitmodules &&
test_tick &&
git commit -m "gitmodules with relative URL that strips off scheme" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects empty URL scheme' '
git checkout --orphan empty-scheme &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = http::://one.example.com/foo.git
EOF
git add .gitmodules &&
test_tick &&
git commit -m "gitmodules with empty URL scheme" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects relative URL resolving to empty scheme' '
git checkout --orphan relative-empty-scheme &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = ../../../:://one.example.com/foo.git
EOF
git add .gitmodules &&
test_tick &&
git commit -m "relative gitmodules URL resolving to empty scheme" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects empty hostname' '
git checkout --orphan empty-host &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = http:///one.example.com/foo.git
EOF
git add .gitmodules &&
test_tick &&
git commit -m "gitmodules with extra slashes" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects relative url that produced empty hostname' '
git checkout --orphan messy-relative &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = ../../..//one.example.com/foo.git
EOF
git add .gitmodules &&
test_tick &&
git commit -m "gitmodules abusing relative_path" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck permits embedded newline with unrecognized scheme' '
git checkout --orphan newscheme &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = "data://acjbkd%0akajfdickajkd"
EOF
git add .gitmodules &&
git commit -m "gitmodules with unrecognized scheme" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
git push dst HEAD
'
test_expect_success 'fsck rejects embedded newline in url' '
# create an orphan branch to avoid existing .gitmodules objects
git checkout --orphan newline &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = "https://one.example.com?%0ahost=two.example.com/foo.git"
EOF
git add .gitmodules &&
git commit -m "gitmodules with newline" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects embedded newline in relative url' '
git checkout --orphan relative-newline &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = "./%0ahost=two.example.com/foo.git"
EOF
git add .gitmodules &&
git commit -m "relative url with newline" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_expect_success 'fsck rejects embedded newline in git url' '
git checkout --orphan git-newline &&
cat >.gitmodules <<-\EOF &&
[submodule "foo"]
url = "git://example.com:1234/repo%0a.git"
EOF
git add .gitmodules &&
git commit -m "git url with newline" &&
test_when_finished "rm -rf dst" &&
git init --bare dst &&
git -C dst config transfer.fsckObjects true &&
test_must_fail git push dst HEAD 2>err &&
grep gitmodulesUrl err
'
test_done