Merge branch 'vu862384'

Fixes Issue 656
Fixes CVE-2016-1541
Fixes VU#862384
Fixes TALOS-CAN-155
diff --git a/CMakeLists.txt b/CMakeLists.txt
index eedcd23..4b97039 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -204,7 +204,7 @@
 
 SET(POSIX_REGEX_LIB "AUTO" CACHE STRING "Choose what library should provide POSIX regular expression support")
 SET(ENABLE_SAFESEH "AUTO" CACHE STRING "Enable use of /SAFESEH linker flag (MSVC only)")
-SET(WINDOWS_VERSION "" CACHE STRING "Set Windows version to use (Windows only)")
+SET(WINDOWS_VERSION "WIN7" CACHE STRING "Set Windows version to use (Windows only)")
 
 IF(ENABLE_COVERAGE)
 	include(LibarchiveCodeCoverage)
@@ -216,22 +216,35 @@
 
 IF(WIN32)
   IF(WINDOWS_VERSION STREQUAL "WIN8")
+    SET(NTDDI_VERSION 0x06020000)
+    SET(_WIN32_WINNT 0x0602)
     SET(WINVER 0x0602)
   ELSEIF(WINDOWS_VERSION STREQUAL "WIN7")
+    SET(NTDDI_VERSION 0x06010000)
+    SET(_WIN32_WINNT 0x0601)
     SET(WINVER 0x0601)
   ELSEIF(WINDOWS_VERSION STREQUAL "WS08")
+    SET(NTDDI_VERSION 0x06000100)
+    SET(_WIN32_WINNT 0x0600)
     SET(WINVER 0x0600)
   ELSEIF(WINDOWS_VERSION STREQUAL "VISTA")
+    SET(NTDDI_VERSION 0x06000000)
+    SET(_WIN32_WINNT 0x0600)
     SET(WINVER 0x0600)
   ELSEIF(WINDOWS_VERSION STREQUAL "WS03")
+    SET(NTDDI_VERSION 0x05020000)
+    SET(_WIN32_WINNT 0x0502)
     SET(WINVER 0x0502)
   ELSEIF(WINDOWS_VERSION STREQUAL "WINXP")
+    SET(NTDDI_VERSION 0x05010000)
+    SET(_WIN32_WINNT 0x0501)
     SET(WINVER 0x0501)
   ELSE(WINDOWS_VERSION STREQUAL "WIN8")
-    # The default is to use Windows 2000 API.
-    SET(WINVER 0x0500)
+    # Default to Windows Server 2003 API if we don't recognize the specifier
+    SET(NTDDI_VERSION 0x05020000)
+    SET(_WIN32_WINNT 0x0502)
+    SET(WINVER 0x0502)
   ENDIF(WINDOWS_VERSION STREQUAL "WIN8")
-  SET(_WIN32_WINNT ${WINVER})
 ENDIF(WIN32)
 
 IF(MSVC)
diff --git a/build/cmake/config.h.in b/build/cmake/config.h.in
index 94fbb59..64f4d4d 100644
--- a/build/cmake/config.h.in
+++ b/build/cmake/config.h.in
@@ -1171,7 +1171,11 @@
 /* Define for large files, on AIX-style hosts. */
 #cmakedefine _LARGE_FILES ${_LARGE_FILES}
 
-/* Define for Windows to use Windows 2000+ APIs. */
+/* Define to control Windows SDK version */
+#ifndef NTDDI_VERSION
+#cmakedefine NTDDI_VERSION ${NTDDI_VERSION}
+#endif // NTDDI_VERSION
+
 #ifndef _WIN32_WINNT
 #cmakedefine _WIN32_WINNT ${_WIN32_WINNT}
 #endif // _WIN32_WINNT
diff --git a/cat/test/main.c b/cat/test/main.c
index 8c414da..319f68c 100644
--- a/cat/test/main.c
+++ b/cat/test/main.c
@@ -780,6 +780,34 @@
 	return (0);
 }
 
+/* Verify that a block of memory is filled with the specified byte. */
+int
+assertion_memory_filled_with(const char *file, int line,
+    const void *_v1, const char *vd,
+    size_t l, const char *ld,
+    char b, const char *bd, void *extra)
+{
+	const char *v1 = (const char *)_v1;
+	size_t c = 0;
+	size_t i;
+	(void)ld; /* UNUSED */
+
+	assertion_count(file, line);
+
+	for (i = 0; i < l; ++i) {
+		if (v1[i] == b) {
+			++c;
+		}
+	}
+	if (c == l)
+		return (1);
+
+	failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
+	logprintf("   Only %d bytes were correct\n", (int)c);
+	failure_finish(extra);
+	return (0);
+}
+
 /* Verify that the named file exists and is empty. */
 int
 assertion_empty_file(const char *filename, int line, const char *f1)
