mirror of
https://github.com/RGBCube/serenity
synced 2025-05-28 19:55:10 +00:00

Previously this was handled implicitly, as our implementation of Tar would just stop processing input as soon as it found something invalid. However, since we now error out as soon as something is found to be wrong, we require proper handling for zero blocks, which aren't actually fatal.
66 lines
1.9 KiB
C++
66 lines
1.9 KiB
C++
/*
|
|
* Copyright (c) 2020, Peter Elliott <pelliott@serenityos.org>
|
|
* Copyright (c) 2021, Idan Horowitz <idan.horowitz@serenityos.org>
|
|
*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*/
|
|
|
|
#include "Tar.h"
|
|
|
|
namespace Archive {
|
|
|
|
unsigned TarFileHeader::expected_checksum() const
|
|
{
|
|
auto checksum = 0u;
|
|
u8 const* u8_this = reinterpret_cast<u8 const*>(this);
|
|
u8 const* u8_m_checksum = reinterpret_cast<u8 const*>(&m_checksum);
|
|
for (auto i = 0u; i < sizeof(TarFileHeader); ++i) {
|
|
if (u8_this + i >= u8_m_checksum && u8_this + i < u8_m_checksum + sizeof(m_checksum)) {
|
|
checksum += ' ';
|
|
} else {
|
|
checksum += u8_this[i];
|
|
}
|
|
}
|
|
return checksum;
|
|
}
|
|
|
|
void TarFileHeader::calculate_checksum()
|
|
{
|
|
memset(m_checksum, ' ', sizeof(m_checksum));
|
|
VERIFY(String::formatted("{:06o}", expected_checksum()).copy_characters_to_buffer(m_checksum, sizeof(m_checksum)));
|
|
}
|
|
|
|
bool TarFileHeader::is_zero_block() const
|
|
{
|
|
u8 const* buffer = reinterpret_cast<u8 const*>(this);
|
|
for (size_t i = 0; i < sizeof(TarFileHeader); ++i) {
|
|
if (buffer[i] != 0)
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
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<size_t> 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));
|
|
}
|
|
|
|
}
|