unzip: Sync with NetBSD upstream.

- Ignore malformed directory entries as created by Dropbox ("/").
  (rev 1.24)
- Use libarchive 3.x interface: check result for archive_read_free()
  and don't call archive_read_close manually. (rev 1.23)
- Always overwrite symlinks on extraction, ever if they're newer than
  entries in archive.
- Use getline() rather than getdelim().

PR:		231827
Submitted by:	ak
Reviewed by:	mm
Obtained from:	NetBSD
MFC after:	2 weeks
This commit is contained in:
Yoshihiro Takahashi 2021-01-02 10:50:08 +09:00
parent bfe90bb336
commit 0cdfa49564

View File

@ -385,6 +385,13 @@ extract_dir(struct archive *a, struct archive_entry *e, const char *path)
{ {
int mode; int mode;
/*
* Dropbox likes to create '/' directory entries, just ignore
* such junk.
*/
if (*path == '\0')
return;
mode = archive_entry_mode(e) & 0777; mode = archive_entry_mode(e) & 0777;
if (mode == 0) if (mode == 0)
mode = 0755; mode = 0755;
@ -451,7 +458,7 @@ handle_existing_file(char **path)
free(*path); free(*path);
*path = NULL; *path = NULL;
alen = 0; alen = 0;
len = getdelim(path, &alen, '\n', stdin); len = getline(path, &alen, stdin);
if ((*path)[len - 1] == '\n') if ((*path)[len - 1] == '\n')
(*path)[len - 1] = '\0'; (*path)[len - 1] = '\0';
return 0; return 0;
@ -601,7 +608,7 @@ extract_file(struct archive *a, struct archive_entry *e, char **path)
if (lstat(*path, &sb) == 0) { if (lstat(*path, &sb) == 0) {
if (u_opt || f_opt) { if (u_opt || f_opt) {
/* check if up-to-date */ /* check if up-to-date */
if ((S_ISREG(sb.st_mode) || S_ISLNK(sb.st_mode)) && if (S_ISREG(sb.st_mode) &&
(sb.st_mtim.tv_sec > mtime.tv_sec || (sb.st_mtim.tv_sec > mtime.tv_sec ||
(sb.st_mtim.tv_sec == mtime.tv_sec && (sb.st_mtim.tv_sec == mtime.tv_sec &&
sb.st_mtim.tv_nsec >= mtime.tv_nsec))) sb.st_mtim.tv_nsec >= mtime.tv_nsec)))
@ -916,8 +923,7 @@ unzip(const char *fn)
} }
} }
ac(archive_read_close(a)); ac(archive_read_free(a));
(void)archive_read_free(a);
if (t_opt) { if (t_opt) {
if (error_count > 0) { if (error_count > 0) {