@@ -2276,7 +2304,10 @@
 	/* Not a lot of error checking here; the input better be right. */
 	out = fopen(name, "wb");
 	while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
-		fwrite(buff, 1, rbytes, out);
+		if (fwrite(buff, 1, rbytes, out) != rbytes) {
+			logprintf("Error: fwrite\n");
+			break;
+		}
 	}
 	fclose(out);
 	fclose(in);
diff --git a/cat/test/test_error.c b/cat/test/test_error.c
index 20d7535..918af01 100644
--- a/cat/test/test_error.c
+++ b/cat/test/test_error.c
@@ -29,7 +29,7 @@
 	const char *reffile = "test_expand.error";
 
 	assertFileNotExists(reffile);
-	assertEqualInt(256, systemf("%s %s >test.out 2>test.err", testprog, reffile));
+	assert(0 != systemf("%s %s >test.out 2>test.err", testprog, reffile));
 
 	assertEmptyFile("test.out");
 	assertNonEmptyFile("test.err");
diff --git a/cat/test/test_error_mixed.c b/cat/test/test_error_mixed.c
index ac01e2e..7d94fce 100644
--- a/cat/test/test_error_mixed.c
+++ b/cat/test/test_error_mixed.c
@@ -33,7 +33,7 @@
 	assertFileNotExists(reffile2);
 	extract_reference_file(reffile1);
 	extract_reference_file(reffile3);
