From 87da3e00042fab02f9e9129ce18efc6b146d4f7e Mon Sep 17 00:00:00 2001 From: Tim Schumacher Date: Mon, 6 Jun 2022 18:17:45 +0200 Subject: [PATCH] tar: Implement support for GNU longname headers --- Userland/Libraries/LibArchive/Tar.h | 5 ++++- Userland/Utilities/tar.cpp | 23 +++++++++++++++++++++-- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Userland/Libraries/LibArchive/Tar.h b/Userland/Libraries/LibArchive/Tar.h index 37f591ddb3..7474c9cb2a 100644 --- a/Userland/Libraries/LibArchive/Tar.h +++ b/Userland/Libraries/LibArchive/Tar.h @@ -26,7 +26,10 @@ enum class TarFileType : char { FIFO = '6', ContiguousFile = '7', GlobalExtendedHeader = 'g', - ExtendedHeader = 'x' + ExtendedHeader = 'x', + + // GNU extensions + LongName = 'L', }; constexpr size_t block_size = 512; diff --git a/Userland/Utilities/tar.cpp b/Userland/Utilities/tar.cpp index dcc261208e..7d65ddb5c6 100644 --- a/Userland/Utilities/tar.cpp +++ b/Userland/Utilities/tar.cpp @@ -125,6 +125,27 @@ ErrorOr serenity_main(Main::Arguments arguments) continue; } + Archive::TarFileStream file_stream = tar_stream.file_contents(); + + // Handle other header types that don't just have an effect on extraction. + switch (header.type_flag()) { + case Archive::TarFileType::LongName: { + StringBuilder long_name; + + Array buffer; + size_t bytes_read; + + while ((bytes_read = file_stream.read(buffer)) > 0) + long_name.append(reinterpret_cast(buffer.data()), bytes_read); + + local_overrides.set("path", long_name.to_string()); + continue; + } + default: + // None of the relevant headers, so continue as normal. + break; + } + LexicalPath path = LexicalPath(header.filename()); if (!header.prefix().is_empty()) path = path.prepend(header.prefix()); @@ -134,8 +155,6 @@ ErrorOr serenity_main(Main::Arguments arguments) outln("{}", filename); if (extract) { - Archive::TarFileStream file_stream = tar_stream.file_contents(); - String absolute_path = Core::File::absolute_path(filename); auto parent_path = LexicalPath(absolute_path).parent();