Skip to content

Commit 7adb980

Browse files
committed
Rework extension for files over 8Gb to be compatible with tar-0.5
1 parent fb7a657 commit 7adb980

File tree

4 files changed

+13
-5
lines changed

4 files changed

+13
-5
lines changed

Codec/Archive/Tar/Write.hs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,13 @@ write es = LBS.concat $ map putEntry es ++ [LBS.replicate (512*2) 0]
3737

3838
putEntry :: Entry -> LBS.ByteString
3939
putEntry entry = case entryContent entry of
40-
NormalFile content size -> LBS.concat [ header, content, padding size ]
40+
NormalFile content size
41+
-- size field is 12 bytes long, so in octal format (see 'putOct')
42+
-- it can hold numbers up to 8Gb
43+
| size >= 1 `shiftL` (3 * (12 -1))
44+
, entryFormat entry == V7Format
45+
-> error "putEntry: support for files over 8Gb is a Ustar extension"
46+
| otherwise -> LBS.concat [ header, content, padding size ]
4147
OtherEntryType 'K' _ _
4248
| entryFormat entry /= GnuFormat -> error "putEntry: long symlink support is a GNU extension"
4349
OtherEntryType 'L' _ _
@@ -102,10 +108,12 @@ putHeaderNoChkSum Entry {
102108
, replicate 12 '\NUL'
103109
]
104110
where
105-
numField :: (Integral a, Bits a, Show a) => FieldWidth -> a -> String
106-
numField = case format of
107-
V7Format -> putOct
108-
_other -> putLarge
111+
numField :: FieldWidth -> Int64 -> String
112+
numField w n
113+
| n >= 0 && n < 1 `shiftL` (3 * (w - 1))
114+
= putOct w n
115+
| otherwise
116+
= putLarge w n
109117

110118
(typeCode, contentSize, linkTarget,
111119
deviceMajor, deviceMinor) = case content of

test/data/long-filepath.tar

0 Bytes
Binary file not shown.

test/data/long-symlink.tar

0 Bytes
Binary file not shown.

test/data/symlink.tar

0 Bytes
Binary file not shown.

0 commit comments

Comments
 (0)