-	assertEqualInt(256, systemf("%s %s %s %s >test.out 2>test.err",
+	assert(0 != systemf("%s %s %s %s >test.out 2>test.err",
 	    testprog, reffile1, reffile2, reffile3));
 
 	assertTextFileContents(
diff --git a/configure.ac b/configure.ac
index d352991..ca8bf6b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -243,8 +243,9 @@
 # Set up defines needed before including any headers
 case $host in
   *mingw* | *cygwin* )
-  AC_DEFINE([_WIN32_WINNT], 0x0500, [Define to '0x0500' for Windows 2000 APIs.])
-  AC_DEFINE([WINVER], 0x0500, [Define to '0x0500' for Windows 2000 APIs.])
+  AC_DEFINE([_WIN32_WINNT], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.])
+  AC_DEFINE([WINVER], 0x0502, [Define to '0x0502' for Windows Server 2003 APIs.])
+  AC_DEFINE([NTDDI_VERSION], 0x05020000, [Define to '0x05020000' for Windows Server 2003 APIs.])
   ;;
 esac
 
@@ -365,7 +366,17 @@
 if test "x$with_lzma" != "xno"; then
   AC_CHECK_HEADERS([lzma.h])
   AC_CHECK_LIB(lzma,lzma_stream_decoder)
-  AC_CHECK_FUNCS([lzma_stream_encoder_mt])
+  # Some pre-release (but widely distributed) versions of liblzma
+  # included a disabled version of lzma_stream_encoder_mt that
+  # fools a naive AC_CHECK_LIB or AC_CHECK_FUNC, so we need
+  # to do something more complex here:
+  AC_CACHE_CHECK(
+    [whether we have multithread support in lzma],
+    ac_cv_lzma_has_mt,
+    [AC_COMPILE_IFELSE([
+      AC_LANG_PROGRAM([[#include <lzma.h>]],
+                      [[lzma_stream_encoder_mt(0, 0);]])],
+      [ac_cv_lzma_has_mt=yes], [ac_cv_lzma_has_mt=no])])
 fi
 
 AC_ARG_WITH([lzo2],
diff --git a/cpio/test/main.c b/cpio/test/main.c
index 5801127..fa22adf 100644
--- a/cpio/test/main.c
+++ b/cpio/test/main.c
@@ -781,6 +781,34 @@
 	return (0);
 }
 
+/* Verify that a block of memory is filled with the specified byte. */
+int
+assertion_memory_filled_with(const char *file, int line,
+    const void *_v1, const char *vd,
+    size_t l, const char *ld,
+    char b, const char *bd, void *extra)
+{
+	const char *v1 = (const char *)_v1;
+	size_t c = 0;
+	size_t i;
+	(void)ld; /* UNUSED */
+
+	assertion_count(file, line);
+
+	for (i = 0; i < l; ++i) {
+		if (v1[i] == b) {
+			++c;
+		}
+	}
+	if (c == l)
+		return (1);
+
+	failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
+	logprintf("   Only %d bytes were correct\n", (int)c);
+	failure_finish(extra);
+	return (0);
+}
+
 /* Verify that the named file exists and is empty. */
 int
 assertion_empty_file(const char *filename, int line, const char *f1)
@@ -2277,7 +2305,10 @@
 	/* Not a lot of error checking here; the input better be right. */
 	out = fopen(name, "wb");
 	while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
-		fwrite(buff, 1, rbytes, out);
+		if (fwrite(buff, 1, rbytes, out) != rbytes) {
+			logprintf("Error: fwrite\n");
+			break;
+		}
 	}
 	fclose(out);
 	fclose(in);
diff --git a/examples/minitar/Makefile b/examples/minitar/Makefile
index 1ec4593..e2cc089 100644
--- a/examples/minitar/Makefile
+++ b/examples/minitar/Makefile
@@ -8,13 +8,19 @@
 	-I../../libarchive	\
 	-g
 
+#
+# You may need to add additional libraries or link options here
+# For example, many Linux systems require -lacl
+#
+LIBS= -lz -lbz2
+
 # How to link against libarchive.
 LIBARCHIVE=	../../libarchive/libarchive.a
 
 all: minitar
 
 minitar: minitar.o
-	cc -g -o minitar minitar.o $(LIBARCHIVE) -lz -lbz2
+	cc -g -o minitar minitar.o $(LIBARCHIVE) $(LIBS)
 	strip minitar
 	ls -l minitar
 
diff --git a/libarchive/archive.h b/libarchive/archive.h
index 92515d8..548db21 100644
--- a/libarchive/archive.h
+++ b/libarchive/archive.h
@@ -41,6 +41,7 @@
 #include <sys/stat.h>
 #include <stddef.h>  /* for wchar_t */
 #include <stdio.h> /* For FILE * */
+#include <time.h> /* For time_t */
 
 /*
  * Note: archive.h is for use outside of libarchive; the configuration
diff --git a/libarchive/archive_string.c b/libarchive/archive_string.c
index 3d4be82..282c58e 100644
--- a/libarchive/archive_string.c
+++ b/libarchive/archive_string.c
@@ -737,7 +737,8 @@
 			}
 			if (count == 0)
 				ret = -1;
-		} while (0);
+			break;
+		} while (1);
 	}
 	as->length += count;
 	as->s[as->length] = '\0';
diff --git a/libarchive/test/main.c b/libarchive/test/main.c
index 8561129..e0af431 100644
--- a/libarchive/test/main.c
+++ b/libarchive/test/main.c
@@ -2303,7 +2303,10 @@
 	/* Not a lot of error checking here; the input better be right. */
 	out = fopen(name, "wb");
 	while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
-		fwrite(buff, 1, rbytes, out);
+		if (fwrite(buff, 1, rbytes, out) != rbytes) {
+			logprintf("Error: fwrite\n");
+			break;
+		}
 	}
 	fclose(out);
 	fclose(in);
diff --git a/libarchive/test/test_sparse_basic.c b/libarchive/test/test_sparse_basic.c
index e5dd2f7..3cea459 100644
--- a/libarchive/test/test_sparse_basic.c
+++ b/libarchive/test/test_sparse_basic.c
@@ -301,7 +301,7 @@
 		/* Block that overlaps beginning of data */
 		if (expected_offset < offset
 		    && expected_offset + (int64_t)sparse->size <= offset + (int64_t)bytes_read) {
-			const char *end = buff + (expected_offset - offset) + (size_t)sparse->size;
+			const char *end = (const char *)buff + (expected_offset - offset) + (size_t)sparse->size;
 #if DEBUG
 			fprintf(stderr, "    overlapping hole expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size);
 #endif
@@ -315,7 +315,7 @@
 		}
 		/* Blocks completely contained in data we just read. */
 		while (expected_offset + (int64_t)sparse->size <= offset + (int64_t)bytes_read) {
-			const char *end = buff + (expected_offset - offset) + (size_t)sparse->size;
+			const char *end = (const char *)buff + (expected_offset - offset) + (size_t)sparse->size;
 			if (sparse->type == HOLE) {
 #if DEBUG
 				fprintf(stderr, "    contained hole expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size);
@@ -323,7 +323,7 @@
 
 				/* verify data corresponding to hole is '\0' */
 				if (end > (const char *)buff + bytes_read) {
-					end = buff + bytes_read;
+					end = (const char *)buff + bytes_read;
 				}
 				assertMemoryFilledWith(start, end - start, '\0');
 				start = end;
@@ -335,7 +335,7 @@
 #endif
 				/* verify data corresponding to hole is ' ' */
 				if (assert(expected_offset + sparse->size <= offset + bytes_read)) {
-					assert(start == buff + (size_t)(expected_offset - offset));
+					assert(start == (const char *)buff + (size_t)(expected_offset - offset));
 					assertMemoryFilledWith(start, end - start, ' ');
 				}
 				start = end;
@@ -347,7 +347,7 @@
 		}
 		/* Block that overlaps end of data */
 		if (expected_offset < offset + (int64_t)bytes_read) {
-			const char *end = buff + bytes_read;
+			const char *end = (const char *)buff + bytes_read;
 #if DEBUG
 			fprintf(stderr, "    trailing overlap expected_offset=%d, size=%d\n", (int)expected_offset, (int)sparse->size);
 #endif
diff --git a/libarchive/test/test_write_format_cpio_newc.c b/libarchive/test/test_write_format_cpio_newc.c
index 3bbc173..48b0b26 100644
--- a/libarchive/test/test_write_format_cpio_newc.c
+++ b/libarchive/test/test_write_format_cpio_newc.c
@@ -30,7 +30,7 @@
 is_hex(const char *p, size_t l)
 {
 	while (l > 0) {
-		if (*p >= 0 && *p <= '9') {
+		if (*p >= '0' && *p <= '9') {
 			/* Ascii digit */
 		} else if (*p >= 'a' && *p <= 'f') {
 			/* lowercase letter a-f */
diff --git a/tar/test/main.c b/tar/test/main.c
index 33a6364..90801a9 100644
--- a/tar/test/main.c
+++ b/tar/test/main.c
@@ -781,6 +781,34 @@
 	return (0);
 }
 
+/* Verify that a block of memory is filled with the specified byte. */
+int
+assertion_memory_filled_with(const char *file, int line,
+    const void *_v1, const char *vd,
+    size_t l, const char *ld,
+    char b, const char *bd, void *extra)
+{
+	const char *v1 = (const char *)_v1;
+	size_t c = 0;
+	size_t i;
+	(void)ld; /* UNUSED */
+
+	assertion_count(file, line);
+
+	for (i = 0; i < l; ++i) {
+		if (v1[i] == b) {
+			++c;
+		}
+	}
+	if (c == l)
+		return (1);
+
+	failure_start(file, line, "%s (size %d) not filled with %s", vd, (int)l, bd);
+	logprintf("   Only %d bytes were correct\n", (int)c);
+	failure_finish(extra);
+	return (0);
+}
+
 /* Verify that the named file exists and is empty. */
 int
 assertion_empty_file(const char *filename, int line, const char *f1)
@@ -2277,7 +2305,10 @@
 	/* Not a lot of error checking here; the input better be right. */
 	out = fopen(name, "wb");
 	while ((rbytes = fread(buff, 1, sizeof(buff), in)) > 0) {
-		fwrite(buff, 1, rbytes, out);
+		if (fwrite(buff, 1, rbytes, out) != rbytes) {
+			logprintf("Error: fwrite\n");
+			break;
+		}
 	}
 	fclose(out);
 	fclose(in);
diff --git a/tar/test/test_leading_slash.c b/tar/test/test_leading_slash.c
index 52646d0..a8921eb 100644
--- a/tar/test/test_leading_slash.c
+++ b/tar/test/test_leading_slash.c
@@ -28,6 +28,9 @@
 DEFINE_TEST(test_leading_slash)
 {
 	const char *reffile = "test_leading_slash.tar";
+	char *errfile;
+	size_t errfile_size;
+	const char *expected_errmsg = "Removing leading '/' from member names";
 
 	extract_reference_file(reffile);
 	assertEqualInt(0, systemf("%s -xf %s >test.out 2>test.err", testprog, reffile));
@@ -36,10 +39,11 @@
 	assertTextFileContents("foo\x0a", "foo/hardlink");
 	assertIsHardlink("foo/file", "foo/hardlink");
 	assertEmptyFile("test.out");
-#ifdef _WIN32
-	assertTextFileContents("bsdtar.exe: Removing leading '/' from member names\x0a", "test.err");
-#else
-	assertTextFileContents("bsdtar: Removing leading '/' from member names\x0a", "test.err");
-#endif
+
+	/* Verify the error output contains the expected text somewhere in it */
+	if (assertFileExists("test.err")) {
+		errfile = slurpfile(&errfile_size, "test.err");
+		assert(strstr(errfile, expected_errmsg) != NULL);
+	}
 }