Skip to content

Commit 6b71d16

Browse files
Bodigrimpeterbecich
authored andcommitted
Migrate to tar-0.6
1 parent e6d4cfe commit 6b71d16

File tree

9 files changed

+61
-41
lines changed

9 files changed

+61
-41
lines changed

flake.nix

+2-2
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@
3232
ap-normalize.check = false;
3333
extensions.jailbreak = true;
3434
# https://community.flake.parts/haskell-flake/dependency#nixpkgs
35-
# tar = { super, ... }:
36-
# { custom = _: super.tar_0_6_0_0; };
35+
tar = { super, ... }:
36+
{ custom = _: super.tar_0_6_0_0; };
3737
# tasty = { super, ... }:
3838
# { custom = _: super.tasty_1_5; };
3939
};

hackage-server.cabal

+1-1
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ common defaults
157157
, network-bsd ^>= 2.8
158158
, network-uri ^>= 2.6
159159
, parsec ^>= 3.1.13
160-
, tar ^>= 0.5
160+
, tar ^>= 0.6
161161
, unordered-containers ^>= 0.2.10
162162
, vector ^>= 0.12 || ^>= 0.13.0.0
163163
, zlib ^>= 0.6.2

src/Data/TarIndex.hs

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ module Data.TarIndex (
1818
import Data.SafeCopy (base, deriveSafeCopy)
1919
import Data.Typeable (Typeable)
2020

21-
import Codec.Archive.Tar (Entry(..), EntryContent(..), Entries(..), entryPath)
21+
import Codec.Archive.Tar (Entry, GenEntry(..), GenEntryContent(..), Entries, GenEntries(..), entryPath)
2222
import qualified Data.StringTable as StringTable
2323
import Data.StringTable (StringTable)
2424
import qualified Data.IntTrie as IntTrie

src/Distribution/Client/Index.hs

-3
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,6 @@ module Distribution.Client.Index (
1616
) where
1717

1818
import qualified Codec.Archive.Tar as Tar
19-
( read, Entries(..) )
20-
import qualified Codec.Archive.Tar.Entry as Tar
21-
( Entry(..), entryPath )
2219

2320
import Distribution.Package
2421
import Distribution.Text

src/Distribution/Server/Features/Documentation.hs

+9-5
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Distribution.Server.Features.BuildReports.BuildReport (PkgDetails(..), Bu
2727
import Data.TarIndex (TarIndex)
2828
import qualified Codec.Archive.Tar as Tar
2929
import qualified Codec.Archive.Tar.Check as Tar
30+
import qualified Codec.Archive.Tar.Entry as Tar
3031

3132
import Distribution.Text
3233
import Distribution.Package
@@ -448,17 +449,20 @@ documentationFeature name
448449
checkDocTarball :: PackageId -> BSL.ByteString -> Either String ()
449450
checkDocTarball pkgid =
450451
checkEntries
451-
. fmapErr (either id show) . Tar.checkTarbomb (display pkgid ++ "-docs")
452-
. fmapErr (either id show) . Tar.checkSecurity
453-
. fmapErr (either id show) . Tar.checkPortability
452+
. fmapErr (either id show) . chainChecks (Tar.checkEntryTarbomb (display pkgid ++ "-docs"))
453+
. fmapErr (either id show) . chainChecks Tar.checkEntrySecurity
454+
. fmapErr (either id show) . chainChecks Tar.checkEntryPortability
455+
. fmapErr (either id show) . Tar.decodeLongNames
454456
. fmapErr show . Tar.read
455457
where
456458
fmapErr f = Tar.foldEntries Tar.Next Tar.Done (Tar.Fail . f)
459+
chainChecks check = Tar.mapEntries (\entry -> maybe (Right entry) Left (check entry))
460+
457461
checkEntries = Tar.foldEntries checkEntry (Right ()) Left
458462

459463
checkEntry entry remainder
460-
| Tar.entryPath entry == docMetaPath = checkDocMeta entry remainder
461-
| otherwise = remainder
464+
| Tar.entryTarPath entry == docMetaPath = checkDocMeta entry remainder
465+
| otherwise = remainder
462466

463467
checkDocMeta entry remainder =
464468
case Tar.entryContent entry of

src/Distribution/Server/Packages/Index.hs

-2
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ module Distribution.Server.Packages.Index (
1010
) where
1111

1212
import qualified Codec.Archive.Tar as Tar
13-
( write )
1413
import qualified Codec.Archive.Tar.Entry as Tar
15-
( Entry(..), fileEntry, toTarPath, Ownership(..) )
1614
import Distribution.Server.Packages.PackageIndex (PackageIndex)
1715
import qualified Distribution.Server.Packages.PackageIndex as PackageIndex
1816
import Distribution.Server.Framework.MemSize

src/Distribution/Server/Packages/Unpack.hs

+36-20
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ tarPackageChecks lax now tarGzFile contents = do
138138
expectedDir = display pkgid
139139

140140
selectEntry entry = case Tar.entryContent entry of
141-
Tar.NormalFile bs _ -> Just (normalise (Tar.entryPath entry), NormalFile bs)
142-
Tar.Directory -> Just (normalise (Tar.entryPath entry), Directory)
143-
Tar.SymbolicLink linkTarget -> Just (normalise (Tar.entryPath entry), Link (Tar.fromLinkTarget linkTarget))
144-
Tar.HardLink linkTarget -> Just (normalise (Tar.entryPath entry), Link (Tar.fromLinkTarget linkTarget))
141+
Tar.NormalFile bs _ -> Just (normalise (Tar.entryTarPath entry), NormalFile bs)
142+
Tar.Directory -> Just (normalise (Tar.entryTarPath entry), Directory)
143+
Tar.SymbolicLink linkTarget -> Just (normalise (Tar.entryTarPath entry), Link linkTarget)
144+
Tar.HardLink linkTarget -> Just (normalise (Tar.entryTarPath entry), Link linkTarget)
145145
_ -> Nothing
146146
files <- selectEntries explainTarError selectEntry entries
147147
return (pkgid, files)
@@ -331,14 +331,14 @@ warn msg = tell [msg]
331331
runUploadMonad :: UploadMonad a -> Either String (a, [String])
332332
runUploadMonad (UploadMonad m) = runIdentity . runExceptT . runWriterT $ m
333333

334-
selectEntries :: forall err a.
334+
selectEntries :: forall tarPath linkTarget err a.
335335
(err -> String)
336-
-> (Tar.Entry -> Maybe a)
337-
-> Tar.Entries err
336+
-> (Tar.GenEntry tarPath linkTarget -> Maybe a)
337+
-> Tar.GenEntries tarPath linkTarget err
338338
-> UploadMonad [a]
339339
selectEntries formatErr select = extract []
340340
where
341-
extract :: [a] -> Tar.Entries err -> UploadMonad [a]
341+
extract :: [a] -> Tar.GenEntries tarPath linkTarget err -> UploadMonad [a]
342342
extract _ (Tar.Fail err) = throwError (formatErr err)
343343
extract selected Tar.Done = return selected
344344
extract selected (Tar.Next entry entries) =
@@ -352,18 +352,20 @@ data CombinedTarErrs =
352352
| TarBombError FilePath FilePath
353353
| FutureTimeError FilePath UTCTime UTCTime
354354
| PermissionsError FilePath Tar.Permissions
355+
| LongNamesError Tar.DecodeLongNamesError
355356

356357
tarballChecks :: Bool -> UTCTime -> FilePath
357358
-> Tar.Entries Tar.FormatError
358-
-> Tar.Entries CombinedTarErrs
359+
-> Tar.GenEntries FilePath FilePath CombinedTarErrs
359360
tarballChecks lax now expectedDir =
360361
(if not lax then checkFutureTimes now else id)
361362
. checkTarbomb expectedDir
362363
. (if not lax then checkUselessPermissions else id)
363364
. (if lax then ignoreShortTrailer
364365
else fmapTarError (either id PortabilityError)
365-
. Tar.checkPortability)
366-
. fmapTarError FormatError
366+
. Tar.mapEntries (\entry -> maybe (Right entry) Left (Tar.checkEntryPortability entry)))
367+
. fmapTarError (either FormatError LongNamesError)
368+
. Tar.decodeLongNames
367369
where
368370
ignoreShortTrailer =
369371
Tar.foldEntries Tar.Next Tar.Done
@@ -373,32 +375,39 @@ tarballChecks lax now expectedDir =
373375
fmapTarError f = Tar.foldEntries Tar.Next Tar.Done (Tar.Fail . f)
374376

375377
checkFutureTimes :: UTCTime
376-
-> Tar.Entries CombinedTarErrs
377-
-> Tar.Entries CombinedTarErrs
378+
-> Tar.GenEntries FilePath linkTarget CombinedTarErrs
379+
-> Tar.GenEntries FilePath linkTarget CombinedTarErrs
378380
checkFutureTimes now =
379381
checkEntries checkEntry
380382
where
381383
-- Allow 30s for client clock skew
382384
now' = addUTCTime 30 now
385+
386+
checkEntry :: Tar.GenEntry FilePath linkTarget -> Maybe CombinedTarErrs
383387
checkEntry entry
384388
| entryUTCTime > now'
385389
= Just (FutureTimeError posixPath entryUTCTime now')
386390
where
387391
entryUTCTime = posixSecondsToUTCTime (realToFrac (Tar.entryTime entry))
388-
posixPath = Tar.fromTarPathToPosixPath (Tar.entryTarPath entry)
392+
posixPath = Tar.entryTarPath entry
389393

390394
checkEntry _ = Nothing
391395

392-
checkTarbomb :: FilePath -> Tar.Entries CombinedTarErrs -> Tar.Entries CombinedTarErrs
396+
checkTarbomb
397+
:: FilePath
398+
-> Tar.GenEntries FilePath linkTarget CombinedTarErrs
399+
-> Tar.GenEntries FilePath linkTarget CombinedTarErrs
393400
checkTarbomb expectedTopDir =
394401
checkEntries checkEntry
395402
where
396403
checkEntry entry =
397-
case splitDirectories (Tar.entryPath entry) of
404+
case splitDirectories (Tar.entryTarPath entry) of
398405
(topDir:_) | topDir == expectedTopDir -> Nothing
399-
_ -> Just $ TarBombError (Tar.entryPath entry) expectedTopDir
406+
_ -> Just $ TarBombError (Tar.entryTarPath entry) expectedTopDir
400407

401-
checkUselessPermissions :: Tar.Entries CombinedTarErrs -> Tar.Entries CombinedTarErrs
408+
checkUselessPermissions
409+
:: Tar.GenEntries FilePath linkTarget CombinedTarErrs
410+
-> Tar.GenEntries FilePath linkTarget CombinedTarErrs
402411
checkUselessPermissions =
403412
checkEntries checkEntry
404413
where
@@ -410,11 +419,14 @@ checkUselessPermissions =
410419
where
411420
checkPermissions expected actual =
412421
if expected .&. actual /= expected
413-
then Just $ PermissionsError (Tar.entryPath entry) actual
422+
then Just $ PermissionsError (Tar.entryTarPath entry) actual
414423
else Nothing
415424

416425

417-
checkEntries :: (Tar.Entry -> Maybe e) -> Tar.Entries e -> Tar.Entries e
426+
checkEntries
427+
:: (Tar.GenEntry tarPath linkTarget -> Maybe e)
428+
-> Tar.GenEntries tarPath linkTarget e
429+
-> Tar.GenEntries tarPath linkTarget e
418430
checkEntries checkEntry =
419431
Tar.foldEntries (\entry rest -> maybe (Tar.Next entry rest) Tar.Fail
420432
(checkEntry entry))
@@ -468,6 +480,10 @@ explainTarError (PermissionsError entryname mode) =
468480
where
469481
showMode :: Tar.Permissions -> String
470482
showMode m = printf "%.3o" (fromIntegral m :: Int)
483+
explainTarError (LongNamesError err) =
484+
"There is an error in the format of entries with long names in the tar file: " ++ show err
485+
++ ". Check that it is a valid tar file (e.g. 'tar -xtf thefile.tar'). "
486+
++ "You may need to re-create the package tarball and try again."
471487

472488
quote :: String -> String
473489
quote s = "'" ++ s ++ "'"

tests/Distribution/Server/Packages/UnpackTest.hs

+6-2
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,14 @@ deriving instance Eq CombinedTarErrs
1919

2020
-- | Test that check permissions does the right thing
2121
testPermissions :: FilePath -- ^ .tar.gz file to test
22-
-> (Tar.Entry -> Maybe CombinedTarErrs) -- ^ Converter to create errors if necessary
22+
-> (Tar.GenEntry FilePath FilePath -> Maybe CombinedTarErrs) -- ^ Converter to create errors if necessary
2323
-> Assertion
2424
testPermissions tarPath mangler = do
2525
entries <- Tar.read . GZip.decompress <$> BL.readFile tarPath
26-
let mappedEntries = Tar.foldEntries Tar.Next Tar.Done (Tar.Fail . FormatError) entries
26+
let mappedEntries = Tar.foldEntries
27+
Tar.Next
28+
Tar.Done
29+
(Tar.Fail . either FormatError LongNamesError)
30+
(Tar.decodeLongNames entries)
2731
when (checkEntries mangler mappedEntries /= checkUselessPermissions mappedEntries) $
2832
assertFailure ("Permissions check did not match expected for: " ++ tarPath)

tests/PackageTestMain.hs

+6-5
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Data.Time (getCurrentTime)
99
import Data.List (isInfixOf)
1010

1111
import qualified Codec.Archive.Tar as Tar
12+
import qualified Codec.Archive.Tar.Entry as Tar
1213
import qualified Codec.Compression.GZip as GZip
1314

1415
import Distribution.Server.Packages.Unpack
@@ -42,19 +43,19 @@ tarPermissions =
4243
(testPermissions "tests/permissions-tarballs/bad-dir-perms.tar.gz" badDirMangler)
4344
]
4445

45-
goodMangler :: (Tar.Entry -> Maybe CombinedTarErrs)
46+
goodMangler :: (Tar.GenEntry tarPath linkTarget -> Maybe CombinedTarErrs)
4647
goodMangler = const Nothing
4748

48-
badFileMangler :: (Tar.Entry -> Maybe CombinedTarErrs)
49+
badFileMangler :: (Tar.GenEntry FilePath linkTarget -> Maybe CombinedTarErrs)
4950
badFileMangler entry =
5051
case Tar.entryContent entry of
51-
(Tar.NormalFile _ _) -> Just $ PermissionsError (Tar.entryPath entry) 0o600
52+
(Tar.NormalFile _ _) -> Just $ PermissionsError (Tar.entryTarPath entry) 0o600
5253
_ -> Nothing
5354

54-
badDirMangler :: (Tar.Entry -> Maybe CombinedTarErrs)
55+
badDirMangler :: (Tar.GenEntry FilePath linkTarget -> Maybe CombinedTarErrs)
5556
badDirMangler entry =
5657
case Tar.entryContent entry of
57-
Tar.Directory -> Just $ PermissionsError (Tar.entryPath entry) 0o700
58+
Tar.Directory -> Just $ PermissionsError (Tar.entryTarPath entry) 0o700
5859
_ -> Nothing
5960

6061
---------------------------------------------------------------------------

0 commit comments

Comments
 (0)