Hello community, here is the log from the commit of package ghc-zip-archive for openSUSE:Factory checked in at 2015-02-10 20:22:04 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-zip-archive (Old) and /work/SRC/openSUSE:Factory/.ghc-zip-archive.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-zip-archive" Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-zip-archive/ghc-zip-archive.changes 2014-04-02 17:18:57.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-zip-archive.new/ghc-zip-archive.changes 2015-02-10 20:22:06.000000000 +0100 @@ -1,0 +2,36 @@ +Sun Feb 1 08:54:40 UTC 2015 - [email protected] + +- Update to 0.2.3.7: + * Declared test suite's dependency on 'zip' using custom Setup.lhs (#21,#22). + * Removed hard-coded path to zip in test suite (#21). + * Removed misplaced build-depends in cabal file. + * Allow compilation with binary >= 0.5. Note that toArchiveOrFail + is not safe when compiled against binary < 0.7; it will never + return a Left value, and will raise an error if parsing fails, + just like toArchive. This is documented in the haddocks. + This is ugly, but justified by the need to have a version + of zip-archive that compiles against older versions of binary. + * Make sure all path comparisons compare normalized paths. + So, findEntryByPath "foo" will find something stored as "./foo" + in the zip container. + * Better normalization of file paths: "./foo/bar" and "foo/./bar" + are now treated the same, for example. Note that we do not + yet treat "foo/../bar" and "bar" as the same. + * Removed lower bound on directory (>= 1.2), which caused build + failures with GHC 7.4 and 7.6. + * Added travis script for automatic testing on 3 GHC versions. + * Require binary >= 0.7 and directory >= 1.2. The newer binary + is needed to provide toArchiveOrFail. The other change is + mainly for convenience, to avoid lots of ugly conditional + compilation. + * Export new function `toArchiveOrFail`. Closes #17. + * Set general purpose bit flag to use UTF8 in local file header. + Otherwise we get a mismatch between the flag in the central + directory and the flag in the local file header, which causes some + programs not to be able to extract the files. Closes #19. + * Fix a stack overflow in getWordsTillSig (Tristan Ravitch). + recognize UTF-8 encoded file names (Tobias Brandt). + * Added OptLocation, to specify the path to which a file + is to be added when readEntry is used (Stephen McIntosh). + +------------------------------------------------------------------- Old: ---- zip-archive-0.2.tar.gz New: ---- zip-archive-0.2.3.7.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-zip-archive.spec ++++++ --- /var/tmp/diff_new_pack.J9FlZf/_old 2015-02-10 20:22:07.000000000 +0100 +++ /var/tmp/diff_new_pack.J9FlZf/_new 2015-02-10 20:22:07.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package ghc-zip-archive # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -19,7 +19,7 @@ %global pkg_name zip-archive Name: ghc-zip-archive -Version: 0.2 +Version: 0.2.3.7 Release: 0 Summary: Library for creating and modifying zip archives License: BSD-3-Clause ++++++ zip-archive-0.2.tar.gz -> zip-archive-0.2.3.7.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2/README.markdown new/zip-archive-0.2.3.7/README.markdown --- old/zip-archive-0.2/README.markdown 1970-01-01 01:00:00.000000000 +0100 +++ new/zip-archive-0.2.3.7/README.markdown 2015-01-21 20:09:49.000000000 +0100 @@ -0,0 +1,6 @@ +zip-archive +=========== + +The zip-archive library provides functions for creating, modifying, and +extracting files from zip archives. + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2/Setup.lhs new/zip-archive-0.2.3.7/Setup.lhs --- old/zip-archive-0.2/Setup.lhs 2013-12-10 18:50:20.000000000 +0100 +++ new/zip-archive-0.2.3.7/Setup.lhs 2015-01-21 20:09:49.000000000 +0100 @@ -1,3 +1,11 @@ #!/usr/bin/env runhaskell + +> module Main ( main ) where +> > import Distribution.Simple -> main = defaultMain +> import Distribution.Simple.Program +> +> main :: IO () +> main = defaultMainWithHooks simpleUserHooks +> { hookedPrograms = [ simpleProgram "zip" ] +> } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2/changelog new/zip-archive-0.2.3.7/changelog --- old/zip-archive-0.2/changelog 1970-01-01 01:00:00.000000000 +0100 +++ new/zip-archive-0.2.3.7/changelog 2015-01-21 20:09:49.000000000 +0100 @@ -0,0 +1,65 @@ +zip-archive 0.2.3.7 + + * Declared test suite's dependency on 'zip' using custom Setup.lhs (#21,#22). + +zip-archive 0.2.3.6 + + * Removed hard-coded path to zip in test suite (#21). + * Removed misplaced build-depends in cabal file. + +zip-archive 0.2.3.5 + + * Allow compilation with binary >= 0.5. Note that toArchiveOrFail + is not safe when compiled against binary < 0.7; it will never + return a Left value, and will raise an error if parsing fails, + just like toArchive. This is documented in the haddocks. + This is ugly, but justified by the need to have a version + of zip-archive that compiles against older versions of binary. + +zip-archive 0.2.3.4 + + * Make sure all path comparisons compare normalized paths. + So, findEntryByPath "foo" will find something stored as "./foo" + in the zip container. + +zip-archive 0.2.3.3 + + * Better normalization of file paths: "./foo/bar" and "foo/./bar" + are now treated the same, for example. Note that we do not + yet treat "foo/../bar" and "bar" as the same. + +zip-archive 0.2.3.2 + + * Removed lower bound on directory (>= 1.2), which caused build + failures with GHC 7.4 and 7.6. + * Added travis script for automatic testing on 3 GHC versions. + +zip-archive 0.2.3.1 + + * Require binary >= 0.7 and directory >= 1.2. The newer binary + is needed to provide toArchiveOrFail. The other change is + mainly for convenience, to avoid lots of ugly conditional + compilation. + +zip-archive 0.2.3 + + * Export new function `toArchiveOrFail`. Closes #17. + * Set general purpose bit flag to use UTF8 in local file header. + Otherwise we get a mismatch between the flag in the central + directory and the flag in the local file header, which causes some + programs not to be able to extract the files. Closes #19. + +zip-archive 0.2.2.1 + + * Fix a stack overflow in getWordsTillSig (Tristan Ravitch). + +zip-archive 0.2.2 + + * Set bit 11 in the file header to ensure other programs + recognize UTF-8 encoded file names (Tobias Brandt). + +zip-archive 0.2.1 + + * Added OptLocation, to specify the path to which a file + is to be added when readEntry is used (Stephen McIntosh). + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2/src/Codec/Archive/Zip.hs new/zip-archive-0.2.3.7/src/Codec/Archive/Zip.hs --- old/zip-archive-0.2/src/Codec/Archive/Zip.hs 2013-12-10 18:50:20.000000000 +0100 +++ new/zip-archive-0.2.3.7/src/Codec/Archive/Zip.hs 2015-01-21 20:09:49.000000000 +0100 @@ -38,6 +38,7 @@ -- * Pure functions for working with zip archives , toArchive + , toArchiveOrFail , fromArchive , filesInArchive , addEntryToArchive @@ -57,25 +58,21 @@ import System.Time ( toUTCTime, addToClockTime, CalendarTime (..), ClockTime (..), TimeDiff (..) ) #if MIN_VERSION_directory(1,2,0) import Data.Time.Clock.POSIX ( utcTimeToPOSIXSeconds ) -#else #endif import Data.Bits ( shiftL, shiftR, (.&.) ) import Data.Binary import Data.Binary.Get import Data.Binary.Put -import Data.List ( nub, find ) +import Data.List ( nub, find, intercalate ) import Text.Printf import System.FilePath import System.Directory ( doesDirectoryExist, getDirectoryContents, createDirectoryIfMissing ) import Control.Monad ( when, unless, zipWithM ) -#if MIN_VERSION_directory(1,2,0) -import Control.Monad ( liftM ) -#endif import System.Directory ( getModificationTime ) import System.IO ( stderr, hPutStrLn ) import qualified Data.Digest.CRC32 as CRC32 import qualified Data.Map as M -#if MIN_VERSION_binary(0, 6, 0) +#if MIN_VERSION_binary(0,6,0) import Control.Applicative #endif #ifndef _WINDOWS @@ -104,6 +101,7 @@ else return [] #endif + ------------------------------------------------------------------------ -- | Structured representation of a zip archive, including directory @@ -142,6 +140,7 @@ data ZipOption = OptRecursive -- ^ Recurse into directories when adding files | OptVerbose -- ^ Print information to stderr | OptDestination FilePath -- ^ Directory in which to extract + | OptLocation FilePath Bool -- ^ Where to place file when adding files and whether to append current path deriving (Read, Show, Eq) -- | A zip archive with no contents. @@ -155,6 +154,20 @@ toArchive :: B.ByteString -> Archive toArchive = decode +-- | Like 'toArchive', but returns an 'Either' value instead of raising an +-- error if the archive cannot be decoded. NOTE: This function only +-- works properly when the library is compiled against binary >= 0.7. +-- With earlier versions, it will always return a Right value, +-- raising an error if parsing fails. +toArchiveOrFail :: B.ByteString -> Either String Archive +#if MIN_VERSION_binary(0,7,0) +toArchiveOrFail bs = case decodeOrFail bs of + Left (_,_,e) -> Left e + Right (_,_,x) -> Right x +#else +toArchiveOrFail bs = Right $ toArchive bs +#endif + -- | Writes an 'Archive' structure to a raw zip archive (in a lazy bytestring). fromArchive :: Archive -> B.ByteString fromArchive = encode @@ -173,13 +186,13 @@ -- | Deletes an entry from a zip archive. deleteEntryFromArchive :: FilePath -> Archive -> Archive deleteEntryFromArchive path archive = - let path' = zipifyFilePath path - newEntries = filter (\e -> eRelativePath e /= path') $ zEntries archive - in archive { zEntries = newEntries } + archive { zEntries = [e | e <- zEntries archive + , not (eRelativePath e `matches` path)] } -- | Returns Just the zip entry with the specified path, or Nothing. findEntryByPath :: FilePath -> Archive -> Maybe Entry -findEntryByPath path archive = find (\e -> path == eRelativePath e) (zEntries archive) +findEntryByPath path archive = + find (\e -> path `matches` eRelativePath e) (zEntries archive) -- | Returns uncompressed contents of zip entry. fromEntry :: Entry -> B.ByteString @@ -204,7 +217,7 @@ then (NoCompression, contents, uncompressedSize) else (Deflate, compressedData, compressedSize) crc32 = CRC32.crc32 contents - in Entry { eRelativePath = path + in Entry { eRelativePath = normalizePath path , eCompressionMethod = compressionMethod , eLastModified = modtime , eCRC32 = crc32 @@ -221,13 +234,19 @@ readEntry :: [ZipOption] -> FilePath -> IO Entry readEntry opts path = do isDir <- doesDirectoryExist path - let path' = zipifyFilePath $ normalise $ - path ++ if isDir then "/" else "" -- make sure directories end with / + -- make sure directories end in / and deal with the OptLocation option + let path' = let p = path ++ (case reverse path of + ('/':_) -> "" + _ | isDir -> "/" + | otherwise -> "") in + (case [(l,a) | OptLocation l a <- opts] of + ((l,a):_) -> if a then l </> p else l + _ -> p) contents <- if isDir then return B.empty else B.readFile path #if MIN_VERSION_directory(1,2,0) - modEpochTime <- liftM (floor . utcTimeToPOSIXSeconds) + modEpochTime <- fmap (floor . utcTimeToPOSIXSeconds) $ getModificationTime path #else (TOD modEpochTime _) <- getModificationTime path @@ -290,14 +309,18 @@ -- Internal functions for reading and writing zip binary format. -- Note that even on Windows, zip files use "/" internally as path separator. -zipifyFilePath :: FilePath -> String -zipifyFilePath path = - let dir = takeDirectory path - fn = takeFileName path +normalizePath :: FilePath -> String +normalizePath path = + let dir = takeDirectory path + fn = takeFileName path (_drive, dir') = splitDrive dir -- note: some versions of filepath return ["."] if no dir - dirParts = dropWhile (==".") $ splitDirectories dir' - in (concat (map (++ "/") dirParts)) ++ fn + dirParts = filter (/=".") $ splitDirectories dir' + in intercalate "/" (dirParts ++ [fn]) + +-- Equality modulo normalization. So, "./foo" `matches` "foo". +matches :: FilePath -> FilePath -> Bool +matches fp1 fp2 = normalizePath fp1 == normalizePath fp2 -- | Uncompress a lazy bytestring. compressData :: CompressionMethod -> B.ByteString -> B.ByteString @@ -434,7 +457,7 @@ getArchive :: Get Archive getArchive = do -#if MIN_VERSION_binary(0, 6, 0) +#if MIN_VERSION_binary(0,6,0) locals <- many getLocalFile files <- many (getFileHeader (M.fromList locals)) digSig <- Just `fmap` getDigitalSignature <|> return Nothing @@ -442,7 +465,7 @@ locals <- manySig 0x04034b50 getLocalFile files <- manySig 0x02014b50 (getFileHeader (M.fromList locals)) digSig <- lookAheadM getDigitalSignature -#endif +#endif endSig <- getWord32le unless (endSig == 0x06054b50) $ fail "Did not find end of central directory signature" @@ -482,13 +505,13 @@ fileHeaderSize :: Entry -> Word32 fileHeaderSize f = fromIntegral $ 4 + 2 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + - fromIntegral (B.length $ fromString $ zipifyFilePath $ eRelativePath f) + + fromIntegral (B.length $ fromString $ normalizePath $ eRelativePath f) + B.length (eExtraField f) + B.length (eFileComment f) localFileSize :: Entry -> Word32 localFileSize f = fromIntegral $ 4 + 2 + 2 + 2 + 2 + 2 + 4 + 4 + 4 + 2 + 2 + - fromIntegral (B.length $ fromString $ zipifyFilePath $ eRelativePath f) + + fromIntegral (B.length $ fromString $ normalizePath $ eRelativePath f) + B.length (eExtraField f) + B.length (eCompressedData f) -- Local file header: @@ -549,27 +572,27 @@ return (fromIntegral offset, compressedData) getWordsTilSig :: Word32 -> Get [Word8] -getWordsTilSig sig = do +getWordsTilSig sig = go [] + where + go acc = do #if MIN_VERSION_binary(0, 6, 0) - (getWord32le >>= ensure (== sig) >> return []) <|> - do w <- getWord8 - ws <- getWordsTilSig sig - return (w:ws) + (getWord32le >>= ensure (== sig) >> return (reverse acc)) <|> + do w <- getWord8 + go (w:acc) #else - sig' <- lookAhead getWord32le - if sig == sig' - then skip 4 >> return [] - else do - w <- getWord8 - ws <- getWordsTilSig sig - return (w:ws) + sig' <- lookAhead getWord32le + if sig == sig' + then skip 4 >> return (reverse acc) + else do + w <- getWord8 + go (w:acc) #endif putLocalFile :: Entry -> Put putLocalFile f = do putWord32le 0x04034b50 putWord16le 20 -- version needed to extract (>=2.0) - putWord16le 2 -- general purpose bit flag (max compression) + putWord16le 0x802 -- general purpose bit flag (bit 1 = max compression, bit 11 = UTF-8) putWord16le $ case eCompressionMethod f of NoCompression -> 0 Deflate -> 8 @@ -580,9 +603,9 @@ putWord32le $ eCompressedSize f putWord32le $ eUncompressedSize f putWord16le $ fromIntegral $ B.length $ fromString - $ zipifyFilePath $ eRelativePath f + $ normalizePath $ eRelativePath f putWord16le $ fromIntegral $ B.length $ eExtraField f - putLazyByteString $ fromString $ zipifyFilePath $ eRelativePath f + putLazyByteString $ fromString $ normalizePath $ eRelativePath f putLazyByteString $ eExtraField f putLazyByteString $ eCompressedData f @@ -667,7 +690,7 @@ putWord32le 0x02014b50 putWord16le 0 -- version made by putWord16le 20 -- version needed to extract (>= 2.0) - putWord16le 2 -- general purpose bit flag (max compression) + putWord16le 0x802 -- general purpose bit flag (bit 1 = max compression, bit 11 = UTF-8) putWord16le $ case eCompressionMethod local of NoCompression -> 0 Deflate -> 8 @@ -678,14 +701,14 @@ putWord32le $ eCompressedSize local putWord32le $ eUncompressedSize local putWord16le $ fromIntegral $ B.length $ fromString - $ zipifyFilePath $ eRelativePath local + $ normalizePath $ eRelativePath local putWord16le $ fromIntegral $ B.length $ eExtraField local putWord16le $ fromIntegral $ B.length $ eFileComment local putWord16le 0 -- disk number start putWord16le $ eInternalFileAttributes local putWord32le $ eExternalFileAttributes local putWord32le offset - putLazyByteString $ fromString $ zipifyFilePath $ eRelativePath local + putLazyByteString $ fromString $ normalizePath $ eRelativePath local putLazyByteString $ eExtraField local putLazyByteString $ eFileComment local @@ -695,7 +718,7 @@ -- > size of data 2 bytes -- > signature data (variable size) -#if MIN_VERSION_binary(0, 6, 0) +#if MIN_VERSION_binary(0,6,0) getDigitalSignature :: Get B.ByteString getDigitalSignature = do getWord32le >>= ensure (== 0x05054b50) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2/tests/test-zip-archive.hs new/zip-archive-0.2.3.7/tests/test-zip-archive.hs --- old/zip-archive-0.2/tests/test-zip-archive.hs 2013-12-10 18:50:20.000000000 +0100 +++ new/zip-archive-0.2.3.7/tests/test-zip-archive.hs 2015-01-21 20:09:49.000000000 +0100 @@ -1,3 +1,4 @@ +{-# OPTIONS_GHC -fno-warn-orphans #-} -- Test suite for Codec.Archive.Zip -- runghc Test.hs @@ -44,7 +45,7 @@ testReadExternalZip :: Test testReadExternalZip = TestCase $ do - _ <- runCommand "/usr/bin/zip -q -9 test-temp/test4.zip zip-archive.cabal src/Codec/Archive/Zip.hs" >>= waitForProcess + _ <- runCommand "zip -q -9 test-temp/test4.zip zip-archive.cabal src/Codec/Archive/Zip.hs" >>= waitForProcess archive <- toArchive <$> B.readFile "test-temp/test4.zip" let files = filesInArchive archive assertEqual "for results of filesInArchive" ["zip-archive.cabal", "src/Codec/Archive/Zip.hs"] files diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/zip-archive-0.2/zip-archive.cabal new/zip-archive-0.2.3.7/zip-archive.cabal --- old/zip-archive-0.2/zip-archive.cabal 2013-12-10 18:50:20.000000000 +0100 +++ new/zip-archive-0.2.3.7/zip-archive.cabal 2015-01-21 20:09:49.000000000 +0100 @@ -1,17 +1,18 @@ Name: zip-archive -Version: 0.2 +Version: 0.2.3.7 Cabal-Version: >= 1.10 -Build-type: Simple +Build-type: Custom Synopsis: Library for creating and modifying zip archives. Description: The zip-archive library provides functions for creating, modifying, and extracting files from zip archives. Category: Codec +Tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.2 License: BSD3 License-file: LICENSE Homepage: http://github.com/jgm/zip-archive Author: John MacFarlane Maintainer: [email protected] -Build-Depends: base +Extra-Source-Files: changelog, README.markdown Source-repository head type: git @@ -29,12 +30,13 @@ Build-depends: base >= 3 && < 5, pretty, containers else Build-depends: base < 3 - Build-depends: binary >= 0.5, zlib, filepath, bytestring >= 0.9.0, array, mtl, text >= 0.11, old-time, digest >= 0.0.0.1, directory, time + Build-depends: binary >= 0.5, zlib, filepath, bytestring >= 0.9.0, + array, mtl, text >= 0.11, old-time, digest >= 0.0.0.1, + directory, time Exposed-modules: Codec.Archive.Zip Default-Language: Haskell98 Hs-Source-Dirs: src Ghc-Options: -Wall - Default-Extensions: CPP if os(windows) cpp-options: -D_WINDOWS else @@ -61,3 +63,4 @@ HUnit, zip-archive Default-Language: Haskell98 Ghc-Options: -Wall + Build-Tools: zip -- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
