on master help sign in
More descriptive error message on failure to unzip .ibc

To give more guidance on errors like https://github.com/edwinb/SDL-idris/issues/2 The DecompressError can be one of three things: http://hackage.haskell.org/package/zlib-0.5.4.1/docs/Codec-Compression-Zlib-Internal.html#t:DecompressError There's not a show instance for it, though. When I try to unzip "/etc/passwd" with this, the text of that error message returned is "incorrect header check".

commite825007007b08aebb0850b430029bc730179e2db authorLeif Warner <abimelech@gmail.com> dateSun 19 Jan 2014, 14:24 (13 years ago) parent0877929
3 files changed+25−5
idris.cabal+1 src/Idris/IBC.hs+9−5 src/Util/Zlib.hs+15
idris.cabal+1
@@ -412,6 +412,7 @@ Library
412412 Util.Pretty
413413 , Util.System
414414 , Util.Net
415+ , Util.Zlib
415416
416417 , Pkg.PParser
417418
src/Idris/IBC.hs+9−5
@@ -21,11 +21,9 @@ import Control.Monad.State.Strict hiding (get, put)
2121import qualified Control.Monad.State.Strict as ST
2222import System.FilePath
2323import System.Directory
24−import Codec.Compression.Zlib
24+import Codec.Compression.Zlib (compress)
25+import Util.Zlib (decompressEither)
2526
26−import Debug.Trace
27−
28−import Paths_idris
2927
3028ibcVersion :: Word8
3129ibcVersion = 54
@@ -74,9 +72,15 @@ loadIBC fp = do iLOG $ "Loading ibc " ++ fp
7472 ibcf <- runIO $ (bdecode fp :: IO IBCFile)
7573 process ibcf fp
7674
75+bencode :: Binary a => FilePath -> a -> IO ()
7776bencode f d = B.writeFile f (compress (encode d))
77+
78+bdecode :: Binary b => FilePath -> IO b
7879bdecode f = do d' <- B.readFile f
79− return (decode (decompress d'))
80+ either
81+ (\(_, e) -> error $ "Invalid / corrupted zip format on " ++ show f ++ ": " ++ e)
82+ (return . decode)
83+ (decompressEither d')
8084
8185writeIBC :: FilePath -> FilePath -> Idris ()
8286writeIBC src f
src/Util/Zlib.hsnew file+15
@@ -0,0 +1,15 @@
1+module Util.Zlib (decompressEither) where
2+
3+-- From http://stackoverflow.com/questions/10043102/how-to-catch-the-decompress-ioerror/10045963#10045963
4+import Codec.Compression.Zlib.Internal
5+import Data.ByteString.Lazy (ByteString, fromChunks)
6+import Control.Arrow (right)
7+
8+decompressEither :: ByteString -> Either (DecompressError, String) ByteString
9+decompressEither = finalise
10+ . foldDecompressStream cons nil err
11+ . decompressWithErrors zlibFormat defaultDecompressParams
12+ where err errorCode errorString = Left (errorCode, errorString)
13+ nil = Right []
14+ cons chunk = right (chunk :)
15+ finalise = right fromChunks