[lfs-patches] r3324 - trunk/libarchive

fernando at higgs.linuxfromscratch.org fernando at higgs.linuxfromscratch.org
Sun Dec 20 10:42:27 PST 2015


Author: fernando
Date: Sun Dec 20 10:42:27 2015
New Revision: 3324

Log:
• Add libarchive-3.1.2-upstream_fixes-1.patch.

Added:
   trunk/libarchive/
   trunk/libarchive/libarchive-3.1.2-upstream_fixes-1.patch

Added: trunk/libarchive/libarchive-3.1.2-upstream_fixes-1.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ trunk/libarchive/libarchive-3.1.2-upstream_fixes-1.patch	Sun Dec 20 10:42:27 2015	(r3324)
@@ -0,0 +1,562 @@
+Submitted By:            Fernando de Oliveira <famobr at yahoo dot com dot br>
+Date:                    2015-12-20
+Initial Package Version: 3.1.2
+Upstream Status:         Committed
+Origin:                  Upstream, suggested by DJ
+Description:             Several fixes:
+                         1 Limit write requests to at most INT_MAX
+                           (CVE-2013-0211).
+                         2 mtree: fix line filename length calculation.
+                         3 Make reading additional information from the
+                           fs optional.
+Comment:                 Used 3 from Arch, which is fixed for one failed
+                         hunk and for the test suite. Arch URL:
+https://projects.archlinux.org/svntogit/packages.git/plain/trunk/libarchive-3.1.2-sparce-mtree.patch?h=packages/libarchive
+
+===============================================================================
+https://github.com/libarchive/libarchive/commit/22531545514043e04633e1c015c7540b9de9dbe4.diff
+
+Limit write requests to at most INT_MAX.
+
+This prevents a certain common programming error (passing -1 to write)
+from leading to other problems deeper in the library.
+===============================================================================
+
+===============================================================================
+https://github.com/libarchive/libarchive/commit/e65bf287f0133426b26611fe3e80b51267987106.diff
+
+mtree: fix line filename length calculation.
+
+Fixes #301.
+Signed-off-by: Andres Mejia <amejia004 at gmail.com>
+===============================================================================
+
+===============================================================================
+https://github.com/libarchive/libarchive/commit/977bf2a4.diff
+
+mtree: Make reading additional information from the fs optional
+
+This feature is not needed if users just want to read in the content of
+an mtree file and do validation against the file system themselves.
+
+It is needed for `bsdtar cvf out.tar @input.mtree` which is why the
+option is enabled in bsdtar.
+
+Since the mtree tests rely on this feature, this patch also enables it
+there.
+
+Signed-off-by: Florian Pritz <bluewind at xinu.at>
+===============================================================================
+
+diff --git a/libarchive/archive_write.c b/libarchive/archive_write.c
+index eede5e0..be85621 100644
+--- a/libarchive/archive_write.c
++++ b/libarchive/archive_write.c
+@@ -673,8 +673,13 @@ static ssize_t
+ _archive_write_data(struct archive *_a, const void *buff, size_t s)
+ {
+ 	struct archive_write *a = (struct archive_write *)_a;
++	const size_t max_write = INT_MAX;
++
+ 	archive_check_magic(&a->archive, ARCHIVE_WRITE_MAGIC,
+ 	    ARCHIVE_STATE_DATA, "archive_write_data");
++	/* In particular, this catches attempts to pass negative values. */
++	if (s > max_write)
++		s = max_write;
+ 	archive_clear_error(&a->archive);
+ 	return ((a->format_write_data)(a, buff, s));
+ }
+diff --git a/libarchive/archive_write_set_format_mtree.c b/libarchive/archive_write_set_format_mtree.c
+index 9c0613c..f37f723 100644
+--- a/libarchive/archive_write_set_format_mtree.c
++++ b/libarchive/archive_write_set_format_mtree.c
+@@ -1855,9 +1855,9 @@ mtree_entry_setup_filenames(struct archive_write *a, struct mtree_entry *file,
+ 		return (ret);
+ 	}
+ 
+-	/* Make a basename from dirname and slash */
++	/* Make a basename from file->parentdir.s and slash */
+ 	*slash  = '\0';
+-	file->parentdir.length = slash - dirname;
++	file->parentdir.length = slash - file->parentdir.s;
+ 	archive_strcpy(&(file->basename),  slash + 1);
+ 	return (ret);
+ }
+From 977bf2a49484239f7a7b6ce08bfa9da413a27ead Mon Sep 17 00:00:00 2001
+From: Florian Pritz <bluewind at xinu.at>
+Date: Sat, 1 Mar 2014 17:21:47 +0100
+Subject: [PATCH] mtree: Make reading additional information from the fs
+ optional
+
+This feature is not needed if users just want to read in the content of
+an mtree file and do validation against the file system themselves.
+
+It is needed for `bsdtar cvf out.tar @input.mtree` which is why the
+option is enabled in bsdtar.
+
+Since the mtree tests rely on this feature, this patch also enables it
+there.
+
+Signed-off-by: Florian Pritz <bluewind at xinu.at>
+---
+ libarchive/archive_read_support_format_mtree.c | 290 ++++++++++++++-----------
+ libarchive/test/test_read_format_mtree.c       |  20 ++
+ tar/write.c                                    |   1 +
+ 3 files changed, 179 insertions(+), 132 deletions(-)
+
+diff --git a/libarchive/archive_read_support_format_mtree.c b/libarchive/archive_read_support_format_mtree.c
+index 44799df..d82d4c1 100644
+--- a/libarchive/archive_read_support_format_mtree.c
++++ b/libarchive/archive_read_support_format_mtree.c
+@@ -104,6 +104,7 @@ struct mtree {
+ 	struct archive_entry_linkresolver *resolver;
+ 
+ 	int64_t			 cur_size;
++	char checkfs;
+ };
+ 
+ static int	bid_keycmp(const char *, const char *, ssize_t);
+@@ -174,6 +175,29 @@ static int	read_header(struct archive_read *,
+ #endif
+ }
+ 
++static int
++archive_read_format_mtree_options(struct archive_read *a,
++    const char *key, const char *val)
++{
++	struct mtree *mtree;
++
++	mtree = (struct mtree *)(a->format->data);
++	if (strcmp(key, "checkfs")  == 0) {
++		/* Allows to read information missing from the mtree from the file system */
++		if (val == NULL || val[0] == 0) {
++			mtree->checkfs = 0;
++		} else {
++			mtree->checkfs = 1;
++		}
++		return (ARCHIVE_OK);
++	}
++
++	/* Note: The "warn" return is just to inform the options
++	 * supervisor that we didn't handle it.  It will generate
++	 * a suitable error if no one used this option. */
++	return (ARCHIVE_WARN);
++}
++
+ static void
+ free_options(struct mtree_option *head)
+ {
+@@ -206,7 +230,7 @@ static int	read_header(struct archive_read *,
+ 	mtree->fd = -1;
+ 
+ 	r = __archive_read_register_format(a, mtree, "mtree",
+-	    mtree_bid, NULL, read_header, read_data, skip, NULL, cleanup);
++           mtree_bid, archive_read_format_mtree_options, read_header, read_data, skip, NULL, cleanup);
+ 
+ 	if (r != ARCHIVE_OK)
+ 		free(mtree);
+@@ -1104,162 +1128,164 @@ static int	read_header(struct archive_read *,
+ 			mtree->current_dir.length = n;
+ 	}
+ 
+-	/*
+-	 * Try to open and stat the file to get the real size
+-	 * and other file info.  It would be nice to avoid
+-	 * this here so that getting a listing of an mtree
+-	 * wouldn't require opening every referenced contents
+-	 * file.  But then we wouldn't know the actual
+-	 * contents size, so I don't see a really viable way
+-	 * around this.  (Also, we may want to someday pull
+-	 * other unspecified info from the contents file on
+-	 * disk.)
+-	 */
+-	mtree->fd = -1;
+-	if (archive_strlen(&mtree->contents_name) > 0)
+-		path = mtree->contents_name.s;
+-	else
+-		path = archive_entry_pathname(entry);
+-
+-	if (archive_entry_filetype(entry) == AE_IFREG ||
+-	    archive_entry_filetype(entry) == AE_IFDIR) {
+-		mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
+-		__archive_ensure_cloexec_flag(mtree->fd);
+-		if (mtree->fd == -1 &&
+-		    (errno != ENOENT ||
+-		     archive_strlen(&mtree->contents_name) > 0)) {
+-			archive_set_error(&a->archive, errno,
+-			    "Can't open %s", path);
+-			r = ARCHIVE_WARN;
++	if (mtree->checkfs) {
++		/*
++		 * Try to open and stat the file to get the real size
++		 * and other file info.  It would be nice to avoid
++		 * this here so that getting a listing of an mtree
++		 * wouldn't require opening every referenced contents
++		 * file.  But then we wouldn't know the actual
++		 * contents size, so I don't see a really viable way
++		 * around this.  (Also, we may want to someday pull
++		 * other unspecified info from the contents file on
++		 * disk.)
++		 */
++		mtree->fd = -1;
++		if (archive_strlen(&mtree->contents_name) > 0)
++			path = mtree->contents_name.s;
++		else
++			path = archive_entry_pathname(entry);
++
++		if (archive_entry_filetype(entry) == AE_IFREG ||
++				archive_entry_filetype(entry) == AE_IFDIR) {
++			mtree->fd = open(path, O_RDONLY | O_BINARY | O_CLOEXEC);
++			__archive_ensure_cloexec_flag(mtree->fd);
++			if (mtree->fd == -1 &&
++					(errno != ENOENT ||
++					 archive_strlen(&mtree->contents_name) > 0)) {
++				archive_set_error(&a->archive, errno,
++						"Can't open %s", path);
++				r = ARCHIVE_WARN;
++			}
+ 		}
+-	}
+ 
+-	st = &st_storage;
+-	if (mtree->fd >= 0) {
+-		if (fstat(mtree->fd, st) == -1) {
+-			archive_set_error(&a->archive, errno,
+-			    "Could not fstat %s", path);
+-			r = ARCHIVE_WARN;
+-			/* If we can't stat it, don't keep it open. */
+-			close(mtree->fd);
+-			mtree->fd = -1;
++		st = &st_storage;
++		if (mtree->fd >= 0) {
++			if (fstat(mtree->fd, st) == -1) {
++				archive_set_error(&a->archive, errno,
++						"Could not fstat %s", path);
++				r = ARCHIVE_WARN;
++				/* If we can't stat it, don't keep it open. */
++				close(mtree->fd);
++				mtree->fd = -1;
++				st = NULL;
++			}
++		} else if (lstat(path, st) == -1) {
+ 			st = NULL;
+ 		}
+-	} else if (lstat(path, st) == -1) {
+-		st = NULL;
+-	}
+ 
+-	/*
+-	 * Check for a mismatch between the type in the specification and
+-	 * the type of the contents object on disk.
+-	 */
+-	if (st != NULL) {
+-		if (
+-		    ((st->st_mode & S_IFMT) == S_IFREG &&
+-		     archive_entry_filetype(entry) == AE_IFREG)
++		/*
++		 * Check for a mismatch between the type in the specification and
++		 * the type of the contents object on disk.
++		 */
++		if (st != NULL) {
++			if (
++					((st->st_mode & S_IFMT) == S_IFREG &&
++					 archive_entry_filetype(entry) == AE_IFREG)
+ #ifdef S_IFLNK
+-		    || ((st->st_mode & S_IFMT) == S_IFLNK &&
+-			archive_entry_filetype(entry) == AE_IFLNK)
++					|| ((st->st_mode & S_IFMT) == S_IFLNK &&
++						archive_entry_filetype(entry) == AE_IFLNK)
+ #endif
+ #ifdef S_IFSOCK
+-		    || ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
+-			archive_entry_filetype(entry) == AE_IFSOCK)
++					|| ((st->st_mode & S_IFSOCK) == S_IFSOCK &&
++						archive_entry_filetype(entry) == AE_IFSOCK)
+ #endif
+ #ifdef S_IFCHR
+-		    || ((st->st_mode & S_IFMT) == S_IFCHR &&
+-			archive_entry_filetype(entry) == AE_IFCHR)
++					|| ((st->st_mode & S_IFMT) == S_IFCHR &&
++						archive_entry_filetype(entry) == AE_IFCHR)
+ #endif
+ #ifdef S_IFBLK
+-		    || ((st->st_mode & S_IFMT) == S_IFBLK &&
+-			archive_entry_filetype(entry) == AE_IFBLK)
++					|| ((st->st_mode & S_IFMT) == S_IFBLK &&
++						archive_entry_filetype(entry) == AE_IFBLK)
+ #endif
+-		    || ((st->st_mode & S_IFMT) == S_IFDIR &&
+-			archive_entry_filetype(entry) == AE_IFDIR)
++					|| ((st->st_mode & S_IFMT) == S_IFDIR &&
++						archive_entry_filetype(entry) == AE_IFDIR)
+ #ifdef S_IFIFO
+-		    || ((st->st_mode & S_IFMT) == S_IFIFO &&
+-			archive_entry_filetype(entry) == AE_IFIFO)
++					|| ((st->st_mode & S_IFMT) == S_IFIFO &&
++							archive_entry_filetype(entry) == AE_IFIFO)
+ #endif
+-		    ) {
+-			/* Types match. */
+-		} else {
+-			/* Types don't match; bail out gracefully. */
+-			if (mtree->fd >= 0)
+-				close(mtree->fd);
+-			mtree->fd = -1;
+-			if (parsed_kws & MTREE_HAS_OPTIONAL) {
+-				/* It's not an error for an optional entry
+-				   to not match disk. */
+-				*use_next = 1;
+-			} else if (r == ARCHIVE_OK) {
+-				archive_set_error(&a->archive,
+-				    ARCHIVE_ERRNO_MISC,
+-				    "mtree specification has different type for %s",
+-				    archive_entry_pathname(entry));
+-				r = ARCHIVE_WARN;
+-			}
+-			return r;
++					) {
++						/* Types match. */
++					} else {
++						/* Types don't match; bail out gracefully. */
++						if (mtree->fd >= 0)
++							close(mtree->fd);
++						mtree->fd = -1;
++						if (parsed_kws & MTREE_HAS_OPTIONAL) {
++							/* It's not an error for an optional entry
++							   to not match disk. */
++							*use_next = 1;
++						} else if (r == ARCHIVE_OK) {
++							archive_set_error(&a->archive,
++									ARCHIVE_ERRNO_MISC,
++									"mtree specification has different type for %s",
++									archive_entry_pathname(entry));
++							r = ARCHIVE_WARN;
++						}
++						return r;
++					}
+ 		}
+-	}
+ 
+-	/*
+-	 * If there is a contents file on disk, pick some of the metadata
+-	 * from that file.  For most of these, we only set it from the contents
+-	 * if it wasn't already parsed from the specification.
+-	 */
+-	if (st != NULL) {
+-		if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
+-		     (parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
+-		    (archive_entry_filetype(entry) == AE_IFCHR ||
+-		     archive_entry_filetype(entry) == AE_IFBLK))
+-			archive_entry_set_rdev(entry, st->st_rdev);
+-		if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
+-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+-			archive_entry_set_gid(entry, st->st_gid);
+-		if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
+-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+-			archive_entry_set_uid(entry, st->st_uid);
+-		if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
+-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
++		/*
++		 * If there is a contents file on disk, pick some of the metadata
++		 * from that file.  For most of these, we only set it from the contents
++		 * if it wasn't already parsed from the specification.
++		 */
++		if (st != NULL) {
++			if (((parsed_kws & MTREE_HAS_DEVICE) == 0 ||
++						(parsed_kws & MTREE_HAS_NOCHANGE) != 0) &&
++					(archive_entry_filetype(entry) == AE_IFCHR ||
++					 archive_entry_filetype(entry) == AE_IFBLK))
++				archive_entry_set_rdev(entry, st->st_rdev);
++			if ((parsed_kws & (MTREE_HAS_GID | MTREE_HAS_GNAME)) == 0 ||
++					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
++				archive_entry_set_gid(entry, st->st_gid);
++			if ((parsed_kws & (MTREE_HAS_UID | MTREE_HAS_UNAME)) == 0 ||
++					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
++				archive_entry_set_uid(entry, st->st_uid);
++			if ((parsed_kws & MTREE_HAS_MTIME) == 0 ||
++					(parsed_kws & MTREE_HAS_NOCHANGE) != 0) {
+ #if HAVE_STRUCT_STAT_ST_MTIMESPEC_TV_NSEC
+-			archive_entry_set_mtime(entry, st->st_mtime,
+-			    st->st_mtimespec.tv_nsec);
++				archive_entry_set_mtime(entry, st->st_mtime,
++						st->st_mtimespec.tv_nsec);
+ #elif HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC
+-			archive_entry_set_mtime(entry, st->st_mtime,
+-			    st->st_mtim.tv_nsec);
++				archive_entry_set_mtime(entry, st->st_mtime,
++						st->st_mtim.tv_nsec);
+ #elif HAVE_STRUCT_STAT_ST_MTIME_N
+-			archive_entry_set_mtime(entry, st->st_mtime,
+-			    st->st_mtime_n);
++				archive_entry_set_mtime(entry, st->st_mtime,
++						st->st_mtime_n);
+ #elif HAVE_STRUCT_STAT_ST_UMTIME
+-			archive_entry_set_mtime(entry, st->st_mtime,
+-			    st->st_umtime*1000);
++				archive_entry_set_mtime(entry, st->st_mtime,
++						st->st_umtime*1000);
+ #elif HAVE_STRUCT_STAT_ST_MTIME_USEC
+-			archive_entry_set_mtime(entry, st->st_mtime,
+-			    st->st_mtime_usec*1000);
++				archive_entry_set_mtime(entry, st->st_mtime,
++						st->st_mtime_usec*1000);
+ #else
+-			archive_entry_set_mtime(entry, st->st_mtime, 0);
++				archive_entry_set_mtime(entry, st->st_mtime, 0);
+ #endif
++			}
++			if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
++					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
++				archive_entry_set_nlink(entry, st->st_nlink);
++			if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
++					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
++				archive_entry_set_perm(entry, st->st_mode);
++			if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
++					(parsed_kws & MTREE_HAS_NOCHANGE) != 0)
++				archive_entry_set_size(entry, st->st_size);
++			archive_entry_set_ino(entry, st->st_ino);
++			archive_entry_set_dev(entry, st->st_dev);
++
++			archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
++		} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
++			/*
++			 * Couldn't open the entry, stat it or the on-disk type
++			 * didn't match.  If this entry is optional, just ignore it
++			 * and read the next header entry.
++			 */
++			*use_next = 1;
++			return ARCHIVE_OK;
+ 		}
+-		if ((parsed_kws & MTREE_HAS_NLINK) == 0 ||
+-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+-			archive_entry_set_nlink(entry, st->st_nlink);
+-		if ((parsed_kws & MTREE_HAS_PERM) == 0 ||
+-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+-			archive_entry_set_perm(entry, st->st_mode);
+-		if ((parsed_kws & MTREE_HAS_SIZE) == 0 ||
+-		    (parsed_kws & MTREE_HAS_NOCHANGE) != 0)
+-			archive_entry_set_size(entry, st->st_size);
+-		archive_entry_set_ino(entry, st->st_ino);
+-		archive_entry_set_dev(entry, st->st_dev);
+-
+-		archive_entry_linkify(mtree->resolver, &entry, &sparse_entry);
+-	} else if (parsed_kws & MTREE_HAS_OPTIONAL) {
+-		/*
+-		 * Couldn't open the entry, stat it or the on-disk type
+-		 * didn't match.  If this entry is optional, just ignore it
+-		 * and read the next header entry.
+-		 */
+-		*use_next = 1;
+-		return ARCHIVE_OK;
+ 	}
+ 
+ 	mtree->cur_size = archive_entry_size(entry);
+diff --git a/libarchive/test/test_read_format_mtree.c b/libarchive/test/test_read_format_mtree.c
+index 830fa0a..f96529d 100644
+--- a/libarchive/test/test_read_format_mtree.c
++++ b/libarchive/test/test_read_format_mtree.c
+@@ -58,6 +58,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_filename(a, reffile, 11));
+ 
+ 	/*
+@@ -209,6 +211,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_memory(a, archive, sizeof(archive)));
+ 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ 	assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE);
+@@ -246,6 +250,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_memory(a, archive, sizeof(archive)));
+ 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ 	assertEqualString(archive_entry_pathname(ae), "a");
+@@ -299,6 +305,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_memory(a, archive, sizeof(archive)));
+ 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ 	assertEqualString(archive_entry_pathname(ae), "./a");	
+@@ -365,6 +373,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_memory(a, archive, sizeof(archive)));
+ 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ 	assertEqualString(archive_entry_pathname(ae), "./a");
+@@ -402,6 +412,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_memory(a, archive2, sizeof(archive2)));
+ 	assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ 	assertEqualString(archive_entry_pathname(ae), "./a");
+@@ -449,6 +461,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_filename(a, reffile, 11));
+ 
+ 	/*
+@@ -552,6 +566,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_filename(a, reffile, 11));
+ 
+ 	/*
+@@ -617,6 +633,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_filename(a, reffile, 11));
+ 
+ 	/*
+@@ -680,6 +698,8 @@
+ 	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_support_format_all(a));
+ 	assertEqualIntA(a, ARCHIVE_OK,
++	    archive_read_set_options(a, "mtree:checkfs"));
++	assertEqualIntA(a, ARCHIVE_OK,
+ 	    archive_read_open_memory(a, archive, sizeof(archive)));
+ 	assertEqualIntA(a, ARCHIVE_WARN, archive_read_next_header(a, &ae));
+ 	assert(strlen(archive_error_string(a)) > 0);
+diff --git a/tar/write.c b/tar/write.c
+index 40d2fb0..7e8cb13 100644
+--- a/tar/write.c
++++ b/tar/write.c
+@@ -648,6 +648,7 @@ static void		 write_hierarchy(struct bsdtar *, struct archive *,
+ 	archive_read_support_format_all(ina);
+ 	archive_read_support_filter_all(ina);
+ 	set_reader_options(bsdtar, a);
++	archive_read_set_options(ina, "mtree:checkfs");
+ 	if (archive_read_open_filename(ina, filename,
+ 					bsdtar->bytes_per_block)) {
+ 		lafe_warnc(0, "%s", archive_error_string(ina));
+-- 
+1.8.5.5
+


More information about the patches mailing list