char *groupname;
uint64_t file_size;
/// xxxx xxx1 - is invalid.
+ /// xxxx xx1x - white/black-list allowed.
int_fast8_t other_flags;
} SDArchiverInternalFileInfo;
__attribute__((cleanup(simple_archiver_hash_map_free)))
SDArchiverHashMap *working_files_map = NULL;
- if (state && state->parsed->working_files &&
+ if (do_extract && state && state->parsed->working_files &&
state->parsed->working_files[0] != NULL) {
working_files_map = simple_archiver_hash_map_init();
for (char **iter = state->parsed->working_files; *iter != NULL; ++iter) {
__attribute__((cleanup(simple_archiver_list_free)))
SDArchiverLinkedList *links_list =
- state && state->parsed && state->parsed->flags & 0x80
+ do_extract && state && state->parsed && state->parsed->flags & 0x80
? NULL
: simple_archiver_list_init();
__attribute__((cleanup(simple_archiver_hash_map_free)))
SDArchiverHashMap *files_map =
- state && state->parsed && state->parsed->flags & 0x80
+ do_extract && state && state->parsed && state->parsed->flags & 0x80
? NULL
: simple_archiver_hash_map_init();
if (is_sig_int_occurred) {
return SDAS_SIGINT;
}
- fprintf(stderr, "SYMLINK %3" PRIu32 " of %3" PRIu32 "\n", idx + 1, count);
if (fread(buf, 1, 2, in_f) != 2) {
return SDAS_INVALID_FILE;
}
const uint_fast8_t is_invalid = (buf[1] & 4) ? 1 : 0;
const uint_fast8_t points_to_outside = (buf[1] & 8) ? 1 : 0;
- if (is_invalid) {
- fprintf(stderr, " WARNING: This symlink entry was marked invalid!\n");
- }
-
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
}
link_name[link_name_length] = 0;
- if (!do_extract) {
+ const uint_fast8_t lists_allowed = simple_archiver_helper_string_allowed_lists(
+ link_name,
+ state->parsed->whitelist_contains,
+ state->parsed->whitelist_begins,
+ state->parsed->whitelist_ends,
+ state->parsed->blacklist_contains,
+ state->parsed->blacklist_begins,
+ state->parsed->blacklist_ends);
+
+ if (!do_extract && lists_allowed) {
+ fprintf(stderr, "SYMLINK %3" PRIu32 " of %3" PRIu32 "\n", idx + 1, count);
+ if (is_invalid) {
+ fprintf(stderr, " WARNING: This symlink entry was marked invalid!\n");
+ }
fprintf(stderr, " Link name: %s\n", link_name);
if (absolute_preferred) {
fprintf(stderr, " Absolute path preferred.\n");
print_permissions(permissions);
fprintf(stderr, "\n");
#endif
+ } else if (do_extract && lists_allowed) {
+ if (is_invalid) {
+ fprintf(stderr, " WARNING: This symlink entry was marked invalid!\n");
+ }
}
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *link_name_prefixed = NULL;
- if (state && state->parsed->prefix) {
+ if (do_extract && state && state->parsed->prefix) {
link_name_prefixed = malloc(prefix_length + link_name_length + 1);
memcpy(link_name_prefixed, state->parsed->prefix, prefix_length);
memcpy(link_name_prefixed + prefix_length, link_name, link_name_length + 1);
}
if (simple_archiver_validate_file_path(link_name)) {
- fprintf(stderr, " WARNING: Invalid link name \"%s\"!\n", link_name);
+ if (lists_allowed) {
+ fprintf(stderr, " WARNING: Invalid link name \"%s\"!\n", link_name);
+ }
skip_due_to_invalid = 1;
}
return ret;
}
parsed_abs_path[path_length] = 0;
- if (!do_extract) {
+ if (!do_extract && lists_allowed) {
fprintf(stderr, " Abs path: %s\n", parsed_abs_path);
}
- if (state && state->parsed->prefix) {
+ if (do_extract && state && state->parsed->prefix) {
if (points_to_outside) {
abs_path_prefixed = strdup(parsed_abs_path);
} else {
return SDAS_INTERNAL_ERROR;
}
}
- } else if (!do_extract) {
+ } else if (!do_extract && lists_allowed) {
fprintf(stderr, " No Absolute path.\n");
}
return ret;
}
parsed_rel_path[path_length] = 0;
- if (!do_extract) {
+ if (!do_extract && lists_allowed) {
fprintf(stderr, " Rel path: %s\n", parsed_rel_path);
}
- if (state && state->parsed->prefix) {
+ if (do_extract && state && state->parsed->prefix) {
rel_path_prefixed =
simple_archiver_helper_insert_prefix_in_link_path(
state->parsed->prefix, link_name, parsed_rel_path);
return SDAS_INTERNAL_ERROR;
}
}
- } else if (!do_extract) {
+ } else if (!do_extract && lists_allowed) {
fprintf(stderr, " No Relative path.\n");
}
simple_archiver_helper_32_bit_be(&u32);
uint32_t uid = u32;
- fprintf(stderr, " UID: %" PRIu32 "\n", uid);
+ if (lists_allowed) {
+ fprintf(stderr, " UID: %" PRIu32 "\n", uid);
+ }
if (fread(&u32, 4, 1, in_f) != 1) {
fprintf(stderr, " ERROR: Failed to read GID for symlink!\n");
simple_archiver_helper_32_bit_be(&u32);
uint32_t gid = u32;
- fprintf(stderr, " GID: %" PRIu32 "\n", gid);
+ if (lists_allowed) {
+ fprintf(stderr, " GID: %" PRIu32 "\n", gid);
+ }
if (fread(&u16, 2, 1, in_f) != 1) {
fprintf(stderr, " ERROR: Failed to read Username length for symlink!\n");
return SDAS_INVALID_FILE;
}
username[u16] = 0;
- fprintf(stderr, " Username: %s\n", username);
+ if (lists_allowed) {
+ fprintf(stderr, " Username: %s\n", username);
+ }
} else {
free(username);
username = NULL;
- fprintf(stderr, " Username does not exist for this link\n");
+ if (lists_allowed) {
+ fprintf(stderr, " Username does not exist for this link\n");
+ }
}
uint32_t *username_uid_mapped = NULL;
- if (state && username) {
+ if (do_extract && state && username) {
username_uid_mapped = simple_archiver_hash_map_get(
state->parsed->users_infos.UnameToUid,
username,
__attribute__((cleanup(simple_archiver_helper_cleanup_uint32)))
uint32_t *user_remapped_uid = NULL;
uint32_t current_uid = uid;
- if (state) {
+ if (do_extract && state) {
if ((state->parsed->flags & 0x4000) == 0 && username_uid_mapped) {
current_uid = *username_uid_mapped;
}
return SDAS_INVALID_FILE;
}
groupname[u16] = 0;
- fprintf(stderr, " Groupname: %s\n", groupname);
+ if (lists_allowed) {
+ fprintf(stderr, " Groupname: %s\n", groupname);
+ }
} else {
free(groupname);
groupname = NULL;
- fprintf(stderr, " Groupname does not exist for this link\n");
+ if (lists_allowed) {
+ fprintf(stderr, " Groupname does not exist for this link\n");
+ }
}
uint32_t *group_gid_mapped = NULL;
- if (state && groupname) {
+ if (do_extract && state && groupname) {
group_gid_mapped = simple_archiver_hash_map_get(
state->parsed->users_infos.GnameToGid,
groupname,
__attribute__((cleanup(simple_archiver_helper_cleanup_uint32)))
uint32_t *group_remapped_gid = NULL;
uint32_t current_gid = gid;
- if (state) {
+ if (do_extract && state) {
if ((state->parsed->flags & 0x8000) == 0 && group_gid_mapped) {
current_gid = *group_gid_mapped;
}
}
}
- if (do_extract && !skip_due_to_map && !skip_due_to_invalid &&
- absolute_preferred && parsed_abs_path) {
+ if (do_extract
+ && !skip_due_to_map
+ && !skip_due_to_invalid
+ && lists_allowed
+ && absolute_preferred
+ && parsed_abs_path) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
V3_SYMLINK_CREATE_AFTER_0:
link_create_retry = 1;
#endif
- } else if (do_extract && !skip_due_to_map && !skip_due_to_invalid &&
- !absolute_preferred && parsed_rel_path) {
+ } else if (do_extract
+ && !skip_due_to_map
+ && !skip_due_to_invalid
+ && lists_allowed
+ && !absolute_preferred
+ && parsed_rel_path) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
#endif
}
- if (do_extract && link_extracted && geteuid() == 0) {
+ if (do_extract && lists_allowed && link_extracted && geteuid() == 0) {
uint32_t picked_uid;
if (uid_remapped || user_remapped_uid) {
if (state->parsed->flags & 0x4000) {
}
}
- if (do_extract && !link_extracted && !skip_due_to_map &&
- !skip_due_to_invalid) {
+ if (do_extract
+ && !link_extracted
+ && !skip_due_to_map
+ && !skip_due_to_invalid
+ && lists_allowed) {
fprintf(stderr, " WARNING: Symlink \"%s\" was not created!\n",
link_name);
- } else if (do_extract && link_extracted && !skip_due_to_map &&
- !skip_due_to_invalid && links_list) {
+ } else if (do_extract
+ && link_extracted
+ && !skip_due_to_map
+ && !skip_due_to_invalid
+ && lists_allowed
+ && links_list) {
simple_archiver_list_add(links_list, strdup(link_name), NULL);
}
}
"ERROR: File idx %" PRIu32 ": Invalid filename!\n",
file_idx);
file_info->other_flags |= 1;
- }
-
- if (state && state->parsed && (state->parsed->flags & 8) != 0) {
+ } else if (simple_archiver_helper_string_allowed_lists(
+ file_info->filename,
+ state->parsed->whitelist_contains,
+ state->parsed->whitelist_begins,
+ state->parsed->whitelist_ends,
+ state->parsed->blacklist_contains,
+ state->parsed->blacklist_begins,
+ state->parsed->blacklist_ends)) {
+ file_info->other_flags |= 2;
+ }
+
+ if (do_extract
+ && state
+ && state->parsed
+ && (state->parsed->flags & 8) != 0
+ && (file_info->other_flags & 2) != 0) {
int fd = open((const char *)buf, O_RDONLY | O_NOFOLLOW);
if (fd == -1) {
if (errno == ELOOP) {
simple_archiver_helper_32_bit_be(&u32);
__attribute__((cleanup(simple_archiver_helper_cleanup_uint32)))
uint32_t *remapped_uid = NULL;
- if (state && (state->parsed->flags & 0x400)) {
+ if (do_extract && state && (state->parsed->flags & 0x400)) {
file_info->uid = state->parsed->uid;
} else {
file_info->uid = u32;
uint32_t out_uid;
- if (state
+ if (do_extract
+ && state
&& simple_archiver_get_uid_mapping(state->parsed->mappings,
state->parsed->users_infos,
u32,
simple_archiver_helper_32_bit_be(&u32);
__attribute__((cleanup(simple_archiver_helper_cleanup_uint32)))
uint32_t *remapped_gid = NULL;
- if (state && (state->parsed->flags & 0x800)) {
+ if (do_extract && state && (state->parsed->flags & 0x800)) {
file_info->gid = state->parsed->gid;
} else {
file_info->gid = u32;
uint32_t out_gid;
- if (state
+ if (do_extract
+ && state
&& simple_archiver_get_gid_mapping(state->parsed->mappings,
state->parsed->users_infos,
u32,
}
// Prefer uid derived from username by default.
- if (state && file_info->username) {
+ if (do_extract && state && file_info->username) {
uint32_t *username_uid = simple_archiver_hash_map_get(
state->parsed->users_infos.UnameToUid,
file_info->username,
}
// Apply user remapping.
- if (state) {
+ if (do_extract && state) {
if (state->parsed->flags & 0x4000) {
// Prefer UID first.
if (remapped_uid) {
}
// Prefer gid derived from group by default.
- if (state && file_info->groupname) {
+ if (do_extract && state && file_info->groupname) {
uint32_t *groupname_gid = simple_archiver_hash_map_get(
state->parsed->users_infos.GnameToGid,
file_info->groupname,
}
// Apply group remapping.
- if (state) {
+ if (do_extract && state) {
if (state->parsed->flags & 0x8000) {
// Prefer GID first.
if (remapped_gid) {
simple_archiver_helper_64_bit_be(&u64);
file_info->file_size = u64;
- if (files_map) {
+ if (files_map && file_info->other_flags & 2) {
simple_archiver_internal_paths_to_files_map(files_map,
file_info->filename);
}
}
node = node->next;
const SDArchiverInternalFileInfo *file_info = node->data;
- fprintf(stderr,
- " FILE %3" PRIu16 " of %3" PRIu32 ": %s\n",
- ++file_idx,
- file_count,
- file_info->filename);
+ if (file_info->other_flags & 2) {
+ fprintf(stderr,
+ " FILE %3" PRIu16 " of %3" PRIu32 ": %s\n",
+ file_idx,
+ file_count,
+ file_info->filename);
+ }
+ ++file_idx;
const size_t filename_length = strlen(file_info->filename);
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *filename_prefixed = NULL;
- if (state && state->parsed->prefix) {
+ if (do_extract && state && state->parsed->prefix) {
filename_prefixed = malloc(prefix_length + filename_length + 1);
memcpy(filename_prefixed, state->parsed->prefix, prefix_length);
memcpy(filename_prefixed + prefix_length,
filename_length + 1) == NULL) {
skip_due_to_map = 1;
fprintf(stderr, " Skipping not specified in args...\n");
- } else if ((file_info->other_flags & 1) != 0) {
+ } else if ((file_info->other_flags & 1) != 0
+ && (file_info->other_flags & 2) != 0) {
fprintf(stderr, " Skipping invalid filename...\n");
}
- if (do_extract && !skip_due_to_map &&
- (file_info->other_flags & 1) == 0) {
+ if (do_extract
+ && !skip_due_to_map
+ && (file_info->other_flags & 1) == 0
+ && (file_info->other_flags & 2) != 0) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
return SDAS_INTERNAL_ERROR;
}
#endif
- } else if (!skip_due_to_map && (file_info->other_flags & 1) == 0) {
+ } else if (!skip_due_to_map
+ && (file_info->other_flags & 1) == 0
+ && (file_info->other_flags & 2) != 0) {
fprintf(stderr, " Permissions:");
permissions_from_bits_version_1(file_info->bit_flags, 1);
fprintf(stderr,
}
node = node->next;
const SDArchiverInternalFileInfo *file_info = node->data;
- fprintf(stderr,
- " FILE %3" PRIu16 " of %3" PRIu32 ": %s\n",
- ++file_idx,
- file_count,
- file_info->filename);
+ if (file_info->other_flags & 2) {
+ fprintf(stderr,
+ " FILE %3" PRIu16 " of %3" PRIu32 ": %s\n",
+ file_idx,
+ file_count,
+ file_info->filename);
+ }
+ ++file_idx;
chunk_idx += file_info->file_size;
if (chunk_idx > chunk_size) {
fprintf(stderr, "ERROR Files in chunk is larger than chunk!\n");
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *filename_prefixed = NULL;
- if (state && state->parsed->prefix) {
+ if (do_extract && state && state->parsed->prefix) {
filename_prefixed = malloc(prefix_length + filename_length + 1);
memcpy(filename_prefixed, state->parsed->prefix, prefix_length);
memcpy(filename_prefixed + prefix_length,
}
uint_fast8_t skip_due_to_map = 0;
- if (working_files_map && simple_archiver_hash_map_get(
- working_files_map, file_info->filename,
- filename_length + 1) == NULL) {
+ if (do_extract
+ && working_files_map
+ && simple_archiver_hash_map_get(working_files_map,
+ file_info->filename,
+ filename_length + 1) == NULL) {
skip_due_to_map = 1;
fprintf(stderr, " Skipping not specified in args...\n");
- } else if (file_info->other_flags & 1) {
+ } else if ((file_info->other_flags & 1) != 0
+ && (file_info->other_flags & 2) != 0) {
fprintf(stderr, " Skipping invalid filename...\n");
}
- if (do_extract && !skip_due_to_map &&
- (file_info->other_flags & 1) == 0) {
+ if (do_extract
+ && !skip_due_to_map
+ && (file_info->other_flags & 1) == 0
+ && (file_info->other_flags & 2) != 0) {
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
return SDAS_INTERNAL_ERROR;
}
#endif
- } else if (!skip_due_to_map && (file_info->other_flags & 1) == 0) {
+ } else if (!skip_due_to_map
+ && (file_info->other_flags & 1) == 0
+ && (file_info->other_flags & 2) != 0) {
fprintf(stderr, " Permissions:");
permissions_from_bits_version_1(file_info->bit_flags, 1);
fprintf(stderr,
simple_archiver_helper_16_bit_be(&u16);
- if (fread(buf, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
+ __attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
+ char *archive_dir_name = malloc(u16 + 1);
+
+ if (fread(archive_dir_name, 1, u16 + 1, in_f) != (size_t)u16 + 1) {
fprintf(stderr, "ERROR: Failed to read directory name!\n");
return SDAS_INVALID_FILE;
}
- buf[u16] = 0;
+ archive_dir_name[u16] = 0;
+
+ const uint_fast8_t lists_allowed =
+ simple_archiver_helper_string_allowed_lists(
+ archive_dir_name,
+ state->parsed->whitelist_contains,
+ state->parsed->whitelist_begins,
+ state->parsed->whitelist_ends,
+ state->parsed->blacklist_contains,
+ state->parsed->blacklist_begins,
+ state->parsed->blacklist_ends);
uint8_t perms_flags[4];
if (fread(perms_flags, 1, 2, in_f) != 2) {
fprintf(stderr,
"ERROR: Failed to read permission flags for \"%s\"!\n",
- buf);
+ archive_dir_name);
return SDAS_INVALID_FILE;
}
perms_flags[2] = 0;
uint32_t uid;
if (fread(&uid, 4, 1, in_f) != 1) {
fprintf(stderr,
- "ERROR: Failed to read UID for \"%s\"!\n", buf);
+ "ERROR: Failed to read UID for \"%s\"!\n", archive_dir_name);
return SDAS_INVALID_FILE;
}
simple_archiver_helper_32_bit_be(&uid);
uint32_t gid;
if (fread(&gid, 4, 1, in_f) != 1) {
fprintf(stderr,
- "ERROR: Failed to read GID for \"%s\"!\n", buf);
+ "ERROR: Failed to read GID for \"%s\"!\n", archive_dir_name);
return SDAS_INVALID_FILE;
}
simple_archiver_helper_32_bit_be(&gid);
uint32_t *remapped_uid = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_uint32)))
uint32_t *remapped_user_uid = NULL;
- if (state) {
+ if (do_extract && state) {
uint32_t out_uid;
if (simple_archiver_get_uid_mapping(state->parsed->mappings,
state->parsed->users_infos,
uint32_t *remapped_gid = NULL;
__attribute__((cleanup(simple_archiver_helper_cleanup_uint32)))
uint32_t *remapped_group_gid = NULL;
- if (state) {
+ if (do_extract && state) {
uint32_t out_gid;
if (simple_archiver_get_gid_mapping(state->parsed->mappings,
state->parsed->users_infos,
}
}
- if (do_extract) {
- fprintf(stderr, "Creating dir \"%s\"\n", buf);
+ if (do_extract && lists_allowed) {
+ fprintf(stderr, "Creating dir \"%s\"\n", archive_dir_name);
// Use UID derived from Username by default.
if ((state->parsed->flags & 0x4000) == 0 && username) {
uint32_t *username_uid = simple_archiver_hash_map_get(
gid = *remapped_gid;
}
}
- } else {
- fprintf(stderr, "Dir entry \"%s\"\n", buf);
+ } else if (lists_allowed) {
+ fprintf(stderr, "Dir entry \"%s\"\n", archive_dir_name);
fprintf(stderr, " Permissions: ");
fprintf(stderr, "%s", (perms_flags[0] & 1) ? "r" : "-");
fprintf(stderr, "%s", (perms_flags[0] & 2) ? "w" : "-");
state->parsed->prefix);
}
- simple_archiver_helper_string_parts_add(string_parts, (char *)buf);
+ simple_archiver_helper_string_parts_add(string_parts, archive_dir_name);
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
char *abs_dir_path =
char *abs_dir_path_with_suffix =
simple_archiver_helper_string_parts_combine(string_parts);
- if (do_extract) {
+ if (do_extract && lists_allowed) {
int ret = simple_archiver_helper_make_dirs_perms(
abs_dir_path_with_suffix,
state && (state->parsed->flags & 0x2000)