read a consistent amount from pointer file

A few places were reading the max symlink size of a pointer file,
then passing tp parseLinkTargetOrPointer. Which is fine currently, but
to support pointer files with lines of data after the pointer, enough
has to be read that parseLinkTargetOrPointer can be assured of seeing
enough of that data to know if it's correctly formatted.

Sponsored-by: Dartmouth College's Datalad project
This commit is contained in:
Joey Hess 2022-02-23 12:38:35 -04:00
parent 4cd9325c2c
commit 5b373a9dd2
No known key found for this signature in database
GPG key ID: DB12DB0FF05F8F38
5 changed files with 12 additions and 12 deletions

View file

@ -162,7 +162,7 @@ catKey' ref sz
-- Avoid catting large files, that cannot be symlinks or -- Avoid catting large files, that cannot be symlinks or
-- pointer files, which would require buffering their -- pointer files, which would require buffering their
-- content in memory, as well as a lot of IO. -- content in memory, as well as a lot of IO.
| sz <= maxPointerSz = | sz <= fromIntegral maxPointerSz =
parseLinkTargetOrPointer . L.toStrict <$> catObject ref parseLinkTargetOrPointer . L.toStrict <$> catObject ref
catKey' _ _ = return Nothing catKey' _ _ = return Nothing

View file

@ -82,10 +82,10 @@ getAnnexLinkTarget' file coresymlinks = if coresymlinks
probesymlink = R.readSymbolicLink file probesymlink = R.readSymbolicLink file
probefilecontent = withFile (fromRawFilePath file) ReadMode $ \h -> do probefilecontent = withFile (fromRawFilePath file) ReadMode $ \h -> do
s <- S.hGet h unpaddedMaxPointerSz s <- S.hGet h maxSymlinkSz
-- If we got the full amount, the file is too large -- If we got the full amount, the file is too large
-- to be a symlink target. -- to be a symlink target.
return $ if S.length s == unpaddedMaxPointerSz return $ if S.length s == maxSymlinkSz
then mempty then mempty
else else
-- If there are any NUL or newline -- If there are any NUL or newline
@ -331,13 +331,13 @@ formatPointer k = prefix <> keyFile k <> nl
- memory when reading files that may be pointers. - memory when reading files that may be pointers.
- -
- 8192 bytes is plenty for a pointer to a key. This adds some additional - 8192 bytes is plenty for a pointer to a key. This adds some additional
- padding to allow for any pointer files that might have - padding to allow for pointer files that have lines of additional data
- lines after the key explaining what the file is used for. -} - after the key. -}
maxPointerSz :: Integer maxPointerSz :: Int
maxPointerSz = 81920 maxPointerSz = 81920
unpaddedMaxPointerSz :: Int maxSymlinkSz :: Int
unpaddedMaxPointerSz = 8192 maxSymlinkSz = 8192
{- Checks if a worktree file is a pointer to a key. {- Checks if a worktree file is a pointer to a key.
- -
@ -367,7 +367,7 @@ isPointerFile f = catchDefaultIO Nothing $
where where
checkcontentfollowssymlinks = checkcontentfollowssymlinks =
withFile (fromRawFilePath f) ReadMode readhandle withFile (fromRawFilePath f) ReadMode readhandle
readhandle h = parseLinkTargetOrPointer <$> S.hGet h unpaddedMaxPointerSz readhandle h = parseLinkTargetOrPointer <$> S.hGet h maxPointerSz
{- Checks a symlink target or pointer file first line to see if it {- Checks a symlink target or pointer file first line to see if it
- appears to point to annexed content. - appears to point to annexed content.

View file

@ -464,7 +464,7 @@ seekFilteredKeys seeker listfs = do
mdprocess mi mdreader ofeeder ocloser = liftIO mdreader >>= \case mdprocess mi mdreader ofeeder ocloser = liftIO mdreader >>= \case
Just ((si, f), Just (sha, size, _type)) Just ((si, f), Just (sha, size, _type))
| size < maxPointerSz -> do | size < fromIntegral maxPointerSz -> do
feedmatches mi ofeeder si f sha feedmatches mi ofeeder si f sha
mdprocess mi mdreader ofeeder ocloser mdprocess mi mdreader ofeeder ocloser
Just _ -> mdprocess mi mdreader ofeeder ocloser Just _ -> mdprocess mi mdreader ofeeder ocloser

View file

@ -62,7 +62,7 @@ clean file = do
let conv b l = (B.concat (map pktLineToByteString l), b) let conv b l = (B.concat (map pktLineToByteString l), b)
(b, readcomplete) <- (b, readcomplete) <-
either (conv False) (conv True) either (conv False) (conv True)
<$> liftIO (readUntilFlushPktOrSize unpaddedMaxPointerSz) <$> liftIO (readUntilFlushPktOrSize maxPointerSz)
let passthrough let passthrough
| readcomplete = liftIO $ respondFilterRequest b | readcomplete = liftIO $ respondFilterRequest b

View file

@ -447,7 +447,7 @@ reconcileStaged qh = unlessM (Git.Config.isBare <$> gitRepo) $ do
where where
procthread mdreader catfeeder = mdreader >>= \case procthread mdreader catfeeder = mdreader >>= \case
Just (ka, Just (sha, size, _type)) Just (ka, Just (sha, size, _type))
| size < maxPointerSz -> do | size < fromIntegral maxPointerSz -> do
() <- catfeeder (ka, sha) () <- catfeeder (ka, sha)
procthread mdreader catfeeder procthread mdreader catfeeder
Just _ -> procthread mdreader catfeeder Just _ -> procthread mdreader catfeeder