]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
tar: avoid parsing mode field twice
authordatauwu <datauwu@users.noreply.github.com>
Sat, 4 Jul 2026 05:57:32 +0000 (13:57 +0800)
committerdatauwu <datauwu@users.noreply.github.com>
Sat, 4 Jul 2026 05:57:32 +0000 (13:57 +0800)
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.

libarchive/archive_read_support_format_tar.c

index e07cfdb63b53cf5440270334a2a488720b3e1348..bf350fa05f90a51358dfb2664eeb606bf09231d3 100644 (file)
@@ -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)) {