Merge branch 'jc/safe-directory-leading-path' into maint-2.45

The safe.directory configuration knob has been updated to
optionally allow leading path matches.

* jc/safe-directory-leading-path:
  safe.directory: allow "lead/ing/path/*" match
maint
Junio C Hamano 2024-06-28 15:53:16 -07:00
commit ce75d32b99
3 changed files with 31 additions and 7 deletions

View File

@ -44,7 +44,8 @@ string `*`. This will allow all repositories to be treated as if their
directory was listed in the `safe.directory` list. If `safe.directory=*` directory was listed in the `safe.directory` list. If `safe.directory=*`
is set in system config and you want to re-enable this protection, then is set in system config and you want to re-enable this protection, then
initialize your list with an empty value before listing the repositories initialize your list with an empty value before listing the repositories
that you deem safe. that you deem safe. Giving a directory with `/*` appended to it will
allow access to all repositories under the named directory.
+ +
As explained, Git only allows you to access repositories owned by As explained, Git only allows you to access repositories owned by
yourself, i.e. the user who is running Git, by default. When Git yourself, i.e. the user who is running Git, by default. When Git

20
setup.c
View File

@ -1177,13 +1177,21 @@ static int safe_directory_cb(const char *key, const char *value,
} else if (!strcmp(value, "*")) { } else if (!strcmp(value, "*")) {
data->is_safe = 1; data->is_safe = 1;
} else { } else {
const char *interpolated = NULL; const char *allowed = NULL;


if (!git_config_pathname(&interpolated, key, value) && if (!git_config_pathname(&allowed, key, value)) {
!fspathcmp(data->path, interpolated ? interpolated : value)) if (!allowed)
data->is_safe = 1; allowed = value;

if (ends_with(allowed, "/*")) {
free((char *)interpolated); size_t len = strlen(allowed);
if (!fspathncmp(allowed, data->path, len - 1))
data->is_safe = 1;
} else if (!fspathcmp(data->path, allowed)) {
data->is_safe = 1;
}
}
if (allowed != value)
free((char *)allowed);
} }


return 0; return 0;

View File

@ -71,7 +71,22 @@ test_expect_success 'safe.directory=*, but is reset' '
expect_rejected_dir expect_rejected_dir
' '


test_expect_success 'safe.directory with matching glob' '
git config --global --unset-all safe.directory &&
p=$(pwd) &&
git config --global safe.directory "${p%/*}/*" &&
git status
'

test_expect_success 'safe.directory with unmatching glob' '
git config --global --unset-all safe.directory &&
p=$(pwd) &&
git config --global safe.directory "${p%/*}no/*" &&
expect_rejected_dir
'

test_expect_success 'safe.directory in included file' ' test_expect_success 'safe.directory in included file' '
git config --global --unset-all safe.directory &&
cat >gitconfig-include <<-EOF && cat >gitconfig-include <<-EOF &&
[safe] [safe]
directory = "$(pwd)" directory = "$(pwd)"