Git fork

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

+31 -7
+2 -1
Documentation/config/safe.txt
··· 44 44 directory was listed in the `safe.directory` list. If `safe.directory=*` 45 45 is set in system config and you want to re-enable this protection, then 46 46 initialize your list with an empty value before listing the repositories 47 - that you deem safe. 47 + that you deem safe. Giving a directory with `/*` appended to it will 48 + allow access to all repositories under the named directory. 48 49 + 49 50 As explained, Git only allows you to access repositories owned by 50 51 yourself, i.e. the user who is running Git, by default. When Git
+14 -6
setup.c
··· 1177 1177 } else if (!strcmp(value, "*")) { 1178 1178 data->is_safe = 1; 1179 1179 } else { 1180 - const char *interpolated = NULL; 1181 - 1182 - if (!git_config_pathname(&interpolated, key, value) && 1183 - !fspathcmp(data->path, interpolated ? interpolated : value)) 1184 - data->is_safe = 1; 1180 + const char *allowed = NULL; 1185 1181 1186 - free((char *)interpolated); 1182 + if (!git_config_pathname(&allowed, key, value)) { 1183 + if (!allowed) 1184 + allowed = value; 1185 + if (ends_with(allowed, "/*")) { 1186 + size_t len = strlen(allowed); 1187 + if (!fspathncmp(allowed, data->path, len - 1)) 1188 + data->is_safe = 1; 1189 + } else if (!fspathcmp(data->path, allowed)) { 1190 + data->is_safe = 1; 1191 + } 1192 + } 1193 + if (allowed != value) 1194 + free((char *)allowed); 1187 1195 } 1188 1196 1189 1197 return 0;
+15
t/t0033-safe-directory.sh
··· 71 71 expect_rejected_dir 72 72 ' 73 73 74 + test_expect_success 'safe.directory with matching glob' ' 75 + git config --global --unset-all safe.directory && 76 + p=$(pwd) && 77 + git config --global safe.directory "${p%/*}/*" && 78 + git status 79 + ' 80 + 81 + test_expect_success 'safe.directory with unmatching glob' ' 82 + git config --global --unset-all safe.directory && 83 + p=$(pwd) && 84 + git config --global safe.directory "${p%/*}no/*" && 85 + expect_rejected_dir 86 + ' 87 + 74 88 test_expect_success 'safe.directory in included file' ' 89 + git config --global --unset-all safe.directory && 75 90 cat >gitconfig-include <<-EOF && 76 91 [safe] 77 92 directory = "$(pwd)"