From: datauwu Date: Sat, 4 Jul 2026 05:57:32 +0000 (+0800) Subject: tar: avoid parsing mode field twice X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=426f2aef8635708ceee9f7d501ebc37535294f86;p=thirdparty%2Flibarchive.git tar: avoid parsing mode field twice header_common() parsed the tar mode field once when setting the file type and again when setting permissions. Cache the parsed value and reuse it for both setters. archive_entry_set_filetype() and archive_entry_set_perm() already mask the relevant bits, so passing the full header mode preserves behavior. The permission-set guard is unchanged. No functional change intended. --- diff --git a/libarchive/archive_read_support_format_tar.c b/libarchive/archive_read_support_format_tar.c index e07cfdb63..bf350fa05 100644 --- a/libarchive/archive_read_support_format_tar.c +++ b/libarchive/archive_read_support_format_tar.c @@ -1347,6 +1347,7 @@ header_common(struct archive_read *a, struct tar *tar, const struct archive_entry_header_ustar *header; const char *existing_linkpath; const wchar_t *existing_wcs_linkpath; + mode_t header_mode; int err = ARCHIVE_OK; header = (const struct archive_entry_header_ustar *)h; @@ -1354,12 +1355,10 @@ header_common(struct archive_read *a, struct tar *tar, /* Parse out the numeric fields (all are octal) */ /* Split mode handling: Set filetype always, perm only if not already set */ - archive_entry_set_filetype(entry, - (mode_t)tar_atol(header->mode, sizeof(header->mode))); - if (!archive_entry_perm_is_set(entry)) { - archive_entry_set_perm(entry, - (mode_t)tar_atol(header->mode, sizeof(header->mode))); - } + header_mode = (mode_t)tar_atol(header->mode, sizeof(header->mode)); + archive_entry_set_filetype(entry, header_mode); + if (!archive_entry_perm_is_set(entry)) + archive_entry_set_perm(entry, header_mode); /* Set uid, gid, mtime if not already set */ if (!archive_entry_uid_is_set(entry)) {