-
Notifications
You must be signed in to change notification settings - Fork 37
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can't extract tar file: inappropriate type (Is a directory) #27
Comments
Here is the "History.md" file, this is the Tar Entry just before the above failing one: Entry
{ entryTarPath = "././@LongLink"
, entryContent = OtherEntryType 'L' "node-v9.3.0-linux-x64/lib/node_modules/npm/node_modules/readable-stream/node_modules/util-deprecate/History.md\NUL" 111
, entryPermissions = 0
, entryOwnership = Ownership
{ ownerName = "root"
, groupName = "root"
, ownerId = 0
, groupId = 0
}
, entryTime = 0
, entryFormat = GnuFormat
} |
I have some code that can extract PAX tar archives pretty well (note: these are different from GNU tar archives that I originally reported) WARNING: This might have security issues (overwriting files outside the destination directory) unpackTar :: FilePath -> Tar.Entries Tar.FormatError -> IO ()
unpackTar dir x =
(loop Nothing Nothing . (checkEntries checkEntrySecurity)) x
where
loop :: (Maybe FilePath) -> (Maybe FilePath) -> Tar.Entries (Either Tar.FormatError Tar.FileNameError) -> IO ()
loop _ _ Tar.Done = return ()
loop _ _ (Tar.Fail e) = either throwIO throwIO e
loop pathOverride linkOverride (Tar.Next e es) = case Tar.entryContent e of
Tar.Directory -> loop Nothing Nothing es
Tar.NormalFile lbs _ -> do
let fp = dir </> fromMaybe (Tar.entryPath e) pathOverride
saveFile fp lbs (Tar.entryPermissions e)
loop Nothing Nothing es
Tar.SymbolicLink target -> do
let fp = dir </> fromMaybe (Tar.entryPath e) pathOverride
let link = fromMaybe (Tar.fromLinkTarget target) linkOverride
saveSymbolicLink fp link
loop Nothing Nothing es
Tar.OtherEntryType 'x' pax _ -> do
case parsePaxExtended pax of
Left err -> fail err
Right overrides -> do
let pathOverride' = lookup (L.pack "path") overrides
linkOverride' = lookup (L.pack "linkpath") overrides
loop (fmap L.unpack pathOverride') (fmap L.unpack linkOverride') es
_ -> do
loop Nothing Nothing es
saveFile :: FilePath -> L.ByteString -> Tar.Permissions -> IO ()
saveFile fp lbs perms = do
createDirectoryIfMissing True $ F.takeDirectory fp
runConduitRes $ mapM_ yield (L.toChunks lbs) .| sinkFile fp
when ((perms .&. (ownerExecuteMode .|. groupExecuteMode .|. otherExecuteMode)) /= 0 ) $ do
stat <- getFileStatus fp
setFileMode fp (fileMode stat .|. (ownerExecuteMode .|. groupExecuteMode .|. otherExecuteMode))
saveSymbolicLink :: FilePath -> FilePath -> IO ()
saveSymbolicLink fp target = do
createDirectoryIfMissing True $ F.takeDirectory fp
createSymbolicLink target fp
checkEntries :: (Tar.Entry -> Maybe e') -> Tar.Entries e -> Tar.Entries (Either e e')
checkEntries checkEntry =
Tar.mapEntries (\entry -> maybe (Right entry) Left (checkEntry entry))
checkEntrySecurity :: Tar.Entry -> Maybe Tar.FileNameError
checkEntrySecurity _ = Nothing
parsePaxExtended :: L.ByteString -> Either String [(L.ByteString, L.ByteString)]
parsePaxExtended = next []
where
next :: [(L.ByteString, L.ByteString)] -> L.ByteString -> Either String [(L.ByteString, L.ByteString)]
next accum str =
let (lenStr, _) = L.break (==' ') str
in case L.readInt lenStr of
Nothing -> Left "Invalid PAX"
Just (len, _) ->
let (seg, rest) = L.splitAt (fromIntegral len) str
seg' = L.drop 1 (L.dropWhile (/=' ') seg)
seg'' = L.take (L.length seg' - 1) seg'
(key, val) = L.break (=='=') seg''
newPair = (key, L.drop 1 val)
in if L.null rest then Right (newPair:accum)
else next (newPair:accum) rest |
#50 seems related |
It works better wrt long file names after #77, but still fails later on:
|
@Bodigrim I presume it works now? |
@hasufell yes, it works. |
I found a .tar file that this library chokes on: https://nodejs.org/dist/v8.9.3/node-v8.9.3-linux-x64.tar.xz
I extracted it with the "unxz" program and got "node-v8.9.3-linux-x64.tar". This file extracts just fine using the regular "tar" program. But when using this library (
extract
function) I get this error:I managed to print the failing Tar Entry:
Looking at the "entryContent", the "entryTarPath" is incorrect, and is supposed to be the file:
node-v8.9.3-linux-x64/lib/node_modules/npm/node_modules/readable-stream/node_modules/util-deprecate/History.md
The text was updated successfully, but these errors were encountered: