Sync with 2.42.2

* maint-2.42: (39 commits)
  Git 2.42.2
  Git 2.41.1
  Git 2.40.2
  Git 2.39.4
  fsck: warn about symlink pointing inside a gitdir
  core.hooksPath: add some protection while cloning
  init.templateDir: consider this config setting protected
  clone: prevent hooks from running during a clone
  Add a helper function to compare file contents
  init: refactor the template directory discovery into its own function
  find_hook(): refactor the `STRIP_EXTENSION` logic
  clone: when symbolic links collide with directories, keep the latter
  entry: report more colliding paths
  t5510: verify that D/F confusion cannot lead to an RCE
  submodule: require the submodule path to contain directories only
  clone_submodule: avoid using `access()` on directories
  submodules: submodule paths must not contain symlinks
  clone: prevent clashing git dirs when cloning submodule in parallel
  t7423: add tests for symlinked submodule directories
  has_dir_name(): do not get confused by characters < '/'
  ...
This commit is contained in:
Johannes Schindelin
2024-04-10 22:04:48 +02:00
46 changed files with 1294 additions and 107 deletions

56
fsck.c
View File

@ -657,6 +657,8 @@ static int fsck_tree(const struct object_id *tree_oid,
retval += report(options, tree_oid, OBJ_TREE,
FSCK_MSG_MAILMAP_SYMLINK,
".mailmap is a symlink");
oidset_insert(&options->symlink_targets_found,
entry_oid);
}
if ((backslash = strchr(name, '\\'))) {
@ -1297,6 +1299,56 @@ static int fsck_blob(const struct object_id *oid, const char *buf,
}
}
if (oidset_contains(&options->symlink_targets_found, oid)) {
const char *ptr = buf;
const struct object_id *reported = NULL;
oidset_insert(&options->symlink_targets_done, oid);
if (!buf || size > PATH_MAX) {
/*
* A missing buffer here is a sign that the caller found the
* blob too gigantic to load into memory. Let's just consider
* that an error.
*/
return report(options, oid, OBJ_BLOB,
FSCK_MSG_SYMLINK_TARGET_LENGTH,
"symlink target too long");
}
while (!reported && ptr) {
const char *p = ptr;
char c, *slash = strchrnul(ptr, '/');
char *backslash = memchr(ptr, '\\', slash - ptr);
c = *slash;
*slash = '\0';
while (!reported && backslash) {
*backslash = '\0';
if (is_ntfs_dotgit(p))
ret |= report(options, reported = oid, OBJ_BLOB,
FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR,
"symlink target points to git dir");
*backslash = '\\';
p = backslash + 1;
backslash = memchr(p, '\\', slash - p);
}
if (!reported && is_ntfs_dotgit(p))
ret |= report(options, reported = oid, OBJ_BLOB,
FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR,
"symlink target points to git dir");
if (!reported && is_hfs_dotgit(ptr))
ret |= report(options, reported = oid, OBJ_BLOB,
FSCK_MSG_SYMLINK_POINTS_TO_GIT_DIR,
"symlink target points to git dir");
*slash = c;
ptr = c ? slash + 1 : NULL;
}
}
return ret;
}
@ -1395,6 +1447,10 @@ int fsck_finish(struct fsck_options *options)
FSCK_MSG_GITATTRIBUTES_MISSING, FSCK_MSG_GITATTRIBUTES_BLOB,
options, ".gitattributes");
ret |= fsck_blobs(&options->symlink_targets_found, &options->symlink_targets_done,
FSCK_MSG_SYMLINK_TARGET_MISSING, FSCK_MSG_SYMLINK_TARGET_BLOB,
options, "<symlink-target>");
return ret;
}