disregard tar pax headers

This commit is contained in:
jacob 2024-04-03 22:35:50 -05:00
parent 9a8b712f98
commit 100fdd264d

View File

@ -19,8 +19,10 @@
* 'A'-'Z' Vendor specific extensions(POSIX.1 - 1988) * 'A'-'Z' Vendor specific extensions(POSIX.1 - 1988)
*/ */
#define TAR_TYPE_FILE '0' #define TAR_TYPE_FILE '0'
#define TAR_TYPE_DIRECTORY '5' #define TAR_TYPE_DIRECTORY '5'
#define TAR_TYPE_PAX_HEADER_X 'x'
#define TAR_TYPE_PAX_HEADER_G 'g'
struct tar_header { struct tar_header {
/* Pre-posix */ /* Pre-posix */
@ -70,31 +72,25 @@ struct tar_archive tar_parse(struct arena *arena, struct buffer data, struct str
struct tar_archive archive = { 0 }; struct tar_archive archive = { 0 };
struct byte_reader br = br_create_from_buffer(data); struct byte_reader br = br_create_from_buffer(data);
/* NOTE: For some reason the bottom of the tar is filled with 0s.
* Don't read when bytes left <= 1024. */
u64 num_files = 0; u64 num_files = 0;
while (br_bytes_left(&br) > 1024) { while (br_bytes_left(&br) > 1024) {
struct tar_header *header = br_read_raw(&br, sizeof(*header)); struct tar_header header = { 0 };
if (!header) { br_read_to_struct(&br, &header);
/* Overflow */
ASSERT(false);
continue;
}
if (!string_eq(STRING_FROM_ARRAY(header->ustar_indicator), STR("ustar\0"))) { if (!string_eq(STRING_FROM_ARRAY(header.ustar_indicator), STR("ustar\0"))) {
/* Invalid header */ /* Invalid header */
ASSERT(false); ASSERT(false);
continue; continue;
} }
if (header->file_name_prefix[0] != 0) { if (header.file_name_prefix[0] != 0) {
/* Header file name prefix not supported */ /* Header file name prefix not supported */
ASSERT(false); ASSERT(false);
continue; continue;
} }
struct string file_size_oct_str = { .len = 11, .text = header->file_size }; struct string file_size_oct_str = { .len = 11, .text = header.file_size };
u64 file_size = str_oct_to_u64(file_size_oct_str); u64 file_size = str_oct_to_u64(file_size_oct_str);
struct buffer file_data = { struct buffer file_data = {
@ -106,14 +102,15 @@ struct tar_archive tar_parse(struct arena *arena, struct buffer data, struct str
u64 remaining = (512 - (file_size % 512)) % 512; u64 remaining = (512 - (file_size % 512)) % 512;
br_seek(&br, remaining); br_seek(&br, remaining);
b32 is_dir = header->file_type == TAR_TYPE_DIRECTORY; b32 is_dir = header.file_type == TAR_TYPE_DIRECTORY;
if (!is_dir && header->file_type != TAR_TYPE_FILE) { if (!is_dir && header.file_type != TAR_TYPE_FILE) {
/* Unsupported type */ /* Unsupported type */
ASSERT(false); ASSERT(header.file_type == TAR_TYPE_PAX_HEADER_X ||
header.file_type == TAR_TYPE_PAX_HEADER_G);
continue; continue;
} }
struct string file_name_cstr = string_from_cstr((char *)header->file_name); struct string file_name_cstr = string_from_cstr((char *)header.file_name);
if (file_name_cstr.len >= 2) { if (file_name_cstr.len >= 2) {
/* Chop off './' prefix */ /* Chop off './' prefix */
file_name_cstr.len -= 2; file_name_cstr.len -= 2;