zip 0.1.6 → 0.1.7
raw patch · 4 files changed
+36/−52 lines, 4 filesdep ~zip
Dependency ranges changed: zip
Files
- CHANGELOG.md +4/−0
- Codec/Archive/Zip/Internal.hs +30/−28
- tests/Main.hs +0/−13
- zip.cabal +2/−11
CHANGELOG.md view
@@ -1,3 +1,7 @@+## Zip 0.1.7++* Fix literal overflows on 32 bit systems.+ ## Zip 0.1.6 * Allowed `time-1.7`.
Codec/Archive/Zip/Internal.hs view
@@ -9,7 +9,6 @@ -- -- Low-level, non-public concepts and operations. -{-# LANGUAGE CPP #-} {-# LANGUAGE ScopedTypeVariables #-} module Codec.Archive.Zip.Internal@@ -478,23 +477,19 @@ -> IO () writeCD h comment m = do let cd = runPut (putCD m)- cdOffset <- hTell h+ cdOffset <- fromIntegral <$> hTell h B.hPut h cd -- write central directory- let totalCount = M.size m- cdSize = B.length cd+ let totalCount = fromIntegral (M.size m)+ cdSize = fromIntegral (B.length cd) needZip64 =-#ifdef USE_ZIP64_ECD- True-#else- totalCount >= 0xffff- || cdSize >= 0xffffffff- || cdOffset >= 0xffffffff-#endif+ totalCount >= ffff+ || cdSize >= ffffffff+ || cdOffset >= ffffffff when needZip64 $ do- zip64ecdOffset <- hTell h- B.hPut h . runPut $ putZip64ECD totalCount cdSize cdOffset- B.hPut h . runPut $ putZip64ECDLocator zip64ecdOffset- B.hPut h . runPut $ putECD totalCount cdSize cdOffset comment+ zip64ecdOffset <- fromIntegral <$> hTell h+ (B.hPut h . runPut) (putZip64ECD totalCount cdSize cdOffset)+ (B.hPut h . runPut) (putZip64ECDLocator zip64ecdOffset)+ (B.hPut h . runPut) (putECD totalCount cdSize cdOffset comment) ---------------------------------------------------------------------------- -- Binary serialization@@ -606,7 +601,7 @@ -> Zip64ExtraField -- ^ Result parseZip64ExtraField dflt@Zip64ExtraField {..} b = either (const dflt) id . flip runGet b $ do- let ifsat v = if v >= 0xffffffff+ let ifsat v = if v >= ffffffff then fromIntegral <$> getWord64le else return v uncompressed <- ifsat z64efUncompressedSize -- uncompressed size@@ -621,11 +616,11 @@ -> Zip64ExtraField -- ^ Zip64 extra field's data -> ByteString -- ^ Resulting representation makeZip64ExtraField c Zip64ExtraField {..} = runPut $ do- when (c == LocalHeader || z64efUncompressedSize >= 0xffffffff) $+ when (c == LocalHeader || z64efUncompressedSize >= ffffffff) $ putWord64le (fromIntegral z64efUncompressedSize) -- uncompressed size- when (c == LocalHeader || z64efCompressedSize >= 0xffffffff) $+ when (c == LocalHeader || z64efCompressedSize >= ffffffff) $ putWord64le (fromIntegral z64efCompressedSize) -- compressed size- when (c == CentralDirHeader && z64efOffset >= 0xffffffff) $+ when (c == CentralDirHeader && z64efOffset >= ffffffff) $ putWord64le (fromIntegral z64efOffset) -- offset of local file header -- | Create 'ByteString' representing an extra field.@@ -693,9 +688,9 @@ -- | Create 'ByteString' representing Zip64 end of central directory record. putZip64ECD- :: Int -- ^ Total number of entries- -> Int -- ^ Size of the central directory- -> Integer -- ^ Offset of central directory record+ :: Natural -- ^ Total number of entries+ -> Natural -- ^ Size of the central directory+ -> Natural -- ^ Offset of central directory record -> Put putZip64ECD totalCount cdSize cdOffset = do putWord32le 0x06064b50 -- zip64 end of central dir signature@@ -714,7 +709,7 @@ -- locator. putZip64ECDLocator- :: Integer -- ^ Offset of Zip64 end of central directory+ :: Natural -- ^ Offset of Zip64 end of central directory -> Put putZip64ECDLocator ecdOffset = do putWord32le 0x07064b50 -- zip64 end of central dir locator signature@@ -766,9 +761,9 @@ -- | Create 'ByteString' representing end of central directory record. putECD- :: Int -- ^ Total number of entries- -> Int -- ^ Size of the central directory- -> Integer -- ^ Offset of central directory record+ :: Natural -- ^ Total number of entries+ -> Natural -- ^ Size of the central directory+ -> Natural -- ^ Offset of central directory record -> Maybe Text -- ^ Zip file comment -> Put putECD totalCount cdSize cdOffset mcomment = do@@ -876,7 +871,7 @@ withSaturation :: forall a b. (Integral a, Integral b, Bounded b) => a -> b withSaturation x =- if x > fromIntegral (maxBound :: b)+ if fromIntegral x > (maxBound :: b) then maxBound :: b else fromIntegral x @@ -949,7 +944,7 @@ -- | Check if entry with these parameters needs Zip64 extension. needsZip64 :: EntryDescription -> Bool-needsZip64 EntryDescription {..} = any (>= 0xffffffff)+needsZip64 EntryDescription {..} = any (>= ffffffff) [edOffset, edCompressedSize, edUncompressedSize] -- | Determine “version needed to extract” that should be written headers@@ -1009,3 +1004,10 @@ day = fromIntegral (msDosDate .&. 0x1f) month = fromIntegral $ shiftR msDosDate 5 .&. 0x0f year = 1980 + fromIntegral (shiftR msDosDate 9)++-- | We use the constants of type 'Natural' instead of literals to protect+-- ourselves from overflows on 32 bit systems.++ffff, ffffffff :: Natural+ffff = 0xffff+ffffffff = 0xffffffff
tests/Main.hs view
@@ -30,7 +30,6 @@ -- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -- POSSIBILITY OF SUCH DAMAGE. -{-# LANGUAGE CPP #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-}@@ -735,17 +734,5 @@ emptyArchive :: ByteString emptyArchive = B.pack-#ifdef USE_ZIP64_ECD- [ 0x50, 0x4b, 0x06, 0x06, 0x2c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x2e, 0x00, 0x2d, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x50, 0x4b, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x50- , 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00- , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]-#else [ 0x50, 0x4b, 0x05, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 , 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 ]-#endif
zip.cabal view
@@ -31,7 +31,7 @@ -- POSSIBILITY OF SUCH DAMAGE. name: zip-version: 0.1.6+version: 0.1.7 cabal-version: >= 1.10 license: BSD3 license-file: LICENSE.md@@ -51,11 +51,6 @@ manual: True default: False -flag zip64-ecd- description: Unconditionally use Zip64 ECD format.- manual: True- default: False- library build-depends: base >= 4.8 && < 5.0 , bytestring >= 0.9 && < 0.11@@ -88,8 +83,6 @@ ghc-options: -Wall -Werror else ghc-options: -O2 -Wall- if flag(zip64-ecd)- cpp-options: -DUSE_ZIP64_ECD default-language: Haskell2010 test-suite tests@@ -100,8 +93,6 @@ ghc-options: -Wall -Werror else ghc-options: -O2 -Wall- if flag(zip64-ecd)- cpp-options: -DUSE_ZIP64_ECD build-depends: base >= 4.8 && < 5.0 , bytestring >= 0.9 && < 0.11 , conduit >= 1.1 && < 2.0@@ -115,7 +106,7 @@ , text >= 0.2 && < 1.3 , time >= 1.4 && < 1.8 , transformers >= 0.4 && < 0.6- , zip >= 0.1.6+ , zip >= 0.1.7 default-language: Haskell2010 source-repository head