@@ -51,29 +51,36 @@ module Codec.Archive.Tar (
51
51
52
52
-- * Notes
53
53
-- ** Compressed tar archives
54
- -- | Tar files are commonly used in conjunction with gzip compression, as in
55
- -- \" @.tar.gz@\" or \" @.tar.bz2@\" files. This module does not directly
54
+ -- | Tar files are commonly used in conjunction with compression, as in
55
+ -- @.tar.gz@ or @.tar.bz2@ files. This module does not directly
56
56
-- handle compressed tar files however they can be handled easily by
57
57
-- composing functions from this module and the modules
58
- -- @Codec.Compression.GZip@ or @Codec.Compression.BZip@
59
- -- (see @zlib@ or @bzlib@ packages).
58
+ -- [@Codec.Compression.GZip@](https://hackage.haskell.org/package/zlib/docs/Codec-Compression-Zlib.html)
59
+ -- or
60
+ -- [@Codec.Compression.BZip@](https://hackage.haskell.org/package/bzlib-0.5.0.5/docs/Codec-Compression-BZip.html).
60
61
--
61
- -- Creating a compressed \" @.tar.gz@\" file is just a minor variation on the
62
+ -- Creating a compressed @.tar.gz@ file is just a minor variation on the
62
63
-- 'create' function, but where throw compression into the pipeline:
63
64
--
64
- -- > BS.writeFile tar . GZip.compress . Tar.write =<< Tar.pack base dir
65
+ -- > import qualified Data.ByteString.Lazy as BL
66
+ -- > import qualified Codec.Compression.GZip as GZip
67
+ -- >
68
+ -- > BL.writeFile tar . GZip.compress . Tar.write =<< Tar.pack base dir
65
69
--
66
- -- Similarly, extracting a compressed \" @.tar.gz@\" is just a minor variation
70
+ -- Similarly, extracting a compressed @.tar.gz@ is just a minor variation
67
71
-- on the 'extract' function where we use decompression in the pipeline:
68
72
--
69
- -- > Tar.unpack dir . Tar.read . GZip.decompress =<< BS.readFile tar
73
+ -- > import qualified Data.ByteString.Lazy as BL
74
+ -- > import qualified Codec.Compression.Zlib as GZip
75
+ -- >
76
+ -- > Tar.unpack dir . Tar.read . GZip.decompress =<< BL.readFile tar
70
77
--
71
78
72
79
-- ** Security
73
80
-- | This is pretty important. A maliciously constructed tar archives could
74
81
-- contain entries that specify bad file names. It could specify absolute
75
- -- file names like \" @\/etc\/passwd@\" or relative files outside of the
76
- -- archive like \" ..\/..\/..\/something\" . This security problem is commonly
82
+ -- file names like @\/etc\/passwd@ or relative files outside of the
83
+ -- archive like @ ..\/..\/..\/something@ . This security problem is commonly
77
84
-- called a \"directory traversal vulnerability\". Historically, such
78
85
-- vulnerabilities have been common in packages handling tar archives.
79
86
--
@@ -87,8 +94,13 @@ module Codec.Archive.Tar (
87
94
-- 'extract' function does not check for these however if you want to do
88
95
-- that you can use the 'checkTarbomb' function like so:
89
96
--
90
- -- > Tar.unpack dir . Tar.checkTarbomb expectedDir
91
- -- > . Tar.read =<< BS.readFile tar
97
+ -- > import Control.Exception (SomeException(..))
98
+ -- > import Control.Applicative ((<|>))
99
+ -- > import qualified Data.ByteString.Lazy as BL
100
+ -- >
101
+ -- > Tar.unpackAndCheck (\x -> SomeException <$> checkEntryTarbomb expectedDir x
102
+ -- > <|> SomeException <$> checkEntrySecurity x) dir .
103
+ -- > Tar.read =<< BL.readFile tar
92
104
--
93
105
-- In this case extraction will fail if any file is outside of @expectedDir@.
94
106
@@ -163,8 +175,9 @@ import Codec.Archive.Tar.Index (hSeekEndEntryOffset)
163
175
164
176
import Codec.Archive.Tar.Check
165
177
166
- import Control.Exception (Exception , throw , catch )
167
- import qualified Data.ByteString.Lazy as BS
178
+ import Control.Applicative ((<|>) )
179
+ import Control.Exception (Exception , throw , catch , SomeException (.. ))
180
+ import qualified Data.ByteString.Lazy as BL
168
181
import System.IO (withFile , IOMode (.. ))
169
182
import Prelude hiding (read )
170
183
@@ -181,7 +194,9 @@ import Prelude hiding (read)
181
194
-- This is a high level \"all in one\" operation. Since you may need variations
182
195
-- on this function it is instructive to see how it is written. It is just:
183
196
--
184
- -- > BS.writeFile tar . Tar.write =<< Tar.pack base paths
197
+ -- > import qualified Data.ByteString.Lazy as BL
198
+ -- >
199
+ -- > BL.writeFile tar . Tar.write =<< Tar.pack base paths
185
200
--
186
201
-- Notes:
187
202
--
@@ -203,7 +218,7 @@ create :: FilePath -- ^ Path of the \".tar\" file to write.
203
218
-> FilePath -- ^ Base directory
204
219
-> [FilePath ] -- ^ Files and directories to archive, relative to base dir
205
220
-> IO ()
206
- create tar base paths = BS .writeFile tar . write =<< pack base paths
221
+ create tar base paths = BL .writeFile tar . write =<< pack base paths
207
222
208
223
-- | Extract all the files contained in a @\".tar\"@ file.
209
224
--
@@ -217,7 +232,9 @@ create tar base paths = BS.writeFile tar . write =<< pack base paths
217
232
-- This is a high level \"all in one\" operation. Since you may need variations
218
233
-- on this function it is instructive to see how it is written. It is just:
219
234
--
220
- -- > Tar.unpack dir . Tar.read =<< BS.readFile tar
235
+ -- > import qualified Data.ByteString.Lazy as BL
236
+ -- >
237
+ -- > Tar.unpack dir . Tar.read =<< BL.readFile tar
221
238
--
222
239
-- Notes:
223
240
--
@@ -236,7 +253,7 @@ create tar base paths = BS.writeFile tar . write =<< pack base paths
236
253
extract :: FilePath -- ^ Destination directory
237
254
-> FilePath -- ^ Tarball
238
255
-> IO ()
239
- extract dir tar = unpack dir . read =<< BS .readFile tar
256
+ extract dir tar = unpack dir . read =<< BL .readFile tar
240
257
241
258
-- | Append new entries to a @\".tar\"@ file from a directory of files.
242
259
--
@@ -251,4 +268,4 @@ append :: FilePath -- ^ Path of the \".tar\" file to write.
251
268
append tar base paths =
252
269
withFile tar ReadWriteMode $ \ hnd -> do
253
270
_ <- hSeekEndEntryOffset hnd Nothing
254
- BS . hPut hnd . write =<< pack base paths
271
+ BL . hPut hnd . write =<< pack base paths
0 commit comments