avoid false positives when detecting core.symlinks=false symlink standin files

If the file is > 8192 bytes, it's certianly not a symlink file.

And if it contains nuls or newlines or whitespace, it's certianly
not a link to annexed content. But it might be a tarball containing
a git-annex repo.
This commit is contained in:
Joey Hess 2013-07-20 19:28:02 -04:00
parent ae341c1a37
commit ecdfa40cbe

View file

@ -29,8 +29,7 @@ isAnnexLink file = maybe Nothing (fileKey . takeFileName) <$> getAnnexLinkTarget
{- Gets the link target of a symlink. {- Gets the link target of a symlink.
- -
- On a filesystem that does not support symlinks, fall back to getting the - On a filesystem that does not support symlinks, fall back to getting the
- link target by looking inside the file. (Only return first 8k of the - link target by looking inside the file.
- file, more than enough for any symlink target.)
- -
- Returns Nothing if the file is not a symlink, or not a link to annex - Returns Nothing if the file is not a symlink, or not a link to annex
- content. - content.
@ -38,7 +37,7 @@ isAnnexLink file = maybe Nothing (fileKey . takeFileName) <$> getAnnexLinkTarget
getAnnexLinkTarget :: FilePath -> Annex (Maybe LinkTarget) getAnnexLinkTarget :: FilePath -> Annex (Maybe LinkTarget)
getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig) getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig)
( check readSymbolicLink $ ( check readSymbolicLink $
check readfilestart $ check probefilecontent $
return Nothing return Nothing
, check readSymbolicLink $ , check readSymbolicLink $
return Nothing return Nothing
@ -52,11 +51,26 @@ getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig)
| otherwise -> return Nothing | otherwise -> return Nothing
Nothing -> fallback Nothing -> fallback
readfilestart f = do probefilecontent f = do
h <- openFile f ReadMode h <- openFile f ReadMode
fileEncoding h fileEncoding h
-- The first 8k is more than enough to read; link
-- files are small.
s <- take 8192 <$> hGetContents h s <- take 8192 <$> hGetContents h
length s `seq` (hClose h >> return s) -- If we got the full 8k, the file is too large
if length s == 8192
then do
hClose h
return ""
else do
hClose h
-- If there are any NUL or newline
-- characters, or whitespace, we
-- certianly don't have a link to a
-- git-annex key.
if any (`elem` s) "\0\n\r \t"
then return ""
else return s
{- Creates a link on disk. {- Creates a link on disk.
- -