Add abs_path check when referring out of archive
If absolute paths are enabled, and a link points to something outside of the archive, a flag is set on the symlink entry to prefer absolute paths.
This commit is contained in:
parent
c6d2d50c0f
commit
b28e384149
1 changed files with 91 additions and 39 deletions
130
src/archiver.c
130
src/archiver.c
|
@ -704,21 +704,13 @@ int write_files_fn(void *data, void *ud) {
|
||||||
// Unsupported platform. Just set the permission bits for user.
|
// Unsupported platform. Just set the permission bits for user.
|
||||||
((unsigned char *)temp_to_write->buf)[0] |= 0xE;
|
((unsigned char *)temp_to_write->buf)[0] |= 0xE;
|
||||||
#endif
|
#endif
|
||||||
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
|
||||||
|
|
||||||
|
// Need to get abs_path for checking/setting a flag before storing flags.
|
||||||
// Get absolute path.
|
// Get absolute path.
|
||||||
__attribute__((cleanup(free_malloced_memory))) void *abs_path =
|
__attribute__((cleanup(free_malloced_memory))) void *abs_path =
|
||||||
realpath(file_info->filename, NULL);
|
realpath(file_info->filename, NULL);
|
||||||
__attribute__((cleanup(free_malloced_memory))) void *rel_path = NULL;
|
__attribute__((cleanup(free_malloced_memory))) void *rel_path = NULL;
|
||||||
if (!abs_path) {
|
if (abs_path) {
|
||||||
fprintf(stderr,
|
|
||||||
"WARNING: Failed to get absolute path of link destination!\n");
|
|
||||||
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
|
||||||
temp_to_write->buf = malloc(2);
|
|
||||||
temp_to_write->size = 2;
|
|
||||||
memset(temp_to_write->buf, 0, 2);
|
|
||||||
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
|
||||||
} else {
|
|
||||||
// Get relative path.
|
// Get relative path.
|
||||||
// First get absolute path of link.
|
// First get absolute path of link.
|
||||||
__attribute__((cleanup(free_malloced_memory))) void *link_abs_path =
|
__attribute__((cleanup(free_malloced_memory))) void *link_abs_path =
|
||||||
|
@ -770,38 +762,58 @@ int write_files_fn(void *data, void *ud) {
|
||||||
}
|
}
|
||||||
} while (has_slash);
|
} while (has_slash);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((state->parsed->flags & 0x20) == 0) {
|
// Check if absolute path refers to one of the filenames.
|
||||||
// Write absolute path length.
|
if (abs_path && (state->parsed->flags & 0x20) == 0 &&
|
||||||
u16 = strlen(abs_path);
|
!simple_archiver_hash_map_get(state->map, abs_path,
|
||||||
simple_archiver_helper_16_bit_be(&u16);
|
strlen(abs_path) + 1)) {
|
||||||
|
// Is not a filename being archived, set preference to absolute path.
|
||||||
|
fprintf(stderr,
|
||||||
|
"NOTICE: abs_path exists, \"--no-abs-symlink\" not specified, "
|
||||||
|
"and link refers to file NOT in archive; preferring abs_path.\n");
|
||||||
|
((unsigned char *)temp_to_write->buf)[1] |= 0x4;
|
||||||
|
}
|
||||||
|
|
||||||
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
// Store the 4 byte bit-flags for file.
|
||||||
temp_to_write->buf = malloc(2);
|
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
||||||
temp_to_write->size = 2;
|
|
||||||
memcpy(temp_to_write->buf, &u16, 2);
|
|
||||||
simple_archiver_list_add(to_write, temp_to_write,
|
|
||||||
free_internal_to_write);
|
|
||||||
|
|
||||||
// Write absolute path.
|
// Store the absolute and relative paths.
|
||||||
simple_archiver_helper_16_bit_be(&u16);
|
if (!abs_path) {
|
||||||
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
fprintf(stderr,
|
||||||
temp_to_write->buf = malloc(u16 + 1);
|
"WARNING: Failed to get absolute path of link destination!\n");
|
||||||
temp_to_write->size = u16 + 1;
|
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
||||||
strncpy(temp_to_write->buf, abs_path, u16 + 1);
|
temp_to_write->buf = malloc(2);
|
||||||
simple_archiver_list_add(to_write, temp_to_write,
|
temp_to_write->size = 2;
|
||||||
free_internal_to_write);
|
memset(temp_to_write->buf, 0, 2);
|
||||||
} else {
|
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
||||||
fprintf(stderr,
|
} else if ((state->parsed->flags & 0x20) == 0) {
|
||||||
"NOTICE: Not saving absolute path since \"--no-abs-symlink\" "
|
// Write absolute path length.
|
||||||
"was specified.\n");
|
u16 = strlen(abs_path);
|
||||||
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
simple_archiver_helper_16_bit_be(&u16);
|
||||||
temp_to_write->buf = malloc(2);
|
|
||||||
temp_to_write->size = 2;
|
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
||||||
memset(temp_to_write->buf, 0, 2);
|
temp_to_write->buf = malloc(2);
|
||||||
simple_archiver_list_add(to_write, temp_to_write,
|
temp_to_write->size = 2;
|
||||||
free_internal_to_write);
|
memcpy(temp_to_write->buf, &u16, 2);
|
||||||
}
|
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
||||||
|
|
||||||
|
// Write absolute path.
|
||||||
|
simple_archiver_helper_16_bit_be(&u16);
|
||||||
|
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
||||||
|
temp_to_write->buf = malloc(u16 + 1);
|
||||||
|
temp_to_write->size = u16 + 1;
|
||||||
|
strncpy(temp_to_write->buf, abs_path, u16 + 1);
|
||||||
|
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
||||||
|
} else {
|
||||||
|
fprintf(stderr,
|
||||||
|
"NOTICE: Not saving absolute path since \"--no-abs-symlink\" "
|
||||||
|
"was specified.\n");
|
||||||
|
temp_to_write = malloc(sizeof(SDArchiverInternalToWrite));
|
||||||
|
temp_to_write->buf = malloc(2);
|
||||||
|
temp_to_write->size = 2;
|
||||||
|
memset(temp_to_write->buf, 0, 2);
|
||||||
|
simple_archiver_list_add(to_write, temp_to_write, free_internal_to_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rel_path) {
|
if (rel_path) {
|
||||||
|
@ -852,10 +864,45 @@ int filenames_to_abs_map_fn(void *data, void *ud) {
|
||||||
|
|
||||||
// Get combined full path to file.
|
// Get combined full path to file.
|
||||||
char *fullpath = filename_to_absolute_path(file_info->filename);
|
char *fullpath = filename_to_absolute_path(file_info->filename);
|
||||||
|
if (!fullpath) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
simple_archiver_hash_map_insert(abs_filenames, fullpath, fullpath,
|
simple_archiver_hash_map_insert(abs_filenames, fullpath, fullpath,
|
||||||
strlen(fullpath) + 1, cleanup_nop_fn, NULL);
|
strlen(fullpath) + 1, cleanup_nop_fn, NULL);
|
||||||
|
|
||||||
|
// Try putting all parent dirs up to current working directory.
|
||||||
|
// First get absolute path to current working directory.
|
||||||
|
__attribute__((cleanup(free_malloced_memory))) void *cwd_dirname =
|
||||||
|
realpath(".", NULL);
|
||||||
|
if (!cwd_dirname) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use copy of fullpath to avoid clobbering it.
|
||||||
|
__attribute__((cleanup(free_malloced_memory))) void *fullpath_copy =
|
||||||
|
malloc(strlen(fullpath) + 1);
|
||||||
|
strncpy(fullpath_copy, fullpath, strlen(fullpath) + 1);
|
||||||
|
|
||||||
|
// Get dirnames.
|
||||||
|
char *prev = fullpath_copy;
|
||||||
|
char *fullpath_dirname;
|
||||||
|
while (1) {
|
||||||
|
fullpath_dirname = dirname(prev);
|
||||||
|
if (!fullpath_dirname || strlen(fullpath_dirname) <= strlen(cwd_dirname)) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// Make and store copy of fullpath_dirname.
|
||||||
|
char *fullpath_dirname_copy = malloc(strlen(fullpath_dirname) + 1);
|
||||||
|
strncpy(fullpath_dirname_copy, fullpath_dirname,
|
||||||
|
strlen(fullpath_dirname) + 1);
|
||||||
|
simple_archiver_hash_map_insert(
|
||||||
|
abs_filenames, fullpath_dirname_copy, fullpath_dirname_copy,
|
||||||
|
strlen(fullpath_dirname_copy) + 1, cleanup_nop_fn, NULL);
|
||||||
|
}
|
||||||
|
prev = fullpath_dirname;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1566,6 +1613,11 @@ int simple_archiver_parse_archive_info(FILE *in_f, int do_extract,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Is a symbolic link.
|
// Is a symbolic link.
|
||||||
|
|
||||||
|
int abs_preferred = (buf[1] & 0x4) != 0 ? 1 : 0;
|
||||||
|
fprintf(stderr, " Absolute paths are %s\n",
|
||||||
|
(abs_preferred ? "preferred" : "NOT preferred"));
|
||||||
|
|
||||||
if (fread(&u16, 2, 1, in_f) != 1) {
|
if (fread(&u16, 2, 1, in_f) != 1) {
|
||||||
return SDAS_INVALID_FILE;
|
return SDAS_INVALID_FILE;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue