this specification and skip to the next entry; if marked invalid,
the following specification bytes for this file/symlink entry must
not exist.
+ 5. The fifth bit is set if this symlink points to something outside of
+ this archive.
3. The third byte.
1. Currently unused.
4. The fourth byte.
3. If this bit is set, then this entry is marked invalid. The link name
will be preserved in this entry, but the following link target paths
will be set to zero-length and will not be stored.
+ 4. If this bit is set, then this entry points to something outside of
+ this archive.
2. 2 bytes 16-bit unsigned integer "link name" in big-endian. This does not
include the NULL at the end of the string. Must not be zero.
3. X bytes of link-name (length defined by previous value). Is a NULL-terminated
3. If this bit is set, then this entry is marked invalid. The link name
will be preserved in this entry, but the following link target paths
will be set to zero-length and will not be stored.
+ 4. If this bit is set, then this symlink points to something outside of
+ this archive.
2. 2 bytes 16-bit unsigned integer "link name" in big-endian. This does not
include the NULL at the end of the string. Must not be zero.
3. X bytes of link-name (length defined by previous value). Is a NULL-terminated
!simple_archiver_hash_map_get(state->map, abs_path,
strlen(abs_path) + 1)) {
// Is not a filename being archived.
+ ((uint8_t *)temp_to_write->buf)[1] |= 0x10;
if ((state->parsed->flags & 0x80) != 0) {
// No safe links, set preference to absolute path.
fprintf(
"will not be stored! (Use \"--no-safe-links\" to disable "
"this behavior)\n",
file_info->filename);
- ((uint8_t *)temp_to_write->buf)[1] |= 0x8;
+ ((uint8_t *)temp_to_write->buf)[1] |= 0x18;
}
} else {
fprintf(stderr,
!simple_archiver_hash_map_get(abs_filenames, abs_path,
strlen(abs_path) + 1)) {
// Is not a filename being archived.
+ buf[1] |= 0x8;
if ((state->parsed->flags & 0x80) == 0) {
// Not a "safe link", mark invalid and continue.
is_invalid = 1;
}
#else
buf[0] = 0xFE;
- buf[1] = 3;
+ buf[1] = 0xB;
#endif
if (is_invalid) {
!simple_archiver_hash_map_get(abs_filenames, abs_path,
strlen(abs_path) + 1)) {
// Is not a filename being archived.
+ buf[1] |= 0x8;
if ((state->parsed->flags & 0x80) == 0) {
// Not a "safe link", mark invalid and continue.
is_invalid = 1;
}
#else
buf[0] = 0xFE;
- buf[1] = 3;
+ buf[1] = 0xB;
#endif
if (is_invalid) {
!simple_archiver_hash_map_get(abs_filenames, abs_path,
strlen(abs_path) + 1)) {
// Is not a filename being archived.
+ buf[1] |= 8;
if ((state->parsed->flags & 0x80) == 0) {
// Not a "safe link", mark invalid and continue.
is_invalid = 1;
}
#else
buf[0] = 0xFE;
- buf[1] = 3;
+ buf[1] = 0xB;
#endif
if (is_invalid) {
state->parsed->file_permissions);
}
+ const uint_fast8_t points_to_outside = (buf[1] & 0x10) ? 1 : 0;
+
if ((buf[0] & 1) == 0) {
// Not a sybolic link.
if (fread(&u64, 8, 1, in_f) != 1) {
int_fast8_t retry_symlink = 0;
int ret;
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
- char *abs_path_prefixed =
- state->parsed->prefix
- ? simple_archiver_helper_insert_prefix_in_link_path(
- state->parsed->prefix, out_f_name, abs_path)
- : NULL;
+ char *abs_path_prefixed = NULL;
+ if (state->parsed->prefix) {
+ if (points_to_outside) {
+ abs_path_prefixed = strdup(abs_path);
+ } else {
+ abs_path_prefixed =
+ simple_archiver_helper_insert_prefix_in_link_path(
+ state->parsed->prefix, out_f_name, abs_path);
+ }
+ }
if (filename_with_prefix && !abs_path_prefixed) {
fprintf(stderr, " ERROR: Prefix specified but unable to resolve"
" abs link with prefix!\n");
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_LINUX
__attribute__((cleanup(simple_archiver_helper_cleanup_c_string)))
- char *abs_path_prefixed =
- state->parsed->prefix
- ? simple_archiver_helper_insert_prefix_in_link_path(
- state->parsed->prefix, out_f_name, abs_path)
- : NULL;
+ char *abs_path_prefixed = NULL;
+ if (state->parsed->prefix) {
+ if (points_to_outside) {
+ abs_path_prefixed = strdup(abs_path);
+ } else {
+ abs_path_prefixed =
+ simple_archiver_helper_insert_prefix_in_link_path(
+ state->parsed->prefix, out_f_name, abs_path);
+ }
+ }
if (filename_with_prefix && !abs_path_prefixed) {
fprintf(stderr, " ERROR: Prefix specified but unable to resolve"
" abs link with prefix!\n");
}
const uint_fast8_t absolute_preferred = (buf[0] & 1) ? 1 : 0;
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 (do_extract && !skip_due_to_map && !skip_due_to_invalid &&
absolute_preferred) {
if (state->parsed->prefix) {
- abs_path_prefixed =
- simple_archiver_helper_insert_prefix_in_link_path(
- state->parsed->prefix, link_name, path);
+ if (points_to_outside) {
+ abs_path_prefixed = strdup(path);
+ } else {
+ abs_path_prefixed =
+ simple_archiver_helper_insert_prefix_in_link_path(
+ state->parsed->prefix, link_name, path);
+ }
if (!abs_path_prefixed) {
fprintf(stderr,
"ERROR: Failed to insert prefix to absolute path!\n");
}
const uint_fast8_t absolute_preferred = (buf[0] & 1) ? 1 : 0;
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 (state && state->parsed->prefix) {
- abs_path_prefixed =
- simple_archiver_helper_insert_prefix_in_link_path(
- state->parsed->prefix, link_name, parsed_abs_path);
+ if (points_to_outside) {
+ abs_path_prefixed = strdup(parsed_abs_path);
+ } else {
+ abs_path_prefixed =
+ simple_archiver_helper_insert_prefix_in_link_path(
+ state->parsed->prefix, link_name, parsed_abs_path);
+ }
if (!abs_path_prefixed) {
fprintf(stderr,
"ERROR: Failed to insert prefix to absolute path!\n");