diff options
author | Joey Hess <joey@kitenet.net> | 2013-07-20 19:28:02 -0400 |
---|---|---|
committer | Joey Hess <joey@kitenet.net> | 2013-07-20 19:28:02 -0400 |
commit | 375ce8f3de7bd31bea57b46c49de40bc1be6cfbe (patch) | |
tree | 26b0a8c54ed076710bf2e0fe4b79378589e1c581 /Annex | |
parent | 08034d294434c2ed0c90e7c11d2139694d7cdd70 (diff) |
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.
Diffstat (limited to 'Annex')
-rw-r--r-- | Annex/Link.hs | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/Annex/Link.hs b/Annex/Link.hs index eeae16f15..bb2354c49 100644 --- a/Annex/Link.hs +++ b/Annex/Link.hs @@ -29,8 +29,7 @@ isAnnexLink file = maybe Nothing (fileKey . takeFileName) <$> getAnnexLinkTarget {- Gets the link target of a symlink. - - 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 - - file, more than enough for any symlink target.) + - link target by looking inside the file. - - Returns Nothing if the file is not a symlink, or not a link to annex - content. @@ -38,7 +37,7 @@ isAnnexLink file = maybe Nothing (fileKey . takeFileName) <$> getAnnexLinkTarget getAnnexLinkTarget :: FilePath -> Annex (Maybe LinkTarget) getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig) ( check readSymbolicLink $ - check readfilestart $ + check probefilecontent $ return Nothing , check readSymbolicLink $ return Nothing @@ -52,11 +51,26 @@ getAnnexLinkTarget file = ifM (coreSymlinks <$> Annex.getGitConfig) | otherwise -> return Nothing Nothing -> fallback - readfilestart f = do + probefilecontent f = do h <- openFile f ReadMode fileEncoding h + -- The first 8k is more than enough to read; link + -- files are small. 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. - |