@@ -18,11 +18,14 @@ import Distribution.Server.Framework.BlobStorage (BlobId)
18
18
import qualified Distribution.Server.Framework.BlobStorage as BlobStorage
19
19
import qualified Distribution.Server.Util.ServeTarball as ServerTarball
20
20
import Data.TarIndex (TarIndex )
21
+ import qualified Codec.Archive.Tar as Tar
22
+ import qualified Codec.Archive.Tar.Check as Tar
21
23
22
24
import Distribution.Text
23
25
import Distribution.Package
24
26
import Distribution.Version (Version (.. ))
25
27
28
+ import qualified Data.ByteString.Lazy as BSL
26
29
import qualified Data.Map as Map
27
30
import Data.Function (fix )
28
31
@@ -202,11 +205,13 @@ documentationFeature name
202
205
-- * Drop the index for the old tar-file
203
206
-- * Link the new documentation to the package
204
207
fileContents <- expectUncompressedTarball
205
- blob <- liftIO $ BlobStorage. add store fileContents
206
- -- TODO: validate the tarball here.
207
- -- Check all files in the tarball are under the dir foo-1.0-docs/
208
- void $ updateState documentationState $ InsertDocumentation pkgid blob
209
- noContent (toResponse () )
208
+ mres <- liftIO $ BlobStorage. addWith store fileContents
209
+ (\ content -> return (checkDocTarball pkgid content))
210
+ case mres of
211
+ Left err -> errBadRequest " Invalid documentation tarball" [MText err]
212
+ Right (() , blobid) -> do
213
+ updateState documentationState $ InsertDocumentation pkgid blobid
214
+ noContent (toResponse () )
210
215
211
216
{-
212
217
To upload documentation using curl:
@@ -257,6 +262,18 @@ documentationFeature name
257
262
index <- liftIO $ cachedTarIndex blob
258
263
func pkgid blob index
259
264
265
+ -- Check the tar file is well formed and all files are within foo-1.0-docs/
266
+ checkDocTarball :: PackageId -> BSL. ByteString -> Either String ()
267
+ checkDocTarball pkgid =
268
+ checkEntries
269
+ . fmapErr (either id show ) . Tar. checkTarbomb (display pkgid ++ " -docs" )
270
+ . fmapErr (either id show ) . Tar. checkSecurity
271
+ . fmapErr (either id show ) . Tar. checkPortability
272
+ . fmapErr show . Tar. read
273
+ where
274
+ fmapErr f = Tar. foldEntries Tar. Next Tar. Done (Tar. Fail . f)
275
+ checkEntries = Tar. foldEntries (\ _ remainder -> remainder) (Right () ) Left
276
+
260
277
{- -----------------------------------------------------------------------------
261
278
Auxiliary
262
279
------------------------------------------------------------------------------}
0 commit comments