diff --git a/Userland/Libraries/LibArchive/Tar.cpp b/Userland/Libraries/LibArchive/Tar.cpp index 41b69dab59..a5758d93af 100644 --- a/Userland/Libraries/LibArchive/Tar.cpp +++ b/Userland/Libraries/LibArchive/Tar.cpp @@ -35,4 +35,22 @@ bool TarFileHeader::content_is_like_extended_header() const return type_flag() == TarFileType::ExtendedHeader || type_flag() == TarFileType::GlobalExtendedHeader; } +void TarFileHeader::set_filename_and_prefix(StringView filename) +{ + // FIXME: Add support for extended tar headers for longer filenames. + VERIFY(filename.length() <= sizeof(m_filename) + sizeof(m_prefix)); + + if (filename.length() <= sizeof(m_filename)) { + set_prefix(""sv); + set_filename(filename); + return; + } + + Optional slash = filename.find('/', filename.length() - sizeof(m_filename)); + + VERIFY(slash.has_value()); + set_prefix(filename.substring_view(0, slash.value() + 1)); + set_filename(filename.substring_view(slash.value() + 1)); +} + } diff --git a/Userland/Libraries/LibArchive/Tar.h b/Userland/Libraries/LibArchive/Tar.h index 50cf04bb52..d3e9973e16 100644 --- a/Userland/Libraries/LibArchive/Tar.h +++ b/Userland/Libraries/LibArchive/Tar.h @@ -130,6 +130,8 @@ public: bool content_is_like_extended_header() const; + void set_filename_and_prefix(StringView filename); + private: char m_filename[100] { 0 }; char m_mode[8] { 0 }; diff --git a/Userland/Libraries/LibArchive/TarStream.cpp b/Userland/Libraries/LibArchive/TarStream.cpp index 80945af341..bd45ab67b0 100644 --- a/Userland/Libraries/LibArchive/TarStream.cpp +++ b/Userland/Libraries/LibArchive/TarStream.cpp @@ -133,7 +133,7 @@ void TarOutputStream::add_directory(String const& path, mode_t mode) VERIFY(!m_finished); TarFileHeader header {}; header.set_size(0); - header.set_filename(String::formatted("{}/", path)); // Old tar implementations assume directory names end with a / + header.set_filename_and_prefix(String::formatted("{}/", path)); // Old tar implementations assume directory names end with a / header.set_type_flag(TarFileType::Directory); header.set_mode(mode); header.set_magic(gnu_magic); @@ -149,7 +149,7 @@ void TarOutputStream::add_file(String const& path, mode_t mode, ReadonlyBytes by VERIFY(!m_finished); TarFileHeader header {}; header.set_size(bytes.size()); - header.set_filename(path); + header.set_filename_and_prefix(path); header.set_type_flag(TarFileType::NormalFile); header.set_mode(mode); header.set_magic(gnu_magic);