commit f356c450a6cfeddc54a577b29ae090141d73a2d9 Author: Jacob Welsh AuthorDate: Tue Apr 16 00:42:24 2024 +0000 Commit: Jacob Welsh CommitDate: Thu Apr 18 21:23:35 2024 +0000 busybox ar: cleaner and more GNU-like extraction behavior. I found the directory mtimes work was less relevant to ar since it's not supposed to extract directories, but that it would do so anyway if instructed by the input, and it also failed to extract some valid (or at least GNU-produced) archives. diff --git a/base/busybox/archival/ar.c b/base/busybox/archival/ar.c index f86c52d..85bbd00 100644 --- a/base/busybox/archival/ar.c +++ b/base/busybox/archival/ar.c @@ -251,6 +251,7 @@ int ar_main(int argc UNUSED_PARAM, char **argv) unsigned opt, t; archive_handle = init_handle(); + archive_handle->ah_flags = ARCHIVE_O_TRUNC; /* don't fail on existing files (follows GNU binutils) */ /* --: prepend '-' to the first argument if required */ /* -1: at least one param is reqd */ diff --git a/base/busybox/archival/libarchive/get_header_ar.c b/base/busybox/archival/libarchive/get_header_ar.c index c66bb3e..aed31d4 100644 --- a/base/busybox/archival/libarchive/get_header_ar.c +++ b/base/busybox/archival/libarchive/get_header_ar.c @@ -102,6 +102,9 @@ char FAST_FUNC get_header_ar(archive_handle_t *archive_handle) typed->uid = read_num(ar.formatted.uid, 10, sizeof(ar.formatted.uid)); typed->mtime = read_num(ar.formatted.date, 10, sizeof(ar.formatted.date)); + /* GNU binutils can produce archives with no type bits in the mode string, e.g. 644 instead of 100644 in its deterministic mode. Otherwise, the ar format isn't intended to represent non-regular files, yet data_extract_all will obey the type bits it's given. So just disregard and override the provided type bits entirely, which seems to match GNU behavior. */ + typed->mode = (typed->mode & 07777) | S_IFREG; + #if ENABLE_FEATURE_AR_LONG_FILENAMES if (ar.formatted.name[0] == '/') { unsigned long_offset;