Bugfixes
This commit is contained in:
parent
6c1afb6919
commit
88493d34a0
@ -34,6 +34,8 @@ import Data.Time
|
||||
import GHC.Generics (Generic)
|
||||
import Data.Typeable (Typeable)
|
||||
|
||||
import Data.List (dropWhileEnd)
|
||||
|
||||
|
||||
data ZipEntry = ZipEntry
|
||||
{ zipEntryName :: FilePath
|
||||
@ -60,13 +62,13 @@ consumeZip handleEntry = Zip.unZipStream `fuseBoth` consumeZip'
|
||||
input <- await
|
||||
case input of
|
||||
Nothing -> return []
|
||||
Just (Right _) -> consumeZip' -- throw $ userError "Data chunk in unexpected place when parsing ZIP"
|
||||
Just (Right _) -> throw $ userError "Data chunk in unexpected place when parsing ZIP"
|
||||
Just (Left e) -> do
|
||||
zipEntryName' <- fmap Text.unpack . either throw return . Text.decodeUtf8' $ Zip.zipEntryName e
|
||||
contentChunks <- accContents
|
||||
let
|
||||
zipEntryName = normalise . makeValid $ dropTrailingPathSeparator zipEntryName'
|
||||
zipEntryTime = localTimeToUTC utc $ Zip.zipEntryTime e
|
||||
zipEntryName = normalise $ makeValid zipEntryName'
|
||||
zipEntryTime = fixZipEpoch . localTimeToUTC utc $ Zip.zipEntryTime e
|
||||
zipEntryContents
|
||||
| hasTrailingPathSeparator zipEntryName' = Nothing
|
||||
| otherwise = Just $ Lazy.ByteString.fromChunks contentChunks
|
||||
@ -76,8 +78,15 @@ consumeZip handleEntry = Zip.unZipStream `fuseBoth` consumeZip'
|
||||
input <- await
|
||||
case input of
|
||||
Just (Right x) -> (x :) <$> accContents
|
||||
Just (Left x) -> [] <$ leftover (Left x)
|
||||
_ -> return []
|
||||
|
||||
fixZipEpoch :: UTCTime -> UTCTime
|
||||
-- ^ Testing showed that the zip library used introduces a weird offset into
|
||||
-- dates when packing/unpacking zip files.
|
||||
-- This is fixed here, for now.
|
||||
fixZipEpoch u@(UTCTime{..}) = u{ utctDay = addDays (-46751) utctDay }
|
||||
|
||||
|
||||
produceZip :: ( MonadBase b m
|
||||
, PrimMonad b
|
||||
@ -101,6 +110,6 @@ produceZip info = Conduit.map toZipData =$= void (Zip.zipStream zipOptions)
|
||||
toZipEntry :: Bool -- ^ Is directory?
|
||||
-> ZipEntry -> Zip.ZipEntry
|
||||
toZipEntry isDir ZipEntry{..} = Zip.ZipEntry
|
||||
{ zipEntryName = Text.encodeUtf8 . Text.pack . normalise . makeValid . bool dropTrailingPathSeparator addTrailingPathSeparator isDir $ zipEntryName
|
||||
{ zipEntryName = Text.encodeUtf8 . Text.pack . bool (dropWhileEnd isPathSeparator) addTrailingPathSeparator isDir . normalise . makeValid $ zipEntryName
|
||||
, zipEntryTime = utcToLocalTime utc zipEntryTime
|
||||
}
|
||||
|
||||
@ -12,7 +12,9 @@ import System.FilePath
|
||||
|
||||
import Data.Conduit
|
||||
import qualified Data.Conduit.List as Conduit
|
||||
import Data.Conduit.Binary (sourceLbs, sinkLbs)
|
||||
|
||||
import Data.List (dropWhileEnd)
|
||||
import Data.Time
|
||||
|
||||
instance Arbitrary ZipEntry where
|
||||
arbitrary = do
|
||||
@ -25,9 +27,11 @@ spec :: Spec
|
||||
spec = describe "Zip file handling" $ do
|
||||
it "has compatible encoding/decoding to/from zip files" . property $
|
||||
\zipFiles -> do
|
||||
bs <- runConduit $ Conduit.sourceList zipFiles =$= produceZip def =$= sinkLbs
|
||||
(_, zipFiles') <- runConduit $ sourceLbs bs =$= consumeZip return
|
||||
forM_ (zip zipFiles zipFiles') $ \(file, file') -> do
|
||||
(shouldBe `on` normalise . makeValid . dropTrailingPathSeparator) (zipEntryName file') (zipEntryName file)
|
||||
-- (zipEntryTime file') `shouldBe` (zipEntryTime file)
|
||||
(_, zipFiles') <- runConduit $ Conduit.sourceList zipFiles =$= produceZip def =$= consumeZip return
|
||||
forM_ (zipFiles `zip` zipFiles') $ \(file, file') -> do
|
||||
let acceptableFilenameChanges
|
||||
= bool (dropWhileEnd isPathSeparator) addTrailingPathSeparator (isNothing $ zipEntryContents file) . normalise . makeValid
|
||||
acceptableTimeDifference t1 t2 = abs (diffUTCTime t1 t2) <= 2
|
||||
(shouldBe `on` acceptableFilenameChanges) (zipEntryName file') (zipEntryName file)
|
||||
(zipEntryTime file', zipEntryTime file) `shouldSatisfy` uncurry acceptableTimeDifference
|
||||
(zipEntryContents file') `shouldBe` (zipEntryContents file)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user