handle edge case of symlink to something that is not really a pointer file
That seems very unlikely to happen, but still, it's possible it could. And with the recent addition of locked files to the keys db, this could be called by places that did not call it before, so it seems even more important it's correct. Adds an extra stat of the file, and is potentially racy, but both problems are fixed by the unix-2.8.0 path. I have not tested that path builds because that package is not yet released and it would be difficult to install it since it's tightly tied to a ghc version.
This commit is contained in:
parent
673b2feaf3
commit
26a9ea12d1
1 changed files with 30 additions and 4 deletions
|
@ -7,7 +7,7 @@
|
|||
-
|
||||
- Pointer files are used instead of symlinks for unlocked files.
|
||||
-
|
||||
- Copyright 2013-2019 Joey Hess <id@joeyh.name>
|
||||
- Copyright 2013-2021 Joey Hess <id@joeyh.name>
|
||||
-
|
||||
- Licensed under the GNU AGPL version 3 or higher.
|
||||
-}
|
||||
|
@ -294,10 +294,36 @@ unpaddedMaxPointerSz = 8192
|
|||
|
||||
{- Checks if a worktree file is a pointer to a key.
|
||||
-
|
||||
- Unlocked files whose content is present are not detected by this. -}
|
||||
- Unlocked files whose content is present are not detected by this.
|
||||
-
|
||||
- It's possible, though unlikely, that an annex symlink points to
|
||||
- an object that looks like a pointer file. Or that a non-annex
|
||||
- symlink does. Avoids a false positive in those cases.
|
||||
- -}
|
||||
isPointerFile :: RawFilePath -> IO (Maybe Key)
|
||||
isPointerFile f = catchDefaultIO Nothing $ withFile (fromRawFilePath f) ReadMode $ \h ->
|
||||
parseLinkTargetOrPointer <$> S.hGet h unpaddedMaxPointerSz
|
||||
isPointerFile f = catchDefaultIO Nothing $ do
|
||||
#if defined(mingw32_HOST_OS)
|
||||
checkcontentfollowssymlinks -- no symlinks supported on windows
|
||||
#else
|
||||
#if MIN_VERSION_unix(2,8,0)
|
||||
bracket
|
||||
(openFd (fromRawFilePath f) ReadOnly (defaultFileFlags { nofollow = True }) Nothing)
|
||||
closeFd
|
||||
(\fd -> readhandle =<< fdToHandle fd)
|
||||
#else
|
||||
pointercontent <- checkcontentfollowssymlinks
|
||||
if isJust pointercontent
|
||||
then ifM (isSymbolicLink <$> R.getSymbolicLinkStatus f)
|
||||
( return Nothing
|
||||
, return pointercontent
|
||||
)
|
||||
else return Nothing
|
||||
#endif
|
||||
#endif
|
||||
where
|
||||
checkcontentfollowssymlinks =
|
||||
withFile (fromRawFilePath f) ReadMode readhandle
|
||||
readhandle h = parseLinkTargetOrPointer <$> S.hGet h unpaddedMaxPointerSz
|
||||
|
||||
{- Checks a symlink target or pointer file first line to see if it
|
||||
- appears to point to annexed content.
|
||||
|
|
Loading…
Reference in a new issue