2. The second byte.
1. The first bit is "other write permission".
2. The second bit is "other execute permission".
+ 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.
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
abs_path);
}
}
+
+ uint_fast8_t is_invalid = 0;
+
if (abs_path && (state->parsed->flags & 0x20) == 0 &&
!simple_archiver_hash_map_get(abs_filenames, abs_path,
strlen(abs_path) + 1)) {
- // Is not a filename being archived, set preference to absolute path.
- buf[0] |= 1;
+ // Is not a filename being archived.
+ if ((state->parsed->flags & 0x80) == 0) {
+ // Not a "safe link", mark invalid and continue.
+ is_invalid = 1;
+ fprintf(stderr,
+ "WARNING: \"%s\" points to outside of archived files (or is "
+ "invalid) and \"--no-safe-links\" not specified, will not "
+ "store abs/rel-links to this entry!\n",
+ (const char *)node->data);
+ } else {
+ // Safe links disabled, set preference to absolute path.
+ buf[0] |= 1;
+ }
}
// Get symlink stats for permissions.
buf[0] = 0xFE;
buf[1] = 3;
#endif
+
+ if (is_invalid) {
+ buf[1] |= 4;
+ }
+
if (fwrite(buf, 1, 2, out_f) != 2) {
return SDAS_FAILED_TO_WRITE;
}
return SDAS_FAILED_TO_WRITE;
}
- if (abs_path && (state->parsed->flags & 0x20) == 0) {
+ if (abs_path && (state->parsed->flags & 0x20) == 0 && !is_invalid) {
len = strlen(abs_path);
if (len >= 0xFFFF) {
fprintf(stderr,
}
}
- if (rel_path) {
+ if (rel_path && !is_invalid) {
len = strlen(rel_path);
if (len >= 0xFFFF) {
fprintf(stderr,
return SDAS_INVALID_FILE;
}
const uint_fast8_t absolute_preferred = (buf[0] & 1) ? 1 : 0;
+ const uint_fast8_t is_invalid = (buf[1] & 4) ? 1 : 0;
+
+ if (is_invalid) {
+ fprintf(stderr,
+ " WARNING: This symlink entry was marked invalid (not a safe "
+ "link)!\n");
+ }
#if SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_COSMOPOLITAN || \
SIMPLE_ARCHIVER_PLATFORM == SIMPLE_ARCHIVER_PLATFORM_MAC || \