From f1de7e32d6e7f5a2573a9786a1b95bcda38266c3 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Sun, 7 Jun 2020 22:33:47 +0200 Subject: [PATCH] fscache: compute correct symlink size in `lstat()` In https://github.com/git-for-windows/git/pull/2637, we fixed a bug where symbolic links' target path sizes were recorded incorrectly in the index. However, we did so only in `mingw_lstat()` but not in `fscache_lstat()`. Meaning: in code paths where the FSCache feature is enabled, Git _still_ got the wrong idea if the symbolic link target's length. Let's fix this. Note: as the FSCache feature reads in whole swaths of directory entries in batch mode, even if metadata for only one of them might be required, we save the expensive `CreateFile()` call that is required to compute the symbolic link target's length to the `fscache_lstat()` call. This fixes https://github.com/git-for-windows/git/issues/2653. Signed-off-by: Johannes Schindelin --- compat/win32/fscache.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/compat/win32/fscache.c b/compat/win32/fscache.c index 5d929a1fc3..6479c476fd 100644 --- a/compat/win32/fscache.c +++ b/compat/win32/fscache.c @@ -597,6 +597,18 @@ int fscache_lstat(const char *filename, struct stat *st) if (!fse) return -1; + /* + * Special case symbolic links: FindFirstFile()/FindNextFile() did not + * provide us with the length of the target path. + */ + if (fse->u.s.st_size == MAX_LONG_PATH && S_ISLNK(fse->st_mode)) { + char buf[MAX_LONG_PATH]; + int len = readlink(filename, buf, sizeof(buf) - 1); + + if (len > 0) + fse->u.s.st_size = len; + } + /* copy stat data */ st->st_ino = 0; st->st_gid = 0;