From fa94194ff849f6933fedb15396e96731eb2c4157 Mon Sep 17 00:00:00 2001 From: kientzle Date: Wed, 30 Dec 2009 05:59:21 +0000 Subject: A raft of test changes and improvements from the Googlecode repository. In particular, this includes tests for the new features I've merged over the last few days. --- lib/libarchive/test/Makefile | 27 +- lib/libarchive/test/main.c | 2035 ++++++++++++++------ lib/libarchive/test/test.h | 227 ++- lib/libarchive/test/test_acl_pax.c | 14 +- lib/libarchive/test/test_compat_bzip2.c | 5 +- lib/libarchive/test/test_compat_cpio.c | 106 + lib/libarchive/test/test_compat_cpio_1.cpio.uu | 19 + lib/libarchive/test/test_compat_lzma.c | 155 ++ lib/libarchive/test/test_compat_lzma_1.tlz.uu | 10 + lib/libarchive/test/test_compat_lzma_2.tlz.uu | 9 + lib/libarchive/test/test_compat_lzma_3.tlz.uu | 9 + lib/libarchive/test/test_compat_solaris_tar_acl.c | 6 +- lib/libarchive/test/test_entry.c | 37 +- lib/libarchive/test/test_entry_strmode.c | 16 +- lib/libarchive/test/test_extattr_freebsd.c | 16 +- lib/libarchive/test/test_fuzz.c | 132 +- lib/libarchive/test/test_fuzz_1.iso.Z.uu | 495 +++++ lib/libarchive/test/test_open_fd.c | 13 +- lib/libarchive/test/test_open_file.c | 4 +- lib/libarchive/test/test_pax_filename_encoding.c | 30 +- lib/libarchive/test/test_read_compress_program.c | 14 +- lib/libarchive/test/test_read_data_large.c | 22 +- lib/libarchive/test/test_read_disk.c | 6 +- .../test/test_read_disk_entry_from_file.c | 10 +- lib/libarchive/test/test_read_extract.c | 108 +- lib/libarchive/test/test_read_format_ar.ar.uu | 12 + lib/libarchive/test/test_read_format_ar.c | 42 +- .../test/test_read_format_cpio_bin_bz2.c | 9 +- .../test/test_read_format_cpio_bin_lzma.c | 60 + lib/libarchive/test/test_read_format_iso.iso.Z.uu | 26 + lib/libarchive/test/test_read_format_iso_gz.c | 11 +- .../test/test_read_format_iso_joliet.iso.Z.uu | 66 + .../test/test_read_format_iso_joliet_long.iso.Z.uu | 71 + .../test_read_format_iso_joliet_rockridge.iso.Z.uu | 68 + .../test/test_read_format_iso_multi_extent.c | 94 + .../test_read_format_iso_multi_extent.iso.Z.uu | 67 + .../test/test_read_format_iso_rockridge.iso.Z.uu | 206 ++ .../test_read_format_iso_rockridge_ce.iso.Z.uu | 63 + .../test_read_format_iso_rockridge_new.iso.Z.uu | 208 ++ ...est_read_format_iso_rockridge_rr_moved.iso.Z.uu | 304 +++ .../test/test_read_format_iso_zisofs.iso.Z.uu | 63 + .../test/test_read_format_isojoliet_bz2.c | 96 +- .../test/test_read_format_isojoliet_long.c | 141 ++ .../test/test_read_format_isojoliet_rr.c | 159 ++ lib/libarchive/test/test_read_format_isorr_bz2.c | 214 +- lib/libarchive/test/test_read_format_isorr_ce.c | 223 +++ .../test/test_read_format_isorr_new_bz2.c | 204 ++ .../test/test_read_format_isorr_rr_moved.c | 270 +++ .../test/test_read_format_isozisofs_bz2.c | 187 ++ lib/libarchive/test/test_read_format_mtree.c | 86 +- .../test/test_read_format_mtree.mtree.uu | 13 + lib/libarchive/test/test_read_format_pax_bz2.c | 8 +- lib/libarchive/test/test_read_format_tar.c | 18 +- lib/libarchive/test/test_read_format_tbz.c | 8 +- lib/libarchive/test/test_read_format_tlz.c | 60 + lib/libarchive/test/test_read_large.c | 35 +- lib/libarchive/test/test_tar_large.c | 2 +- lib/libarchive/test/test_write_compress_program.c | 13 +- lib/libarchive/test/test_write_disk.c | 63 +- lib/libarchive/test/test_write_disk_failures.c | 6 +- lib/libarchive/test/test_write_disk_hardlink.c | 110 +- lib/libarchive/test/test_write_disk_perms.c | 6 +- lib/libarchive/test/test_write_disk_secure.c | 13 +- lib/libarchive/test/test_write_disk_sparse.c | 36 +- lib/libarchive/test/test_write_disk_symlink.c | 117 ++ lib/libarchive/test/test_write_disk_times.c | 68 +- lib/libarchive/test/test_write_format_cpio_empty.c | 2 +- lib/libarchive/test/test_write_format_cpio_newc.c | 11 +- lib/libarchive/test/test_write_format_cpio_odc.c | 27 +- lib/libarchive/test/test_write_format_tar_ustar.c | 3 +- lib/libarchive/test/test_write_format_zip.c | 180 ++ lib/libarchive/test/test_write_format_zip_empty.c | 56 + .../test/test_write_format_zip_no_compression.c | 304 +++ 73 files changed, 6293 insertions(+), 1341 deletions(-) create mode 100644 lib/libarchive/test/test_compat_cpio.c create mode 100644 lib/libarchive/test/test_compat_cpio_1.cpio.uu create mode 100644 lib/libarchive/test/test_compat_lzma.c create mode 100644 lib/libarchive/test/test_compat_lzma_1.tlz.uu create mode 100644 lib/libarchive/test/test_compat_lzma_2.tlz.uu create mode 100644 lib/libarchive/test/test_compat_lzma_3.tlz.uu create mode 100644 lib/libarchive/test/test_fuzz_1.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_ar.ar.uu create mode 100644 lib/libarchive/test/test_read_format_cpio_bin_lzma.c create mode 100644 lib/libarchive/test/test_read_format_iso.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_multi_extent.c create mode 100644 lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_rockridge_ce.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_rockridge_rr_moved.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu create mode 100644 lib/libarchive/test/test_read_format_isojoliet_long.c create mode 100644 lib/libarchive/test/test_read_format_isojoliet_rr.c create mode 100644 lib/libarchive/test/test_read_format_isorr_ce.c create mode 100644 lib/libarchive/test/test_read_format_isorr_new_bz2.c create mode 100644 lib/libarchive/test/test_read_format_isorr_rr_moved.c create mode 100644 lib/libarchive/test/test_read_format_isozisofs_bz2.c create mode 100644 lib/libarchive/test/test_read_format_mtree.mtree.uu create mode 100644 lib/libarchive/test/test_read_format_tlz.c create mode 100644 lib/libarchive/test/test_write_disk_symlink.c create mode 100644 lib/libarchive/test/test_write_format_zip.c create mode 100644 lib/libarchive/test/test_write_format_zip_empty.c create mode 100644 lib/libarchive/test/test_write_format_zip_no_compression.c (limited to 'lib/libarchive') diff --git a/lib/libarchive/test/Makefile b/lib/libarchive/test/Makefile index dec95fd..4d88151 100644 --- a/lib/libarchive/test/Makefile +++ b/lib/libarchive/test/Makefile @@ -14,8 +14,10 @@ TESTS= \ test_archive_api_feature.c \ test_bad_fd.c \ test_compat_bzip2.c \ + test_compat_cpio.c \ test_compat_gtar.c \ test_compat_gzip.c \ + test_compat_lzma.c \ test_compat_solaris_tar_acl.c \ test_compat_tar_hardlink.c \ test_compat_xz.c \ @@ -42,6 +44,7 @@ TESTS= \ test_read_format_cpio_bin_be.c \ test_read_format_cpio_bin_bz2.c \ test_read_format_cpio_bin_gz.c \ + test_read_format_cpio_bin_lzma.c \ test_read_format_cpio_bin_xz.c \ test_read_format_cpio_odc.c \ test_read_format_cpio_svr4_gzip.c \ @@ -51,8 +54,15 @@ TESTS= \ test_read_format_gtar_lzma.c \ test_read_format_gtar_sparse.c \ test_read_format_iso_gz.c \ + test_read_format_iso_multi_extent.c \ + test_read_format_isorr_rr_moved.c \ test_read_format_isojoliet_bz2.c \ + test_read_format_isojoliet_long.c \ + test_read_format_isojoliet_rr.c \ test_read_format_isorr_bz2.c \ + test_read_format_isorr_ce.c \ + test_read_format_isorr_new_bz2.c \ + test_read_format_isozisofs_bz2.c \ test_read_format_mtree.c \ test_read_format_pax_bz2.c \ test_read_format_raw.c \ @@ -60,6 +70,7 @@ TESTS= \ test_read_format_tar_empty_filename.c \ test_read_format_tbz.c \ test_read_format_tgz.c \ + test_read_format_tlz.c \ test_read_format_txz.c \ test_read_format_tz.c \ test_read_format_zip.c \ @@ -82,6 +93,7 @@ TESTS= \ test_write_disk_perms.c \ test_write_disk_secure.c \ test_write_disk_sparse.c \ + test_write_disk_symlink.c \ test_write_disk_times.c \ test_write_format_ar.c \ test_write_format_cpio.c \ @@ -94,6 +106,9 @@ TESTS= \ test_write_format_tar.c \ test_write_format_tar_empty.c \ test_write_format_tar_ustar.c \ + test_write_format_zip.c \ + test_write_format_zip_empty.c \ + test_write_format_zip_no_compression.c \ test_write_open_memory.c @@ -108,16 +123,12 @@ NO_MAN=yes PROG=libarchive_test INTERNALPROG=yes # Don't install this; it's just for testing -DPADD=${LIBBZ2} ${LIBZ} +DPADD=${LIBBZ2} ${LIBZ} ${LIBMD} ${LIBCRYPTO} ${LIBBSDXML} CFLAGS+= -DPLATFORM_CONFIG_H=\"config_freebsd.h\" -LDADD= -lz -lbz2 -lmd -lcrypto +LDADD= -lz -lbz2 -lmd -lcrypto -lbsdxml CFLAGS+= -g CFLAGS+= -I${LA_SRCDIR} -I. -# Uncomment to build and test lzma support via liblzmadec -#CFLAGS+= -I/usr/local/include -DHAVE_LIBLZMADEC=1 -DHAVE_LZMADEC_H=1 -#LDADD+= -L/usr/local/lib -llzmadec - # Uncomment to build and test lzma and xz support via liblzma #CFLAGS+= -I/usr/local/include -DHAVE_LIBLZMA=1 -DHAVE_LZMA_H=1 #LDADD+= -L/usr/local/lib -llzma @@ -125,11 +136,11 @@ CFLAGS+= -I${LA_SRCDIR} -I. # Uncomment to link against dmalloc #LDADD+= -L/usr/local/lib -ldmalloc #CFLAGS+= -I/usr/local/include -DUSE_DMALLOC -WARNS=6 +#WARNS=6 # Build libarchive_test and run it. check test: libarchive_test - ./libarchive_test -v -r ${.CURDIR} + ./libarchive_test -r ${.CURDIR} # list.h is just a list of all tests, as indicated by DEFINE_TEST macro lines list.h: ${TESTS} Makefile diff --git a/lib/libarchive/test/main.c b/lib/libarchive/test/main.c index 0d16c81..5f8cbc3 100644 --- a/lib/libarchive/test/main.c +++ b/lib/libarchive/test/main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2003-2009 Tim Kientzle * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,74 +23,142 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/* - * Various utility routines useful for test programs. - * Each test program is linked against this file. - */ #include "test.h" - #include #include #include #include -#if defined(_WIN32) && !defined(__CYGWIN__) -#include -#include -#include -#endif /* * This same file is used pretty much verbatim for all test harnesses. * * The next few lines are the only differences. + * TODO: Move this into a separate configuration header, have all test + * suites share one copy of this file. */ +__FBSDID("$FreeBSD$"); +#define KNOWNREF "test_compat_gtar_1.tar.uu" +#define ENVBASE "LIBARCHIVE" /* Prefix for environment variables. */ #undef PROGRAM /* Testing a library, not a program. */ #define LIBRARY "libarchive" -#define ENVBASE "LIBARCHIVE" /* Prefix for environment variables. */ #define EXTRA_DUMP(x) archive_error_string((struct archive *)(x)) #define EXTRA_VERSION archive_version() -#define KNOWNREF "test_compat_gtar_1.tar.uu" -__FBSDID("$FreeBSD$"); /* - * "list.h" is simply created by "grep DEFINE_TEST"; it has - * a line like - * DEFINE_TEST(test_function) - * for each test. - * Include it here with a suitable DEFINE_TEST to declare all of the - * test functions. + * + * Windows support routines + * + * Note: Configuration is a tricky issue. Using HAVE_* feature macros + * in the test harness is dangerous because they cover up + * configuration errors. The classic example of this is omitting a + * configure check. If libarchive and libarchive_test both look for + * the same feature macro, such errors are hard to detect. Platform + * macros (e.g., _WIN32 or __GNUC__) are a little better, but can + * easily lead to very messy code. It's best to limit yourself + * to only the most generic programming techniques in the test harness + * and thus avoid conditionals altogether. Where that's not possible, + * try to minimize conditionals by grouping platform-specific tests in + * one place (e.g., test_acl_freebsd) or by adding new assert() + * functions (e.g., assertMakeHardlink()) to cover up platform + * differences. Platform-specific coding in libarchive_test is often + * a symptom that some capability is missing from libarchive itself. */ -#undef DEFINE_TEST -#define DEFINE_TEST(name) void name(void); -#include "list.h" +#if defined(_WIN32) && !defined(__CYGWIN__) +#include +#include +#ifndef F_OK +#define F_OK (0) +#endif +#ifndef S_ISDIR +#define S_ISDIR(m) ((m) & _S_IFDIR) +#endif +#ifndef S_ISREG +#define S_ISREG(m) ((m) & _S_IFREG) +#endif +#if !defined(__BORLANDC__) +#define access _access +#define chdir _chdir +#endif +#ifndef fileno +#define fileno _fileno +#endif +/*#define fstat _fstat64*/ +#if !defined(__BORLANDC__) +#define getcwd _getcwd +#endif +#define lstat stat +/*#define lstat _stat64*/ +/*#define stat _stat64*/ +#define rmdir _rmdir +#if !defined(__BORLANDC__) +#define strdup _strdup +#define umask _umask +#endif +#define int64_t __int64 +#endif -/* Interix doesn't define these in a standard header. */ -#if __INTERIX__ -extern char *optarg; -extern int optind; +#if defined(HAVE__CrtSetReportMode) +# include #endif -/* Enable core dump on failure. */ -static int dump_on_failure = 0; -/* Default is to remove temp dirs for successful tests. */ -static int keep_temp_files = 0; -/* Default is to print some basic information about each test. */ -static int quiet_flag = 0; -/* Default is to summarize repeated failures. */ -static int verbose = 0; -/* Cumulative count of component failures. */ -static int failures = 0; -/* Cumulative count of skipped component tests. */ -static int skips = 0; -/* Cumulative count of assertions. */ -static int assertions = 0; +#if defined(_WIN32) && !defined(__CYGWIN__) +void *GetFunctionKernel32(const char *name) +{ + static HINSTANCE lib; + static int set; + if (!set) { + set = 1; + lib = LoadLibrary("kernel32.dll"); + } + if (lib == NULL) { + fprintf(stderr, "Can't load kernel32.dll?!\n"); + exit(1); + } + return (void *)GetProcAddress(lib, name); +} -/* Directory where uuencoded reference files can be found. */ -static const char *refdir; +static int +my_CreateSymbolicLinkA(const char *linkname, const char *target, int flags) +{ + static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, DWORD); + static int set; + if (!set) { + set = 1; + f = GetFunctionKernel32("CreateSymbolicLinkA"); + } + return f == NULL ? 0 : (*f)(linkname, target, flags); +} +static int +my_CreateHardLinkA(const char *linkname, const char *target) +{ + static BOOLEAN (WINAPI *f)(LPCSTR, LPCSTR, LPSECURITY_ATTRIBUTES); + static int set; + if (!set) { + set = 1; + f = GetFunctionKernel32("CreateHardLinkA"); + } + return f == NULL ? 0 : (*f)(linkname, target, NULL); +} -#if defined(_WIN32) && !defined(__CYGWIN__) +int +my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi) +{ + HANDLE h; + int r; + memset(bhfi, 0, sizeof(*bhfi)); + h = CreateFile(path, FILE_READ_ATTRIBUTES, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) + return (0); + r = GetFileInformationByHandle(h, bhfi); + CloseHandle(h); + return (r); +} +#endif + +#if defined(HAVE__CrtSetReportMode) static void invalid_parameter_handler(const wchar_t * expression, const wchar_t * function, const wchar_t * file, @@ -98,123 +166,181 @@ invalid_parameter_handler(const wchar_t * expression, { /* nop */ } - #endif /* - * My own implementation of the standard assert() macro emits the - * message in the same format as GCC (file:line: message). - * It also includes some additional useful information. - * This makes it a lot easier to skim through test failures in - * Emacs. ;-) * - * It also supports a few special features specifically to simplify - * test harnesses: - * failure(fmt, args) -- Stores a text string that gets - * printed if the following assertion fails, good for - * explaining subtle tests. + * OPTIONS FLAGS + * */ -static char msg[4096]; -/* - * For each test source file, we remember how many times each - * failure was reported. - */ -static const char *failed_filename = NULL; -static struct line { - int line; - int count; - int critical; -} failed_lines[1000]; +/* Enable core dump on failure. */ +static int dump_on_failure = 0; +/* Default is to remove temp dirs and log data for successful tests. */ +static int keep_temp_files = 0; +/* Default is to just report pass/fail for each test. */ +static int verbosity = 0; +#define VERBOSITY_SUMMARY_ONLY -1 /* -q */ +#define VERBOSITY_PASSFAIL 0 /* Default */ +#define VERBOSITY_LIGHT_REPORT 1 /* -v */ +#define VERBOSITY_FULL 2 /* -vv */ +/* A few places generate even more output for verbosity > VERBOSITY_FULL, + * mostly for debugging the test harness itself. */ +/* Cumulative count of assertion failures. */ +static int failures = 0; +/* Cumulative count of reported skips. */ +static int skips = 0; +/* Cumulative count of assertions checked. */ +static int assertions = 0; + +/* Directory where uuencoded reference files can be found. */ +static const char *refdir; /* - * Called at the beginning of each assert() function. + * Report log information selectively to console and/or disk log. */ +static int log_console = 0; +static FILE *logfile; static void -count_assertion(const char *file, int line) +vlogprintf(const char *fmt, va_list ap) { - (void)file; /* UNUSED */ - (void)line; /* UNUSED */ - ++assertions; - /* Uncomment to print file:line after every assertion. - * Verbose, but occasionally useful in tracking down crashes. */ - /* printf("Checked %s:%d\n", file, line); */ +#ifdef va_copy + va_list lfap; + va_copy(lfap, ap); +#endif + if (log_console) + vfprintf(stdout, fmt, ap); + if (logfile != NULL) +#ifdef va_copy + vfprintf(logfile, fmt, lfap); + va_end(lfap); +#else + vfprintf(logfile, fmt, ap); +#endif } -/* - * Count this failure; return the number of previous failures. - */ -static int -previous_failures(const char *filename, int line, int critical) +static void +logprintf(const char *fmt, ...) { - unsigned int i; - int count; - - if (failed_filename == NULL || strcmp(failed_filename, filename) != 0) - memset(failed_lines, 0, sizeof(failed_lines)); - failed_filename = filename; + va_list ap; + va_start(ap, fmt); + vlogprintf(fmt, ap); + va_end(ap); +} - for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) { - if (failed_lines[i].line == line) { - count = failed_lines[i].count; - failed_lines[i].count++; - return (count); - } - if (failed_lines[i].line == 0) { - failed_lines[i].line = line; - failed_lines[i].count = 1; - failed_lines[i].critical = critical; - return (0); - } - } - return (0); +/* Set up a message to display only if next assertion fails. */ +static char msgbuff[4096]; +static const char *msg, *nextmsg; +void +failure(const char *fmt, ...) +{ + va_list ap; + va_start(ap, fmt); + vsprintf(msgbuff, fmt, ap); + va_end(ap); + nextmsg = msgbuff; } /* * Copy arguments into file-local variables. + * This was added to permit vararg assert() functions without needing + * variadic wrapper macros. Turns out that the vararg capability is almost + * never used, so almost all of the vararg assertions can be simplified + * by removing the vararg capability and reworking the wrapper macro to + * pass __FILE__, __LINE__ directly into the function instead of using + * this hook. I suspect this machinery is used so rarely that we + * would be better off just removing it entirely. That would simplify + * the code here noticably. */ static const char *test_filename; static int test_line; static void *test_extra; -void test_setup(const char *filename, int line) +void assertion_setup(const char *filename, int line) { test_filename = filename; test_line = line; } +/* Called at the beginning of each assert() function. */ +static void +assertion_count(const char *file, int line) +{ + (void)file; /* UNUSED */ + (void)line; /* UNUSED */ + ++assertions; + /* Proper handling of "failure()" message. */ + msg = nextmsg; + nextmsg = NULL; + /* Uncomment to print file:line after every assertion. + * Verbose, but occasionally useful in tracking down crashes. */ + /* printf("Checked %s:%d\n", file, line); */ +} + /* - * Inform user that we're skipping a test. + * For each test source file, we remember how many times each + * assertion was reported. Cleared before each new test, + * used by test_summarize(). */ -void -test_skipping(const char *fmt, ...) +static struct line { + int count; + int skip; +} failed_lines[10000]; + +/* Count this failure, setup up log destination and handle initial report. */ +static void +failure_start(const char *filename, int line, const char *fmt, ...) { va_list ap; - if (previous_failures(test_filename, test_line, 0)) - return; + /* Record another failure for this line. */ + ++failures; + /* test_filename = filename; */ + failed_lines[line].count++; + + /* Determine whether to log header to console. */ + switch (verbosity) { + case VERBOSITY_LIGHT_REPORT: + log_console = (failed_lines[line].count < 2); + break; + default: + log_console = (verbosity >= VERBOSITY_FULL); + } + /* Log file:line header for this failure */ va_start(ap, fmt); - fprintf(stderr, " *** SKIPPING: "); - vfprintf(stderr, fmt, ap); - fprintf(stderr, "\n"); +#if _MSC_VER + logprintf("%s(%d): ", filename, line); +#else + logprintf("%s:%d: ", filename, line); +#endif + vlogprintf(fmt, ap); va_end(ap); - ++skips; + logprintf("\n"); + + if (msg != NULL && msg[0] != '\0') { + logprintf(" Description: %s\n", msg); + msg = NULL; + } + + /* Determine whether to log details to console. */ + if (verbosity == VERBOSITY_LIGHT_REPORT) + log_console = 0; } -/* Common handling of failed tests. */ +/* Complete reporting of failed tests. */ +/* + * The 'extra' hook here is used by libarchive to include libarchive + * error messages with assertion failures. It could also be used + * to add strerror() output, for example. Just define the EXTRA_DUMP() + * macro appropriately. + */ static void -report_failure(void *extra) +failure_finish(void *extra) { - if (msg[0] != '\0') { - fprintf(stderr, " Description: %s\n", msg); - msg[0] = '\0'; - } - + (void)extra; /* UNUSED (maybe) */ #ifdef EXTRA_DUMP if (extra != NULL) - fprintf(stderr, " detail: %s\n", EXTRA_DUMP(extra)); -#else - (void)extra; /* UNUSED */ + logprintf(" detail: %s\n", EXTRA_DUMP(extra)); #endif if (dump_on_failure) { @@ -225,203 +351,154 @@ report_failure(void *extra) } } -/* - * Summarize repeated failures in the just-completed test file. - * The reports above suppress multiple failures from the same source - * line; this reports on any tests that did fail multiple times. - */ -static int -summarize_comparator(const void *a0, const void *b0) -{ - const struct line *a = a0, *b = b0; - if (a->line == 0 && b->line == 0) - return (0); - if (a->line == 0) - return (1); - if (b->line == 0) - return (-1); - return (a->line - b->line); -} - -static void -summarize(void) -{ - unsigned int i; - - qsort(failed_lines, sizeof(failed_lines)/sizeof(failed_lines[0]), - sizeof(failed_lines[0]), summarize_comparator); - for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) { - if (failed_lines[i].line == 0) - break; - if (failed_lines[i].count > 1 && failed_lines[i].critical) - fprintf(stderr, "%s:%d: Failed %d times\n", - failed_filename, failed_lines[i].line, - failed_lines[i].count); - } - /* Clear the failure history for the next file. */ - memset(failed_lines, 0, sizeof(failed_lines)); -} - -/* Set up a message to display only after a test fails. */ +/* Inform user that we're skipping some checks. */ void -failure(const char *fmt, ...) +test_skipping(const char *fmt, ...) { + char buff[1024]; va_list ap; + va_start(ap, fmt); - vsprintf(msg, fmt, ap); + vsprintf(buff, fmt, ap); va_end(ap); + /* failure_start() isn't quite right, but is awfully convenient. */ + failure_start(test_filename, test_line, "SKIPPING: %s", buff); + --failures; /* Undo failures++ in failure_start() */ + /* Don't failure_finish() here. */ + /* Mark as skip, so doesn't count as failed test. */ + failed_lines[test_line].skip = 1; + ++skips; } +/* + * + * ASSERTIONS + * + */ + /* Generic assert() just displays the failed condition. */ int -test_assert(const char *file, int line, int value, const char *condition, void *extra) +assertion_assert(const char *file, int line, int value, + const char *condition, void *extra) { - count_assertion(file, line); - if (value) { - msg[0] = '\0'; - return (value); + assertion_count(file, line); + if (!value) { + failure_start(file, line, "Assertion failed: %s", condition); + failure_finish(extra); } - failures ++; - if (!verbose && previous_failures(file, line, 1)) - return (value); - fprintf(stderr, "%s:%d: Assertion failed\n", file, line); - fprintf(stderr, " Condition: %s\n", condition); - report_failure(extra); return (value); } -/* assertEqualInt() displays the values of the two integers. */ +/* chdir() and report any errors */ int -test_assert_equal_int(const char *file, int line, - int v1, const char *e1, int v2, const char *e2, void *extra) +assertion_chdir(const char *file, int line, const char *pathname) { - count_assertion(file, line); - if (v1 == v2) { - msg[0] = '\0'; + assertion_count(file, line); + if (chdir(pathname) == 0) return (1); - } - failures ++; - if (!verbose && previous_failures(file, line, 1)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: Ints not equal\n", - file, line); - fprintf(stderr, " %s=%d\n", e1, v1); - fprintf(stderr, " %s=%d\n", e2, v2); - report_failure(extra); + failure_start(file, line, "chdir(\"%s\")", pathname); + failure_finish(NULL); + return (0); + +} + +/* Verify two integers are equal. */ +int +assertion_equal_int(const char *file, int line, + long long v1, const char *e1, long long v2, const char *e2, void *extra) +{ + assertion_count(file, line); + if (v1 == v2) + return (1); + failure_start(file, line, "%s != %s", e1, e2); + logprintf(" %s=%lld (0x%llx, 0%llo)\n", e1, v1, v1, v1); + logprintf(" %s=%lld (0x%llx, 0%llo)\n", e2, v2, v2, v2); + failure_finish(extra); return (0); } -static void strdump(const char *p) +static void strdump(const char *e, const char *p) { + const char *q = p; + + logprintf(" %s = ", e); if (p == NULL) { - fprintf(stderr, "(null)"); + logprintf("NULL"); return; } - fprintf(stderr, "\""); + logprintf("\""); while (*p != '\0') { unsigned int c = 0xff & *p++; switch (c) { - case '\a': fprintf(stderr, "\a"); break; - case '\b': fprintf(stderr, "\b"); break; - case '\n': fprintf(stderr, "\n"); break; - case '\r': fprintf(stderr, "\r"); break; + case '\a': printf("\a"); break; + case '\b': printf("\b"); break; + case '\n': printf("\n"); break; + case '\r': printf("\r"); break; default: if (c >= 32 && c < 127) - fprintf(stderr, "%c", c); + logprintf("%c", c); else - fprintf(stderr, "\\x%02X", c); + logprintf("\\x%02X", c); } } - fprintf(stderr, "\""); + logprintf("\""); + logprintf(" (length %d)\n", q == NULL ? -1 : (int)strlen(q)); } -/* assertEqualString() displays the values of the two strings. */ +/* Verify two strings are equal, dump them if not. */ int -test_assert_equal_string(const char *file, int line, +assertion_equal_string(const char *file, int line, const char *v1, const char *e1, const char *v2, const char *e2, void *extra) { - count_assertion(file, line); - if (v1 == NULL || v2 == NULL) { - if (v1 == v2) { - msg[0] = '\0'; - return (1); - } - } else if (strcmp(v1, v2) == 0) { - msg[0] = '\0'; + assertion_count(file, line); + if (v1 == v2 || (v1 != NULL && v2 != NULL && strcmp(v1, v2) == 0)) return (1); - } - failures ++; - if (!verbose && previous_failures(file, line, 1)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: Strings not equal\n", - file, line); - fprintf(stderr, " %s = ", e1); - strdump(v1); - fprintf(stderr, " (length %d)\n", v1 == NULL ? 0 : (int)strlen(v1)); - fprintf(stderr, " %s = ", e2); - strdump(v2); - fprintf(stderr, " (length %d)\n", v2 == NULL ? 0 : (int)strlen(v2)); - report_failure(extra); + failure_start(file, line, "%s != %s", e1, e2); + strdump(e1, v1); + strdump(e2, v2); + failure_finish(extra); return (0); } -static void wcsdump(const wchar_t *w) +static void +wcsdump(const char *e, const wchar_t *w) { + logprintf(" %s = ", e); if (w == NULL) { - fprintf(stderr, "(null)"); + logprintf("(null)"); return; } - fprintf(stderr, "\""); + logprintf("\""); while (*w != L'\0') { unsigned int c = *w++; if (c >= 32 && c < 127) - fprintf(stderr, "%c", c); + logprintf("%c", c); else if (c < 256) - fprintf(stderr, "\\x%02X", c); + logprintf("\\x%02X", c); else if (c < 0x10000) - fprintf(stderr, "\\u%04X", c); + logprintf("\\u%04X", c); else - fprintf(stderr, "\\U%08X", c); + logprintf("\\U%08X", c); } - fprintf(stderr, "\""); + logprintf("\"\n"); } -/* assertEqualWString() displays the values of the two strings. */ +/* Verify that two wide strings are equal, dump them if not. */ int -test_assert_equal_wstring(const char *file, int line, +assertion_equal_wstring(const char *file, int line, const wchar_t *v1, const char *e1, const wchar_t *v2, const char *e2, void *extra) { - count_assertion(file, line); - if (v1 == NULL) { - if (v2 == NULL) { - msg[0] = '\0'; - return (1); - } - } else if (v2 == NULL) { - if (v1 == NULL) { - msg[0] = '\0'; - return (1); - } - } else if (wcscmp(v1, v2) == 0) { - msg[0] = '\0'; + assertion_count(file, line); + if (v1 == v2 || wcscmp(v1, v2) == 0) return (1); - } - failures ++; - if (!verbose && previous_failures(file, line, 1)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: Unicode strings not equal\n", - file, line); - fprintf(stderr, " %s = ", e1); - wcsdump(v1); - fprintf(stderr, "\n"); - fprintf(stderr, " %s = ", e2); - wcsdump(v2); - fprintf(stderr, "\n"); - report_failure(extra); + failure_start(file, line, "%s != %s", e1, e2); + wcsdump(e1, v1); + wcsdump(e2, v2); + failure_finish(extra); return (0); } @@ -436,35 +513,40 @@ hexdump(const char *p, const char *ref, size_t l, size_t offset) size_t i, j; char sep; + if (p == NULL) { + logprintf("(null)\n"); + return; + } for(i=0; i < l; i+=16) { - fprintf(stderr, "%04x", (unsigned)(i + offset)); + logprintf("%04x", (unsigned)(i + offset)); sep = ' '; for (j = 0; j < 16 && i + j < l; j++) { if (ref != NULL && p[i + j] != ref[i + j]) sep = '_'; - fprintf(stderr, "%c%02x", sep, 0xff & (int)p[i+j]); + logprintf("%c%02x", sep, 0xff & (int)p[i+j]); if (ref != NULL && p[i + j] == ref[i + j]) sep = ' '; } for (; j < 16; j++) { - fprintf(stderr, "%c ", sep); + logprintf("%c ", sep); sep = ' '; } - fprintf(stderr, "%c", sep); + logprintf("%c", sep); for (j=0; j < 16 && i + j < l; j++) { int c = p[i + j]; if (c >= ' ' && c <= 126) - fprintf(stderr, "%c", c); + logprintf("%c", c); else - fprintf(stderr, "."); + logprintf("."); } - fprintf(stderr, "\n"); + logprintf("\n"); } } -/* assertEqualMem() displays the values of the two memory blocks. */ +/* Verify that two blocks of memory are the same, display the first + * block of differences if they're not. */ int -test_assert_equal_mem(const char *file, int line, +assertion_equal_mem(const char *file, int line, const void *_v1, const char *e1, const void *_v2, const char *e2, size_t l, const char *ld, void *extra) @@ -473,200 +555,906 @@ test_assert_equal_mem(const char *file, int line, const char *v2 = (const char *)_v2; size_t offset; - count_assertion(file, line); - if (v1 == NULL || v2 == NULL) { - if (v1 == v2) { - msg[0] = '\0'; - return (1); - } - } else if (memcmp(v1, v2, l) == 0) { - msg[0] = '\0'; + assertion_count(file, line); + if (v1 == v2 || (v1 != NULL && v2 != NULL && memcmp(v1, v2, l) == 0)) return (1); - } - failures ++; - if (!verbose && previous_failures(file, line, 1)) - return (0); - fprintf(stderr, "%s:%d: Assertion failed: memory not equal\n", - file, line); - fprintf(stderr, " size %s = %d\n", ld, (int)l); + + failure_start(file, line, "%s != %s", e1, e2); + logprintf(" size %s = %d\n", ld, (int)l); /* Dump 48 bytes (3 lines) so that the first difference is * in the second line. */ offset = 0; while (l > 64 && memcmp(v1, v2, 32) == 0) { - /* The first two lines agree, so step forward one line. */ + /* Two lines agree, so step forward one line. */ v1 += 16; v2 += 16; l -= 16; offset += 16; } - fprintf(stderr, " Dump of %s\n", e1); + logprintf(" Dump of %s\n", e1); hexdump(v1, v2, l < 64 ? l : 64, offset); - fprintf(stderr, " Dump of %s\n", e2); + logprintf(" Dump of %s\n", e2); hexdump(v2, v1, l < 64 ? l : 64, offset); - fprintf(stderr, "\n"); - report_failure(extra); + logprintf("\n"); + failure_finish(extra); return (0); } +/* Verify that the named file exists and is empty. */ int -test_assert_empty_file(const char *f1fmt, ...) +assertion_empty_file(const char *f1fmt, ...) { char buff[1024]; char f1[1024]; struct stat st; va_list ap; ssize_t s; - int fd; - + FILE *f; + assertion_count(test_filename, test_line); va_start(ap, f1fmt); vsprintf(f1, f1fmt, ap); va_end(ap); if (stat(f1, &st) != 0) { - fprintf(stderr, "%s:%d: Could not stat: %s\n", test_filename, test_line, f1); - report_failure(NULL); + failure_start(test_filename, test_line, "Stat failed: %s", f1); + failure_finish(NULL); return (0); } if (st.st_size == 0) return (1); - failures ++; - if (!verbose && previous_failures(test_filename, test_line, 1)) - return (0); - - fprintf(stderr, "%s:%d: File not empty: %s\n", test_filename, test_line, f1); - fprintf(stderr, " File size: %d\n", (int)st.st_size); - fprintf(stderr, " Contents:\n"); - fd = open(f1, O_RDONLY); - if (fd < 0) { - fprintf(stderr, " Unable to open %s\n", f1); + failure_start(test_filename, test_line, "File should be empty: %s", f1); + logprintf(" File size: %d\n", (int)st.st_size); + logprintf(" Contents:\n"); + f = fopen(f1, "rb"); + if (f == NULL) { + logprintf(" Unable to open %s\n", f1); } else { - s = sizeof(buff) < st.st_size ? sizeof(buff) : st.st_size; - s = read(fd, buff, s); + s = ((off_t)sizeof(buff) < st.st_size) ? + (ssize_t)sizeof(buff) : (ssize_t)st.st_size; + s = fread(buff, 1, s, f); hexdump(buff, NULL, s, 0); + fclose(f); } - report_failure(NULL); + failure_finish(NULL); return (0); } -/* assertEqualFile() asserts that two files have the same contents. */ +/* Verify that the named file exists and is not empty. */ +int +assertion_non_empty_file(const char *f1fmt, ...) +{ + char f1[1024]; + struct stat st; + va_list ap; + + assertion_count(test_filename, test_line); + va_start(ap, f1fmt); + vsprintf(f1, f1fmt, ap); + va_end(ap); + + if (stat(f1, &st) != 0) { + failure_start(test_filename, test_line, "Stat failed: %s", f1); + failure_finish(NULL); + return (0); + } + if (st.st_size == 0) { + failure_start(test_filename, test_line, "File empty: %s", f1); + failure_finish(NULL); + return (0); + } + return (1); +} + +/* Verify that two files have the same contents. */ /* TODO: hexdump the first bytes that actually differ. */ int -test_assert_equal_file(const char *f1, const char *f2pattern, ...) +assertion_equal_file(const char *fn1, const char *f2pattern, ...) { - char f2[1024]; + char fn2[1024]; va_list ap; char buff1[1024]; char buff2[1024]; - int fd1, fd2; + FILE *f1, *f2; int n1, n2; + assertion_count(test_filename, test_line); va_start(ap, f2pattern); - vsprintf(f2, f2pattern, ap); + vsprintf(fn2, f2pattern, ap); va_end(ap); - fd1 = open(f1, O_RDONLY); - fd2 = open(f2, O_RDONLY); + f1 = fopen(fn1, "rb"); + f2 = fopen(fn2, "rb"); for (;;) { - n1 = read(fd1, buff1, sizeof(buff1)); - n2 = read(fd2, buff2, sizeof(buff2)); + n1 = fread(buff1, 1, sizeof(buff1), f1); + n2 = fread(buff2, 1, sizeof(buff2), f2); if (n1 != n2) break; - if (n1 == 0 && n2 == 0) + if (n1 == 0 && n2 == 0) { + fclose(f1); + fclose(f2); return (1); + } if (memcmp(buff1, buff2, n1) != 0) break; } - failures ++; - if (!verbose && previous_failures(test_filename, test_line, 1)) - return (0); - fprintf(stderr, "%s:%d: Files are not identical\n", - test_filename, test_line); - fprintf(stderr, " file1=\"%s\"\n", f1); - fprintf(stderr, " file2=\"%s\"\n", f2); - report_failure(test_extra); + fclose(f1); + fclose(f2); + failure_start(test_filename, test_line, "Files not identical"); + logprintf(" file1=\"%s\"\n", fn1); + logprintf(" file2=\"%s\"\n", fn2); + failure_finish(test_extra); return (0); } +/* Verify that the named file does exist. */ int -test_assert_file_exists(const char *fpattern, ...) +assertion_file_exists(const char *fpattern, ...) { char f[1024]; va_list ap; + assertion_count(test_filename, test_line); va_start(ap, fpattern); vsprintf(f, fpattern, ap); va_end(ap); +#if defined(_WIN32) && !defined(__CYGWIN__) + if (!_access(f, 0)) + return (1); +#else if (!access(f, F_OK)) return (1); - if (!previous_failures(test_filename, test_line, 1)) { - fprintf(stderr, "%s:%d: File doesn't exist\n", - test_filename, test_line); - fprintf(stderr, " file=\"%s\"\n", f); - report_failure(test_extra); +#endif + failure_start(test_filename, test_line, "File should exist: %s", f); + failure_finish(test_extra); + return (0); +} + +/* Verify that the named file doesn't exist. */ +int +assertion_file_not_exists(const char *fpattern, ...) +{ + char f[1024]; + va_list ap; + + assertion_count(test_filename, test_line); + va_start(ap, fpattern); + vsprintf(f, fpattern, ap); + va_end(ap); + +#if defined(_WIN32) && !defined(__CYGWIN__) + if (_access(f, 0)) + return (1); +#else + if (access(f, F_OK)) + return (1); +#endif + failure_start(test_filename, test_line, "File should not exist: %s", f); + failure_finish(test_extra); + return (0); +} + +/* Compare the contents of a file to a block of memory. */ +int +assertion_file_contents(const void *buff, int s, const char *fpattern, ...) +{ + char fn[1024]; + va_list ap; + char *contents; + FILE *f; + int n; + + assertion_count(test_filename, test_line); + va_start(ap, fpattern); + vsprintf(fn, fpattern, ap); + va_end(ap); + + f = fopen(fn, "rb"); + if (f == NULL) { + failure_start(test_filename, test_line, + "File should exist: %s", fn); + failure_finish(test_extra); + return (0); + } + contents = malloc(s * 2); + n = fread(contents, 1, s * 2, f); + fclose(f); + if (n == s && memcmp(buff, contents, s) == 0) { + free(contents); + return (1); + } + failure_start(test_filename, test_line, "File contents don't match"); + logprintf(" file=\"%s\"\n", fn); + if (n > 0) + hexdump(contents, buff, n > 512 ? 512 : n, 0); + else { + logprintf(" File empty, contents should be:\n"); + hexdump(buff, NULL, s > 512 ? 512 : n, 0); + } + failure_finish(test_extra); + free(contents); + return (0); +} + +/* Check the contents of a text file, being tolerant of line endings. */ +int +assertion_text_file_contents(const char *buff, const char *fn) +{ + char *contents; + const char *btxt, *ftxt; + FILE *f; + int n, s; + + assertion_count(test_filename, test_line); + f = fopen(fn, "r"); + s = strlen(buff); + contents = malloc(s * 2 + 128); + n = fread(contents, 1, s * 2 + 128 - 1, f); + if (n >= 0) + contents[n] = '\0'; + fclose(f); + /* Compare texts. */ + btxt = buff; + ftxt = (const char *)contents; + while (*btxt != '\0' && *ftxt != '\0') { + if (*btxt == *ftxt) { + ++btxt; + ++ftxt; + continue; + } + if (btxt[0] == '\n' && ftxt[0] == '\r' && ftxt[1] == '\n') { + /* Pass over different new line characters. */ + ++btxt; + ftxt += 2; + continue; + } + break; + } + if (*btxt == '\0' && *ftxt == '\0') { + free(contents); + return (1); + } + failure_start(test_filename, test_line, "Contents don't match"); + logprintf(" file=\"%s\"\n", fn); + if (n > 0) + hexdump(contents, buff, n, 0); + else { + logprintf(" File empty, contents should be:\n"); + hexdump(buff, NULL, s, 0); + } + failure_finish(test_extra); + free(contents); + return (0); +} + +/* Test that two paths point to the same file. */ +/* As a side-effect, asserts that both files exist. */ +static int +is_hardlink(const char *file, int line, + const char *path1, const char *path2) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + BY_HANDLE_FILE_INFORMATION bhfi1, bhfi2; + int r; + + assertion_count(file, line); + r = my_GetFileInformationByName(path1, &bhfi1); + if (r == 0) { + failure_start(file, line, "File %s can't be inspected?", path1); + failure_finish(NULL); + return (0); + } + r = my_GetFileInformationByName(path2, &bhfi2); + if (r == 0) { + failure_start(file, line, "File %s can't be inspected?", path2); + failure_finish(NULL); + return (0); + } + return (bhfi1.dwVolumeSerialNumber == bhfi2.dwVolumeSerialNumber + && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh + && bhfi1.nFileIndexLow == bhfi2.nFileIndexLow); +#else + struct stat st1, st2; + int r; + + assertion_count(file, line); + r = lstat(path1, &st1); + if (r != 0) { + failure_start(file, line, "File should exist: %s", path1); + failure_finish(NULL); + return (0); + } + r = lstat(path2, &st2); + if (r != 0) { + failure_start(file, line, "File should exist: %s", path2); + failure_finish(NULL); + return (0); + } + return (st1.st_ino == st2.st_ino && st1.st_dev == st2.st_dev); +#endif +} + +int +assertion_is_hardlink(const char *file, int line, + const char *path1, const char *path2) +{ + if (is_hardlink(file, line, path1, path2)) + return (1); + failure_start(file, line, + "Files %s and %s are not hardlinked", path1, path2); + failure_finish(NULL); + return (0); +} + +int +assertion_is_not_hardlink(const char *file, int line, + const char *path1, const char *path2) +{ + if (!is_hardlink(file, line, path1, path2)) + return (1); + failure_start(file, line, + "Files %s and %s should not be hardlinked", path1, path2); + failure_finish(NULL); + return (0); +} + +/* Verify a/b/mtime of 'pathname'. */ +/* If 'recent', verify that it's within last 10 seconds. */ +static int +assertion_file_time(const char *file, int line, + const char *pathname, long t, long nsec, char type, int recent) +{ + long long filet, filet_nsec; + int r; + +#if defined(_WIN32) && !defined(__CYGWIN__) +#define EPOC_TIME (116444736000000000ULL) + FILETIME ftime, fbirthtime, fatime, fmtime; + ULARGE_INTEGER wintm; + HANDLE h; + ftime.dwLowDateTime = 0; + ftime.dwHighDateTime = 0; + + assertion_count(file, line); + h = CreateFile(pathname, FILE_READ_ATTRIBUTES, 0, NULL, + OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (h == INVALID_HANDLE_VALUE) { + failure_start(file, line, "Can't access %s\n", pathname); + failure_finish(NULL); + return (0); + } + r = GetFileTime(h, &fbirthtime, &fatime, &fmtime); + switch (type) { + case 'a': ftime = fatime; break; + case 'b': ftime = fbirthtime; break; + case 'm': ftime = fmtime; break; + } + CloseHandle(h); + if (r == 0) { + failure_start(file, line, "Can't GetFileTime %s\n", pathname); + failure_finish(NULL); + return (0); + } + wintm.LowPart = ftime.dwLowDateTime; + wintm.HighPart = ftime.dwHighDateTime; + filet = (wintm.QuadPart - EPOC_TIME) / 10000000; + filet_nsec = ((wintm.QuadPart - EPOC_TIME) % 10000000) * 100; + nsec = (nsec / 100) * 100; /* Round the request */ +#else + struct stat st; + + assertion_count(file, line); + r = lstat(pathname, &st); + if (r != 0) { + failure_start(file, line, "Can't stat %s\n", pathname); + failure_finish(NULL); + return (0); + } + switch (type) { + case 'a': filet = st.st_atime; break; + case 'm': filet = st.st_mtime; break; + case 'b': filet = 0; break; + default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); + exit(1); + } +#if defined(__FreeBSD__) + switch (type) { + case 'a': filet_nsec = st.st_atimespec.tv_nsec; break; + case 'b': filet = st.st_birthtime; + filet_nsec = st.st_birthtimespec.tv_nsec; break; + case 'm': filet_nsec = st.st_mtimespec.tv_nsec; break; + default: fprintf(stderr, "INTERNAL: Bad type %c for file time", type); + exit(1); + } + /* FreeBSD generally only stores to microsecond res, so round. */ + filet_nsec = (filet_nsec / 1000) * 1000; + nsec = (nsec / 1000) * 1000; +#else + filet_nsec = nsec = 0; /* Generic POSIX only has whole seconds. */ + if (type == 'b') return (1); /* Generic POSIX doesn't have birthtime */ +#if defined(__HAIKU__) + if (type == 'a') return (1); /* Haiku doesn't have atime. */ +#endif +#endif +#endif + if (recent) { + /* Check that requested time is up-to-date. */ + time_t now = time(NULL); + if (filet < now - 10 || filet > now + 1) { + failure_start(file, line, + "File %s has %ctime %ld, %ld seconds ago\n", + pathname, type, filet, now - filet); + failure_finish(NULL); + return (0); + } + } else if (filet != t || filet_nsec != nsec) { + failure_start(file, line, + "File %s has %ctime %ld.%09ld, expected %ld.%09ld", + pathname, type, filet, filet_nsec, t, nsec); + failure_finish(NULL); + return (0); + } + return (1); +} + +/* Verify atime of 'pathname'. */ +int +assertion_file_atime(const char *file, int line, + const char *pathname, long t, long nsec) +{ + return assertion_file_time(file, line, pathname, t, nsec, 'a', 0); +} + +/* Verify atime of 'pathname' is up-to-date. */ +int +assertion_file_atime_recent(const char *file, int line, const char *pathname) +{ + return assertion_file_time(file, line, pathname, 0, 0, 'a', 1); +} + +/* Verify birthtime of 'pathname'. */ +int +assertion_file_birthtime(const char *file, int line, + const char *pathname, long t, long nsec) +{ + return assertion_file_time(file, line, pathname, t, nsec, 'b', 0); +} + +/* Verify birthtime of 'pathname' is up-to-date. */ +int +assertion_file_birthtime_recent(const char *file, int line, + const char *pathname) +{ + return assertion_file_time(file, line, pathname, 0, 0, 'b', 1); +} + +/* Verify mtime of 'pathname'. */ +int +assertion_file_mtime(const char *file, int line, + const char *pathname, long t, long nsec) +{ + return assertion_file_time(file, line, pathname, t, nsec, 'm', 0); +} + +/* Verify mtime of 'pathname' is up-to-date. */ +int +assertion_file_mtime_recent(const char *file, int line, const char *pathname) +{ + return assertion_file_time(file, line, pathname, 0, 0, 'm', 1); +} + +/* Verify number of links to 'pathname'. */ +int +assertion_file_nlinks(const char *file, int line, + const char *pathname, int nlinks) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + BY_HANDLE_FILE_INFORMATION bhfi; + int r; + + assertion_count(file, line); + r = my_GetFileInformationByName(pathname, &bhfi); + if (r != 0 && bhfi.nNumberOfLinks == (DWORD)nlinks) + return (1); + failure_start(file, line, "File %s has %d links, expected %d", + pathname, bhfi.nNumberOfLinks, nlinks); + failure_finish(NULL); + return (0); +#else + struct stat st; + int r; + + assertion_count(file, line); + r = lstat(pathname, &st); + if (r == 0 && st.st_nlink == nlinks) + return (1); + failure_start(file, line, "File %s has %d links, expected %d", + pathname, st.st_nlink, nlinks); + failure_finish(NULL); + return (0); +#endif +} + +/* Verify size of 'pathname'. */ +int +assertion_file_size(const char *file, int line, const char *pathname, long size) +{ + int64_t filesize; + int r; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + { + BY_HANDLE_FILE_INFORMATION bhfi; + r = !my_GetFileInformationByName(pathname, &bhfi); + filesize = ((int64_t)bhfi.nFileSizeHigh << 32) + bhfi.nFileSizeLow; + } +#else + { + struct stat st; + r = lstat(pathname, &st); + filesize = st.st_size; + } +#endif + if (r == 0 && filesize == size) + return (1); + failure_start(file, line, "File %s has size %ld, expected %ld", + pathname, (long)filesize, (long)size); + failure_finish(NULL); + return (0); +} + +/* Assert that 'pathname' is a dir. If mode >= 0, verify that too. */ +int +assertion_is_dir(const char *file, int line, const char *pathname, int mode) +{ + struct stat st; + int r; + +#if defined(_WIN32) && !defined(__CYGWIN__) + (void)mode; /* UNUSED */ +#endif + assertion_count(file, line); + r = lstat(pathname, &st); + if (r != 0) { + failure_start(file, line, "Dir should exist: %s", pathname); + failure_finish(NULL); + return (0); + } + if (!S_ISDIR(st.st_mode)) { + failure_start(file, line, "%s is not a dir", pathname); + failure_finish(NULL); + return (0); + } +#if !defined(_WIN32) || defined(__CYGWIN__) + /* Windows doesn't handle permissions the same way as POSIX, + * so just ignore the mode tests. */ + /* TODO: Can we do better here? */ + if (mode >= 0 && mode != (st.st_mode & 07777)) { + failure_start(file, line, "Dir %s has wrong mode", pathname); + logprintf(" Expected: 0%3o\n", mode); + logprintf(" Found: 0%3o\n", st.st_mode & 07777); + failure_finish(NULL); + return (0); + } +#endif + return (1); +} + +/* Verify that 'pathname' is a regular file. If 'mode' is >= 0, + * verify that too. */ +int +assertion_is_reg(const char *file, int line, const char *pathname, int mode) +{ + struct stat st; + int r; + +#if defined(_WIN32) && !defined(__CYGWIN__) + (void)mode; /* UNUSED */ +#endif + assertion_count(file, line); + r = lstat(pathname, &st); + if (r != 0 || !S_ISREG(st.st_mode)) { + failure_start(file, line, "File should exist: %s", pathname); + failure_finish(NULL); + return (0); + } +#if !defined(_WIN32) || defined(__CYGWIN__) + /* Windows doesn't handle permissions the same way as POSIX, + * so just ignore the mode tests. */ + /* TODO: Can we do better here? */ + if (mode >= 0 && mode != (st.st_mode & 07777)) { + failure_start(file, line, "File %s has wrong mode", pathname); + logprintf(" Expected: 0%3o\n", mode); + logprintf(" Found: 0%3o\n", st.st_mode & 07777); + failure_finish(NULL); + return (0); + } +#endif + return (1); +} + +/* Check whether 'pathname' is a symbolic link. If 'contents' is + * non-NULL, verify that the symlink has those contents. */ +static int +is_symlink(const char *file, int line, + const char *pathname, const char *contents) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + (void)pathname; /* UNUSED */ + (void)contents; /* UNUSED */ + assertion_count(file, line); + /* Windows sort-of has real symlinks, but they're only usable + * by privileged users and are crippled even then, so there's + * really not much point in bothering with this. */ + return (0); +#else + char buff[300]; + struct stat st; + ssize_t linklen; + int r; + + assertion_count(file, line); + r = lstat(pathname, &st); + if (r != 0) { + failure_start(file, line, + "Symlink should exist: %s", pathname); + failure_finish(NULL); + return (0); + } + if (!S_ISLNK(st.st_mode)) + return (0); + if (contents == NULL) + return (1); + linklen = readlink(pathname, buff, sizeof(buff)); + if (linklen < 0) { + failure_start(file, line, "Can't read symlink %s", pathname); + failure_finish(NULL); + return (0); + } + buff[linklen] = '\0'; + if (strcmp(buff, contents) != 0) + return (0); + return (1); +#endif +} + +/* Assert that path is a symlink that (optionally) contains contents. */ +int +assertion_is_symlink(const char *file, int line, + const char *path, const char *contents) +{ + if (is_symlink(file, line, path, contents)) + return (1); + if (contents) + failure_start(file, line, "File %s is not a symlink to %s", + path, contents); + else + failure_start(file, line, "File %s is not a symlink", path); + failure_finish(NULL); + return (0); +} + + +/* Create a directory and report any errors. */ +int +assertion_make_dir(const char *file, int line, const char *dirname, int mode) +{ + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + (void)mode; /* UNUSED */ + if (0 == _mkdir(dirname)) + return (1); +#else + if (0 == mkdir(dirname, mode)) + return (1); +#endif + failure_start(file, line, "Could not create directory %s", dirname); + failure_finish(NULL); + return(0); +} + +/* Create a file with the specified contents and report any failures. */ +int +assertion_make_file(const char *file, int line, + const char *path, int mode, const char *contents) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + /* TODO: Rework this to set file mode as well. */ + FILE *f; + (void)mode; /* UNUSED */ + assertion_count(file, line); + f = fopen(path, "wb"); + if (f == NULL) { + failure_start(file, line, "Could not create file %s", path); + failure_finish(NULL); + return (0); + } + if (contents != NULL) { + if (strlen(contents) + != fwrite(contents, 1, strlen(contents), f)) { + fclose(f); + failure_start(file, line, + "Could not write file %s", path); + failure_finish(NULL); + return (0); + } + } + fclose(f); + return (1); +#else + int fd; + assertion_count(file, line); + fd = open(path, O_CREAT | O_WRONLY, mode >= 0 ? mode : 0644); + if (fd < 0) { + failure_start(file, line, "Could not create %s", path); + failure_finish(NULL); + return (0); + } + if (contents != NULL) { + if ((ssize_t)strlen(contents) + != write(fd, contents, strlen(contents))) { + close(fd); + failure_start(file, line, "Could not write to %s", path); + failure_finish(NULL); + return (0); + } + } + close(fd); + return (1); +#endif +} + +/* Create a hardlink and report any failures. */ +int +assertion_make_hardlink(const char *file, int line, + const char *newpath, const char *linkto) +{ + int succeeded; + + assertion_count(file, line); +#if defined(_WIN32) && !defined(__CYGWIN__) + succeeded = my_CreateHardLinkA(newpath, linkto); +#elif HAVE_LINK + succeeded = !link(linkto, newpath); +#else + succeeded = 0; +#endif + if (succeeded) + return (1); + failure_start(file, line, "Could not create hardlink"); + logprintf(" New link: %s\n", newpath); + logprintf(" Old name: %s\n", linkto); + failure_finish(NULL); + return(0); +} + +/* Create a symlink and report any failures. */ +int +assertion_make_symlink(const char *file, int line, + const char *newpath, const char *linkto) +{ +#if defined(_WIN32) && !defined(__CYGWIN__) + int targetIsDir = 0; /* TODO: Fix this */ + assertion_count(file, line); + if (my_CreateSymbolicLinkA(newpath, linkto, targetIsDir)) + return (1); +#elif HAVE_SYMLINK + assertion_count(file, line); + if (0 == symlink(linkto, newpath)) + return (1); +#endif + failure_start(file, line, "Could not create symlink"); + logprintf(" New link: %s\n", newpath); + logprintf(" Old name: %s\n", linkto); + failure_finish(NULL); + return(0); +} + +/* Set umask, report failures. */ +int +assertion_umask(const char *file, int line, int mask) +{ + assertion_count(file, line); + (void)file; /* UNUSED */ + (void)line; /* UNUSED */ + umask(mask); + return (1); +} + +/* + * + * UTILITIES for use by tests. + * + */ + +/* + * Check whether platform supports symlinks. This is intended + * for tests to use in deciding whether to bother testing symlink + * support; if the platform doesn't support symlinks, there's no point + * in checking whether the program being tested can create them. + * + * Note that the first time this test is called, we actually go out to + * disk to create and verify a symlink. This is necessary because + * symlink support is actually a property of a particular filesystem + * and can thus vary between directories on a single system. After + * the first call, this returns the cached result from memory, so it's + * safe to call it as often as you wish. + */ +int +canSymlink(void) +{ + /* Remember the test result */ + static int value = 0, tested = 0; + if (tested) + return (value); + + ++tested; + assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a"); + /* Note: Cygwin has its own symlink() emulation that does not + * use the Win32 CreateSymbolicLink() function. */ +#if defined(_WIN32) && !defined(__CYGWIN__) + value = my_CreateSymbolicLinkA("canSymlink.1", "canSymlink.0", 0) + && is_symlink(__FILE__, __LINE__, "canSymlink.1", "canSymlink.0"); +#elif HAVE_SYMLINK + value = (0 == symlink("canSymlink.0", "canSymlink.1")) + && is_symlink(__FILE__, __LINE__, "canSymlink.1","canSymlink.0"); +#endif + return (value); +} + +/* + * Can this platform run the gzip program? + */ +/* Platform-dependent options for hiding the output of a subcommand. */ +#if defined(_WIN32) && !defined(__CYGWIN__) +static const char *redirectArgs = ">NUL 2>NUL"; /* Win32 cmd.exe */ +#else +static const char *redirectArgs = ">/dev/null 2>/dev/null"; /* POSIX 'sh' */ +#endif +int +canGzip(void) +{ + static int tested = 0, value = 0; + if (!tested) { + tested = 1; + if (systemf("gzip -V %s", redirectArgs) == 0) + value = 1; } - return (0); + return (value); } +/* + * Can this platform run the gunzip program? + */ int -test_assert_file_not_exists(const char *fpattern, ...) +canGunzip(void) { - char f[1024]; - va_list ap; - - va_start(ap, fpattern); - vsprintf(f, fpattern, ap); - va_end(ap); - - if (access(f, F_OK)) - return (1); - if (!previous_failures(test_filename, test_line, 1)) { - fprintf(stderr, "%s:%d: File exists and shouldn't\n", - test_filename, test_line); - fprintf(stderr, " file=\"%s\"\n", f); - report_failure(test_extra); + static int tested = 0, value = 0; + if (!tested) { + tested = 1; + if (systemf("gunzip -V %s", redirectArgs) == 0) + value = 1; } - return (0); + return (value); } -/* assertFileContents() asserts the contents of a file. */ -int -test_assert_file_contents(const void *buff, int s, const char *fpattern, ...) +/* + * Sleep as needed; useful for verifying disk timestamp changes by + * ensuring that the wall-clock time has actually changed before we + * go back to re-read something from disk. + */ +void +sleepUntilAfter(time_t t) { - char f[1024]; - va_list ap; - char *contents; - int fd; - int n; - - va_start(ap, fpattern); - vsprintf(f, fpattern, ap); - va_end(ap); - - fd = open(f, O_RDONLY); - contents = malloc(s * 2); - n = read(fd, contents, s * 2); - if (n == s && memcmp(buff, contents, s) == 0) { - free(contents); - return (1); - } - failures ++; - if (!previous_failures(test_filename, test_line, 1)) { - fprintf(stderr, "%s:%d: File contents don't match\n", - test_filename, test_line); - fprintf(stderr, " file=\"%s\"\n", f); - if (n > 0) - hexdump(contents, buff, n, 0); - else { - fprintf(stderr, " File empty, contents should be:\n"); - hexdump(buff, NULL, s, 0); - } - report_failure(test_extra); - } - free(contents); - return (0); + while (t >= time(NULL)) +#if defined(_WIN32) && !defined(__CYGWIN__) + Sleep(500); +#else + sleep(1); +#endif } /* @@ -682,6 +1470,8 @@ systemf(const char *fmt, ...) va_start(ap, fmt); vsprintf(buff, fmt, ap); + if (verbosity > VERBOSITY_FULL) + logprintf("Cmd: %s\n", buff); r = system(buff); va_end(ap); return (r); @@ -700,176 +1490,48 @@ slurpfile(size_t * sizep, const char *fmt, ...) va_list ap; char *p; ssize_t bytes_read; - int fd; + FILE *f; int r; va_start(ap, fmt); vsprintf(filename, fmt, ap); va_end(ap); - fd = open(filename, O_RDONLY); - if (fd < 0) { + f = fopen(filename, "rb"); + if (f == NULL) { /* Note: No error; non-existent file is okay here. */ return (NULL); } - r = fstat(fd, &st); + r = fstat(fileno(f), &st); if (r != 0) { - fprintf(stderr, "Can't stat file %s\n", filename); - close(fd); + logprintf("Can't stat file %s\n", filename); + fclose(f); return (NULL); } - p = malloc(st.st_size + 1); + p = malloc((size_t)st.st_size + 1); if (p == NULL) { - fprintf(stderr, "Can't allocate %ld bytes of memory to read file %s\n", (long int)st.st_size, filename); - close(fd); + logprintf("Can't allocate %ld bytes of memory to read file %s\n", + (long int)st.st_size, filename); + fclose(f); return (NULL); } - bytes_read = read(fd, p, st.st_size); + bytes_read = fread(p, 1, (size_t)st.st_size, f); if (bytes_read < st.st_size) { - fprintf(stderr, "Can't read file %s\n", filename); - close(fd); + logprintf("Can't read file %s\n", filename); + fclose(f); free(p); return (NULL); } p[st.st_size] = '\0'; if (sizep != NULL) *sizep = (size_t)st.st_size; - close(fd); + fclose(f); return (p); } -/* - * "list.h" is automatically generated; it just has a lot of lines like: - * DEFINE_TEST(function_name) - * It's used above to declare all of the test functions. - * We reuse it here to define a list of all tests (functions and names). - */ -#undef DEFINE_TEST -#define DEFINE_TEST(n) { n, #n }, -struct { void (*func)(void); const char *name; } tests[] = { - #include "list.h" -}; - -/* - * This is well-intentioned, but sometimes the standard libraries - * leave open file descriptors and expect to be able to come back to - * them (e.g., for username lookups or logging). Closing these - * descriptors out from under those libraries creates havoc. - * - * Maybe there's some reasonably portable way to tell if a descriptor - * is open without using close()? - */ -#if 0 -static void -close_descriptors(int warn) -{ - int i; - int left_open = 0; - - for (i = 3; i < 100; ++i) { - if (close(i) == 0) - ++left_open; - } - if (warn && left_open > 0) { - fprintf(stderr, " ** %d descriptors unclosed\n", left_open); - failures += left_open; - report_failure(NULL); - } -} -#endif - -/* - * Each test is run in a private work dir. Those work dirs - * do have consistent and predictable names, in case a group - * of tests need to collaborate. However, there is no provision - * for requiring that tests run in a certain order. - */ -static int test_run(int i, const char *tmpdir) -{ - int failures_before = failures; - - if (!quiet_flag) { - printf("%d: %s\n", i, tests[i].name); - fflush(stdout); - } - - /* - * Always explicitly chdir() in case the last test moved us to - * a strange place. - */ - if (chdir(tmpdir)) { - fprintf(stderr, - "ERROR: Couldn't chdir to temp dir %s\n", - tmpdir); - exit(1); - } - /* Create a temp directory for this specific test. */ - if (mkdir(tests[i].name, 0755)) { - fprintf(stderr, - "ERROR: Couldn't create temp dir ``%s''\n", - tests[i].name); - exit(1); - } - /* Chdir() to that work directory. */ - if (chdir(tests[i].name)) { - fprintf(stderr, - "ERROR: Couldn't chdir to temp dir ``%s''\n", - tests[i].name); - exit(1); - } - /* Explicitly reset the locale before each test. */ - setlocale(LC_ALL, "C"); - /* Make sure there are no stray descriptors going into the test. */ - /* TODO: Find a better way to identify file descriptor leaks. */ - //close_descriptors(0); - /* Run the actual test. */ - (*tests[i].func)(); - /* Close stray descriptors, record as errors against this test. */ - //close_descriptors(1); - /* Summarize the results of this test. */ - summarize(); - /* If there were no failures, we can remove the work dir. */ - if (failures == failures_before) { - if (!keep_temp_files && chdir(tmpdir) == 0) { -#if !defined(_WIN32) || defined(__CYGWIN__) - systemf("rm -rf %s", tests[i].name); -#else - systemf("rmdir /S /Q %s", tests[i].name); -#endif - } - } - /* Return appropriate status. */ - return (failures == failures_before ? 0 : 1); -} - -static void usage(const char *program) -{ - static const int limit = sizeof(tests) / sizeof(tests[0]); - int i; - - printf("Usage: %s [options] ...\n", program); - printf("Default is to run all tests.\n"); - printf("Otherwise, specify the numbers of the tests you wish to run.\n"); - printf("Options:\n"); - printf(" -d Dump core after any failure, for debugging.\n"); - printf(" -k Keep all temp files.\n"); - printf(" Default: temp files for successful tests deleted.\n"); -#ifdef PROGRAM - printf(" -p Path to executable to be tested.\n"); - printf(" Default: path taken from " ENVBASE " environment variable.\n"); -#endif - printf(" -q Quiet.\n"); - printf(" -r Path to dir containing reference files.\n"); - printf(" Default: Current directory.\n"); - printf(" -v Verbose.\n"); - printf("Available tests:\n"); - for (i = 0; i < limit; i++) - printf(" %d: %s\n", i, tests[i].name); - exit(1); -} - +/* Read a uuencoded file from the reference directory, decode, and + * write the result into the current directory. */ #define UUDECODE(c) (((c) - 0x20) & 0x3f) - void extract_reference_file(const char *name) { @@ -893,7 +1555,7 @@ extract_reference_file(const char *name) } /* Now, decode the rest and write it. */ /* Not a lot of error checking here; the input better be right. */ - out = fopen(name, "w"); + out = fopen(name, "wb"); while (fgets(buff, sizeof(buff), in) != NULL) { char *p = buff; int bytes; @@ -927,48 +1589,211 @@ extract_reference_file(const char *name) fclose(in); } +/* + * + * TEST management + * + */ + +/* + * "list.h" is simply created by "grep DEFINE_TEST test_*.c"; it has + * a line like + * DEFINE_TEST(test_function) + * for each test. + */ + +/* Use "list.h" to declare all of the test functions. */ +#undef DEFINE_TEST +#define DEFINE_TEST(name) void name(void); +#include "list.h" + +/* Use "list.h" to create a list of all tests (functions and names). */ +#undef DEFINE_TEST +#define DEFINE_TEST(n) { n, #n, 0 }, +struct { void (*func)(void); const char *name; int failures; } tests[] = { + #include "list.h" +}; + +/* + * Summarize repeated failures in the just-completed test. + */ +static void +test_summarize(const char *filename, int failed) +{ + unsigned int i; + + switch (verbosity) { + case VERBOSITY_SUMMARY_ONLY: + printf(failed ? "E" : "."); + fflush(stdout); + break; + case VERBOSITY_PASSFAIL: + printf(failed ? "FAIL\n" : "ok\n"); + break; + } + + log_console = (verbosity == VERBOSITY_LIGHT_REPORT); + + for (i = 0; i < sizeof(failed_lines)/sizeof(failed_lines[0]); i++) { + if (failed_lines[i].count > 1 && !failed_lines[i].skip) + logprintf("%s:%d: Summary: Failed %d times\n", + filename, i, failed_lines[i].count); + } + /* Clear the failure history for the next file. */ + memset(failed_lines, 0, sizeof(failed_lines)); +} -/* Since gzip is by far the most popular external compression program - * available, we try to use it in the read_program and write_program - * tests. But if it's not available, then we can't use it. This - * function just tries to run gzip/gunzip to see if they're available. - * If not, some of the external compression program tests will be - * skipped. */ -const char * -external_gzip_program(int un) +/* + * Actually run a single test, with appropriate setup and cleanup. + */ +static int +test_run(int i, const char *tmpdir) { - static int tested = 0; - static const char *compress_prog = NULL; - static const char *decompress_prog = NULL; - /* Args vary depending on the command interpreter we're using. */ + char logfilename[64]; + int failures_before = failures; + int oldumask; + + switch (verbosity) { + case VERBOSITY_SUMMARY_ONLY: /* No per-test reports at all */ + break; + case VERBOSITY_PASSFAIL: /* rest of line will include ok/FAIL marker */ + printf("%3d: %-50s", i, tests[i].name); + fflush(stdout); + break; + default: /* Title of test, details will follow */ + printf("%3d: %s\n", i, tests[i].name); + } + + /* Chdir to the top-level work directory. */ + if (!assertChdir(tmpdir)) { + fprintf(stderr, + "ERROR: Can't chdir to top work dir %s\n", tmpdir); + exit(1); + } + /* Create a log file for this test. */ + sprintf(logfilename, "%s.log", tests[i].name); + logfile = fopen(logfilename, "w"); + fprintf(logfile, "%s\n\n", tests[i].name); + /* Chdir() to a work dir for this specific test. */ + if (!assertMakeDir(tests[i].name, 0755) + || !assertChdir(tests[i].name)) { + fprintf(stderr, + "ERROR: Can't chdir to work dir %s/%s\n", + tmpdir, tests[i].name); + exit(1); + } + /* Explicitly reset the locale before each test. */ + setlocale(LC_ALL, "C"); + /* Record the umask before we run the test. */ + umask(oldumask = umask(0)); + /* + * Run the actual test. + */ + (*tests[i].func)(); + /* + * Clean up and report afterwards. + */ + /* Restore umask */ + umask(oldumask); + /* Reset locale. */ + setlocale(LC_ALL, "C"); + /* Reset directory. */ + if (!assertChdir(tmpdir)) { + fprintf(stderr, "ERROR: Couldn't chdir to temp dir %s\n", + tmpdir); + exit(1); + } + /* Report per-test summaries. */ + tests[i].failures = failures - failures_before; + test_summarize(test_filename, tests[i].failures); + /* Close the per-test log file. */ + fclose(logfile); + logfile = NULL; + /* If there were no failures, we can remove the work dir and logfile. */ + if (tests[i].failures == 0) { + if (!keep_temp_files && assertChdir(tmpdir)) { #if defined(_WIN32) && !defined(__CYGWIN__) - static const char *args = "-V >NUL 2>NUL"; /* Win32 cmd.exe */ + /* Make sure not to leave empty directories. + * Sometimes a processing of closing files used by tests + * is not done, then rmdir will be failed and it will + * leave a empty test directory. So we should wait a few + * seconds and retry rmdir. */ + int r, t; + for (t = 0; t < 10; t++) { + if (t > 0) + Sleep(1000); + r = systemf("rmdir /S /Q %s", tests[i].name); + if (r == 0) + break; + } + systemf("del %s", logfilename); #else - static const char *args = "-V >/dev/null 2>/dev/null"; /* POSIX 'sh' */ + systemf("rm -rf %s", tests[i].name); + systemf("rm %s", logfilename); #endif - - if (!tested) { - if (systemf("gunzip %s", args) == 0) - decompress_prog = "gunzip"; - if (systemf("gzip %s", args) == 0) - compress_prog = "gzip"; - tested = 1; + } } - return (un ? decompress_prog : compress_prog); + /* Return appropriate status. */ + return (tests[i].failures); +} + +/* + * + * + * MAIN and support routines. + * + * + */ + +static void +usage(const char *program) +{ + static const int limit = sizeof(tests) / sizeof(tests[0]); + int i; + + printf("Usage: %s [options] ...\n", program); + printf("Default is to run all tests.\n"); + printf("Otherwise, specify the numbers of the tests you wish to run.\n"); + printf("Options:\n"); + printf(" -d Dump core after any failure, for debugging.\n"); + printf(" -k Keep all temp files.\n"); + printf(" Default: temp files for successful tests deleted.\n"); +#ifdef PROGRAM + printf(" -p Path to executable to be tested.\n"); + printf(" Default: path taken from " ENVBASE " environment variable.\n"); +#endif + printf(" -q Quiet.\n"); + printf(" -r Path to dir containing reference files.\n"); + printf(" Default: Current directory.\n"); + printf(" -v Verbose.\n"); + printf("Available tests:\n"); + for (i = 0; i < limit; i++) + printf(" %d: %s\n", i, tests[i].name); + exit(1); } static char * -get_refdir(void) +get_refdir(const char *d) { char tried[512] = { '\0' }; char buff[128]; char *pwd, *p; + /* If a dir was specified, try that */ + if (d != NULL) { + pwd = NULL; + snprintf(buff, sizeof(buff), "%s", d); + p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); + if (p != NULL) goto success; + strncat(tried, buff, sizeof(tried) - strlen(tried) - 1); + strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1); + goto failure; + } + /* Get the current dir. */ pwd = getcwd(NULL, 0); while (pwd[strlen(pwd) - 1] == '\n') pwd[strlen(pwd) - 1] = '\0'; - printf("PWD: %s\n", pwd); /* Look for a known file. */ snprintf(buff, sizeof(buff), "%s", pwd); @@ -983,7 +1808,11 @@ get_refdir(void) strncat(tried, buff, sizeof(tried) - strlen(tried) - 1); strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1); +#if defined(LIBRARY) snprintf(buff, sizeof(buff), "%s/%s/test", pwd, LIBRARY); +#else + snprintf(buff, sizeof(buff), "%s/%s/test", pwd, PROGRAM); +#endif p = slurpfile(NULL, "%s/%s", buff, KNOWNREF); if (p != NULL) goto success; strncat(tried, buff, sizeof(tried) - strlen(tried) - 1); @@ -1003,11 +1832,12 @@ get_refdir(void) strncat(tried, "\n", sizeof(tried) - strlen(tried) - 1); } +failure: + printf("Unable to locate known reference file %s\n", KNOWNREF); + printf(" Checked following directories:\n%s\n", tried); #if defined(_WIN32) && !defined(__CYGWIN__) && defined(_DEBUG) DebugBreak(); #endif - printf("Unable to locate known reference file %s\n", KNOWNREF); - printf(" Checked following directories:\n%s\n", tried); exit(1); success: @@ -1016,31 +1846,42 @@ success: return strdup(buff); } -int main(int argc, char **argv) +int +main(int argc, char **argv) { static const int limit = sizeof(tests) / sizeof(tests[0]); int i, tests_run = 0, tests_failed = 0, option; time_t now; char *refdir_alloc = NULL; - const char *progname = LIBRARY "_test"; + const char *progname; const char *tmp, *option_arg, *p; char tmpdir[256]; char tmpdir_timestamp[256]; (void)argc; /* UNUSED */ -#if defined(_WIN32) && !defined(__CYGWIN__) +#if defined(HAVE__CrtSetReportMode) /* To stop to run the default invalid parameter handler. */ _set_invalid_parameter_handler(invalid_parameter_handler); - /* for open() to a binary mode. */ - _set_fmode(_O_BINARY); /* Disable annoying assertion message box. */ _CrtSetReportMode(_CRT_ASSERT, 0); #endif + /* + * Name of this program, used to build root of our temp directory + * tree. + */ + progname = p = argv[0]; + while (*p != '\0') { + /* Support \ or / dir separators for Windows compat. */ + if (*p == '/' || *p == '\\') + progname = p + 1; + ++p; + } + #ifdef PROGRAM /* Get the target program from environment, if available. */ - testprog = getenv(ENVBASE); + testprogfile = getenv(ENVBASE); #endif if (getenv("TMPDIR") != NULL) @@ -1098,19 +1939,19 @@ int main(int argc, char **argv) break; case 'p': #ifdef PROGRAM - testprog = option_arg; + testprogfile = option_arg; #else usage(progname); #endif break; case 'q': - quiet_flag++; + verbosity--; break; case 'r': refdir = option_arg; break; case 'v': - verbose = 1; + verbosity++; break; default: usage(progname); @@ -1122,8 +1963,26 @@ int main(int argc, char **argv) * Sanity-check that our options make sense. */ #ifdef PROGRAM - if (testprog == NULL) + if (testprogfile == NULL) usage(progname); + { + char *testprg; +#if defined(_WIN32) && !defined(__CYGWIN__) + /* Command.com sometimes rejects '/' separators. */ + testprg = strdup(testprogfile); + for (i = 0; testprg[i] != '\0'; i++) { + if (testprg[i] == '/') + testprg[i] = '\\'; + } + testprogfile = testprg; +#endif + /* Quote the name that gets put into shell command lines. */ + testprg = malloc(strlen(testprogfile) + 3); + strcpy(testprg, "\""); + strcat(testprg, testprogfile); + strcat(testprg, "\""); + testprog = testprg; + } #endif /* @@ -1132,19 +1991,20 @@ int main(int argc, char **argv) * to make it easier to track the results of multiple tests. */ now = time(NULL); - for (i = 0; i < 1000; i++) { + for (i = 0; ; i++) { strftime(tmpdir_timestamp, sizeof(tmpdir_timestamp), "%Y-%m-%dT%H.%M.%S", localtime(&now)); sprintf(tmpdir, "%s/%s.%s-%03d", tmp, progname, tmpdir_timestamp, i); - if (mkdir(tmpdir,0755) == 0) + if (assertMakeDir(tmpdir,0755)) break; - if (errno == EEXIST) - continue; - fprintf(stderr, "ERROR: Unable to create temp directory %s\n", - tmpdir); - exit(1); + if (i >= 999) { + fprintf(stderr, + "ERROR: Unable to create temp directory %s\n", + tmpdir); + exit(1); + } } /* @@ -1152,14 +2012,16 @@ int main(int argc, char **argv) * reference files, try to find the reference files in * the "usual places." */ - if (refdir == NULL) - refdir = refdir_alloc = get_refdir(); + refdir = refdir_alloc = get_refdir(refdir); /* * Banner with basic information. */ - if (!quiet_flag) { - printf("Running tests in: %s\n", tmpdir); + printf("\n"); + printf("If tests fail or crash, details will be in:\n"); + printf(" %s\n", tmpdir); + printf("\n"); + if (verbosity > VERBOSITY_SUMMARY_ONLY) { printf("Reference files will be read from: %s\n", refdir); #ifdef PROGRAM printf("Running tests on: %s\n", testprog); @@ -1167,6 +2029,9 @@ int main(int argc, char **argv) printf("Exercising: "); fflush(stdout); printf("%s\n", EXTRA_VERSION); + } else { + printf("Running "); + fflush(stdout); } /* @@ -1212,20 +2077,38 @@ int main(int argc, char **argv) /* * Report summary statistics. */ - if (!quiet_flag) { + if (verbosity > VERBOSITY_SUMMARY_ONLY) { + printf("\n"); + printf("Totals:\n"); + printf(" Tests run: %8d\n", tests_run); + printf(" Tests failed: %8d\n", tests_failed); + printf(" Assertions checked:%8d\n", assertions); + printf(" Assertions failed: %8d\n", failures); + printf(" Skips reported: %8d\n", skips); + } + if (failures) { printf("\n"); - printf("%d of %d tests reported failures\n", - tests_failed, tests_run); - printf(" Total of %d assertions checked.\n", assertions); - printf(" Total of %d assertions failed.\n", failures); - printf(" Total of %d reported skips.\n", skips); + printf("Failing tests:\n"); + for (i = 0; i < limit; ++i) { + if (tests[i].failures) + printf(" %d: %s (%d failures)\n", i, + tests[i].name, tests[i].failures); + } + printf("\n"); + printf("Details for failing tests: %s\n", tmpdir); + printf("\n"); + } else { + if (verbosity == VERBOSITY_SUMMARY_ONLY) + printf("\n"); + printf("%d tests passed, no failures\n", tests_run); } free(refdir_alloc); /* If the final tmpdir is empty, we can remove it. */ /* This should be the usual case when all tests succeed. */ + assertChdir(".."); rmdir(tmpdir); - return (tests_failed); + return (tests_failed ? 1 : 0); } diff --git a/lib/libarchive/test/test.h b/lib/libarchive/test/test.h index 94c66e8..6ea7b57 100644 --- a/lib/libarchive/test/test.h +++ b/lib/libarchive/test/test.h @@ -45,43 +45,85 @@ #error Oops: No config.h and no pre-built configuration in test.h. #endif -#if !defined(_WIN32) || defined(__CYGWIN__) +#include /* Windows requires this before sys/stat.h */ +#include + +#ifdef USE_DMALLOC +#include +#endif +#if HAVE_DIRENT_H #include -#else +#endif +#ifdef HAVE_DIRECT_H #include +#define dirent direct #endif #include #include +#ifdef HAVE_IO_H +#include +#endif +#ifdef HAVE_STDINT_H +#include +#endif #include #include #include -#include -#if !defined(_WIN32) || defined(__CYGWIN__) +#include +#ifdef HAVE_UNISTD_H #include #endif #include - -#ifdef USE_DMALLOC -#include +#ifdef HAVE_WINDOWS_H +#include #endif -/* No non-FreeBSD platform will have __FBSDID, so just define it here. */ -#ifdef __FreeBSD__ -#include /* For __FBSDID */ -#else -/* Some non-FreeBSD platforms such as newlib-derived ones like - * cygwin, have __FBSDID, so this definition must be guarded. +/* + * System-specific tweaks. We really want to minimize these + * as much as possible, since they make it harder to understand + * the mainline code. */ -#ifndef __FBSDID -#define __FBSDID(a) /* null */ + +/* Windows (including Visual Studio and MinGW but not Cygwin) */ +#if defined(_WIN32) && !defined(__CYGWIN__) +#if !defined(__BORLANDC__) +#define strdup _strdup #endif +#define LOCALE_UTF8 NULL +#else +#define LOCALE_UTF8 "de_DE.UTF-8" #endif -#if defined(_WIN32) && !defined(__CYGWIN__) +/* Visual Studio */ +#ifdef _MSC_VER #define snprintf sprintf_s -#define LOCALE_DE "deu" -#else -#define LOCALE_DE "de_DE.UTF-8" +#endif + +#if defined(__BORLANDC__) +#pragma warn -8068 /* Constant out of range in comparison. */ +#endif + +/* Cygwin */ +#if defined(__CYGWIN__) +/* Cygwin-1.7.x is lazy about populating nlinks, so don't + * expect it to be accurate. */ +# define NLINKS_INACCURATE_FOR_DIRS +#endif + +/* Haiku OS */ +#if defined(__HAIKU__) +/* Haiku has typedefs in stdint.h (needed for int64_t) */ +#include +#endif + +/* Get a real definition for __FBSDID if we can */ +#if HAVE_SYS_CDEFS_H +#include +#endif + +/* If not, define it so as to avoid dangling semicolons. */ +#ifndef __FBSDID +#define __FBSDID(a) struct _undefined_hack #endif #ifndef O_BINARY @@ -95,38 +137,81 @@ #define DEFINE_TEST(name) void name(void); void name(void) /* An implementation of the standard assert() macro */ -#define assert(e) test_assert(__FILE__, __LINE__, (e), #e, NULL) - +#define assert(e) assertion_assert(__FILE__, __LINE__, (e), #e, NULL) +/* chdir() and error if it fails */ +#define assertChdir(path) \ + assertion_chdir(__FILE__, __LINE__, path) /* Assert two integers are the same. Reports value of each one if not. */ -#define assertEqualInt(v1,v2) \ - test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) - +#define assertEqualInt(v1,v2) \ + assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) /* Assert two strings are the same. Reports value of each one if not. */ #define assertEqualString(v1,v2) \ - test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) + assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) /* As above, but v1 and v2 are wchar_t * */ #define assertEqualWString(v1,v2) \ - test_assert_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) + assertion_equal_wstring(__FILE__, __LINE__, (v1), #v1, (v2), #v2, NULL) /* As above, but raw blocks of bytes. */ #define assertEqualMem(v1, v2, l) \ - test_assert_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL) + assertion_equal_mem(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (l), #l, NULL) /* Assert two files are the same; allow printf-style expansion of second name. * See below for comments about variable arguments here... */ #define assertEqualFile \ - test_setup(__FILE__, __LINE__);test_assert_equal_file + assertion_setup(__FILE__, __LINE__);assertion_equal_file /* Assert that a file is empty; supports printf-style arguments. */ #define assertEmptyFile \ - test_setup(__FILE__, __LINE__);test_assert_empty_file + assertion_setup(__FILE__, __LINE__);assertion_empty_file +/* Assert that a file is not empty; supports printf-style arguments. */ +#define assertNonEmptyFile \ + assertion_setup(__FILE__, __LINE__);assertion_non_empty_file +#define assertFileAtime(pathname, sec, nsec) \ + assertion_file_atime(__FILE__, __LINE__, pathname, sec, nsec) +#define assertFileAtimeRecent(pathname) \ + assertion_file_atime_recent(__FILE__, __LINE__, pathname) +#define assertFileBirthtime(pathname, sec, nsec) \ + assertion_file_birthtime(__FILE__, __LINE__, pathname, sec, nsec) +#define assertFileBirthtimeRecent(pathname) \ + assertion_file_birthtime_recent(__FILE__, __LINE__, pathname) /* Assert that a file exists; supports printf-style arguments. */ #define assertFileExists \ - test_setup(__FILE__, __LINE__);test_assert_file_exists + assertion_setup(__FILE__, __LINE__);assertion_file_exists /* Assert that a file exists; supports printf-style arguments. */ #define assertFileNotExists \ - test_setup(__FILE__, __LINE__);test_assert_file_not_exists + assertion_setup(__FILE__, __LINE__);assertion_file_not_exists /* Assert that file contents match a string; supports printf-style arguments. */ #define assertFileContents \ - test_setup(__FILE__, __LINE__);test_assert_file_contents + assertion_setup(__FILE__, __LINE__);assertion_file_contents +#define assertFileMtime(pathname, sec, nsec) \ + assertion_file_mtime(__FILE__, __LINE__, pathname, sec, nsec) +#define assertFileMtimeRecent(pathname) \ + assertion_file_mtime_recent(__FILE__, __LINE__, pathname) +#define assertFileNLinks(pathname, nlinks) \ + assertion_file_nlinks(__FILE__, __LINE__, pathname, nlinks) +#define assertFileSize(pathname, size) \ + assertion_file_size(__FILE__, __LINE__, pathname, size) +#define assertTextFileContents \ + assertion_setup(__FILE__, __LINE__);assertion_text_file_contents +#define assertIsDir(pathname, mode) \ + assertion_is_dir(__FILE__, __LINE__, pathname, mode) +#define assertIsHardlink(path1, path2) \ + assertion_is_hardlink(__FILE__, __LINE__, path1, path2) +#define assertIsNotHardlink(path1, path2) \ + assertion_is_not_hardlink(__FILE__, __LINE__, path1, path2) +#define assertIsReg(pathname, mode) \ + assertion_is_reg(__FILE__, __LINE__, pathname, mode) +#define assertIsSymlink(pathname, contents) \ + assertion_is_symlink(__FILE__, __LINE__, pathname, contents) +/* Create a directory, report error if it fails. */ +#define assertMakeDir(dirname, mode) \ + assertion_make_dir(__FILE__, __LINE__, dirname, mode) +#define assertMakeFile(path, mode, contents) \ + assertion_make_file(__FILE__, __LINE__, path, mode, contents) +#define assertMakeHardlink(newfile, oldfile) \ + assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile) +#define assertMakeSymlink(newfile, linkto) \ + assertion_make_symlink(__FILE__, __LINE__, newfile, linkto) +#define assertUmask(mask) \ + assertion_umask(__FILE__, __LINE__, mask) /* * This would be simple with C99 variadic macros, but I don't want to @@ -135,26 +220,60 @@ * but effective. */ #define skipping \ - test_setup(__FILE__, __LINE__);test_skipping + assertion_setup(__FILE__, __LINE__);test_skipping /* Function declarations. These are defined in test_utility.c. */ void failure(const char *fmt, ...); -void test_setup(const char *, int); +int assertion_assert(const char *, int, int, const char *, void *); +int assertion_chdir(const char *, int, const char *); +int assertion_empty_file(const char *, ...); +int assertion_equal_file(const char *, const char *, ...); +int assertion_equal_int(const char *, int, long long, const char *, long long, const char *, void *); +int assertion_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *); +int assertion_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *); +int assertion_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *); +int assertion_file_atime(const char *, int, const char *, long, long); +int assertion_file_atime_recent(const char *, int, const char *); +int assertion_file_birthtime(const char *, int, const char *, long, long); +int assertion_file_birthtime_recent(const char *, int, const char *); +int assertion_file_contents(const void *, int, const char *, ...); +int assertion_file_exists(const char *, ...); +int assertion_file_mtime(const char *, int, const char *, long, long); +int assertion_file_mtime_recent(const char *, int, const char *); +int assertion_file_nlinks(const char *, int, const char *, int); +int assertion_file_not_exists(const char *, ...); +int assertion_file_size(const char *, int, const char *, long); +int assertion_is_dir(const char *, int, const char *, int); +int assertion_is_hardlink(const char *, int, const char *, const char *); +int assertion_is_not_hardlink(const char *, int, const char *, const char *); +int assertion_is_reg(const char *, int, const char *, int); +int assertion_is_symlink(const char *, int, const char *, const char *); +int assertion_make_dir(const char *, int, const char *, int); +int assertion_make_file(const char *, int, const char *, int, const char *); +int assertion_make_hardlink(const char *, int, const char *newpath, const char *); +int assertion_make_symlink(const char *, int, const char *newpath, const char *); +int assertion_non_empty_file(const char *, ...); +int assertion_text_file_contents(const char *buff, const char *f); +int assertion_umask(const char *, int, int); +void assertion_setup(const char *, int); + void test_skipping(const char *fmt, ...); -int test_assert(const char *, int, int, const char *, void *); -int test_assert_empty_file(const char *, ...); -int test_assert_equal_file(const char *, const char *, ...); -int test_assert_equal_int(const char *, int, int, const char *, int, const char *, void *); -int test_assert_equal_string(const char *, int, const char *v1, const char *, const char *v2, const char *, void *); -int test_assert_equal_wstring(const char *, int, const wchar_t *v1, const char *, const wchar_t *v2, const char *, void *); -int test_assert_equal_mem(const char *, int, const void *, const char *, const void *, const char *, size_t, const char *, void *); -int test_assert_file_contents(const void *, int, const char *, ...); -int test_assert_file_exists(const char *, ...); -int test_assert_file_not_exists(const char *, ...); /* Like sprintf, then system() */ int systemf(const char * fmt, ...); +/* Delay until time() returns a value after this. */ +void sleepUntilAfter(time_t); + +/* Return true if this platform can create symlinks. */ +int canSymlink(void); + +/* Return true if this platform can run the "gzip" program. */ +int canGzip(void); + +/* Return true if this platform can run the "gunzip" program. */ +int canGunzip(void); + /* Suck file into string allocated via malloc(). Call free() when done. */ /* Supports printf-style args: slurpfile(NULL, "%s/myfile", refdir); */ char *slurpfile(size_t *, const char *fmt, ...); @@ -162,9 +281,6 @@ char *slurpfile(size_t *, const char *fmt, ...); /* Extracts named reference file to the current directory. */ void extract_reference_file(const char *); -/* Get external gzip program name */ -const char *external_gzip_program(int un); - /* * Special interfaces for libarchive test harness. */ @@ -177,20 +293,9 @@ int read_open_memory(struct archive *, void *, size_t, size_t); /* "2" version exercises a slightly different set of libarchive APIs. */ int read_open_memory2(struct archive *, void *, size_t, size_t); -/* - * ARCHIVE_VERSION_STAMP first appeared in 1.9 and libarchive 2.2.4. - * We can approximate it for earlier versions, though. - * This is used to disable tests of features not present in the current - * version. - */ -#ifndef ARCHIVE_VERSION_STAMP -#define ARCHIVE_VERSION_STAMP \ - (ARCHIVE_API_VERSION * 1000000 + ARCHIVE_API_FEATURE * 1000) -#endif - /* Versions of above that accept an archive argument for additional info. */ -#define assertA(e) test_assert(__FILE__, __LINE__, (e), #e, (a)) +#define assertA(e) assertion_assert(__FILE__, __LINE__, (e), #e, (a)) #define assertEqualIntA(a,v1,v2) \ - test_assert_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a)) + assertion_equal_int(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a)) #define assertEqualStringA(a,v1,v2) \ - test_assert_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a)) + assertion_equal_string(__FILE__, __LINE__, (v1), #v1, (v2), #v2, (a)) diff --git a/lib/libarchive/test/test_acl_pax.c b/lib/libarchive/test/test_acl_pax.c index 5898a66..f6b065d 100644 --- a/lib/libarchive/test/test_acl_pax.c +++ b/lib/libarchive/test/test_acl_pax.c @@ -406,7 +406,7 @@ DEFINE_TEST(test_acl_pax) struct archive *a; struct archive_entry *ae; size_t used; - int fd; + FILE *f; /* Write an archive to memory. */ assert(NULL != (a = archive_write_new())); @@ -453,14 +453,14 @@ DEFINE_TEST(test_acl_pax) #endif /* Write out the data we generated to a file for manual inspection. */ - assert(-1 < (fd = open("testout", O_WRONLY | O_CREAT | O_TRUNC, 0775))); - assert(used == (size_t)write(fd, buff, (unsigned int)used)); - close(fd); + assert(NULL != (f = fopen("testout", "wb"))); + assertEqualInt(used, (size_t)fwrite(buff, 1, (unsigned int)used, f)); + fclose(f); /* Write out the reference data to a file for manual inspection. */ - assert(-1 < (fd = open("reference", O_WRONLY | O_CREAT | O_TRUNC, 0775))); - assert(sizeof(reference) == write(fd, reference, sizeof(reference))); - close(fd); + assert(NULL != (f = fopen("reference", "wb"))); + assert(sizeof(reference) == fwrite(reference, 1, sizeof(reference), f)); + fclose(f); /* Assert that the generated data matches the built-in reference data.*/ failure("Generated pax archive does not match reference; check 'testout' and 'reference' files."); diff --git a/lib/libarchive/test/test_compat_bzip2.c b/lib/libarchive/test/test_compat_bzip2.c index cbd113b..96eacad 100644 --- a/lib/libarchive/test/test_compat_bzip2.c +++ b/lib/libarchive/test/test_compat_bzip2.c @@ -47,7 +47,10 @@ compat_bzip2(const char *name) int i; assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); + if (ARCHIVE_OK != archive_read_support_compression_bzip2(a)) { + skipping("Unsupported bzip2"); + return; + } assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); extract_reference_file(name); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); diff --git a/lib/libarchive/test/test_compat_cpio.c b/lib/libarchive/test/test_compat_cpio.c new file mode 100644 index 0000000..b0ead39 --- /dev/null +++ b/lib/libarchive/test/test_compat_cpio.c @@ -0,0 +1,106 @@ +/*- + * Copyright (c) 2003-2009 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* + * Verify our ability to read various sample files. + * It should be easy to add any new sample files sent in by users + * to this collection of tests. + */ + +/* Copy this function for each test file and adjust it accordingly. */ + +/* + * test_compat_cpio_1.cpio checks heuristics for avoiding false + * hardlinks. foo1 and foo2 are files that have nlinks=1 and so + * should not be marked as hardlinks even though they have identical + * ino values. bar1 and bar2 have nlinks=2 so should be marked + * as hardlinks. + */ +static void +test_compat_cpio_1(void) +{ + char name[] = "test_compat_cpio_1.cpio"; + struct archive_entry *ae; + struct archive *a; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + extract_reference_file(name); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 17)); + + /* Read first entry. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("foo1", archive_entry_pathname(ae)); + assertEqualString(NULL, archive_entry_hardlink(ae)); + assertEqualInt(1260250228, archive_entry_mtime(ae)); + assertEqualInt(1000, archive_entry_uid(ae)); + assertEqualInt(1000, archive_entry_gid(ae)); + assertEqualInt(0100644, archive_entry_mode(ae)); + + /* Read second entry. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("foo2", archive_entry_pathname(ae)); + assertEqualString(NULL, archive_entry_hardlink(ae)); + assertEqualInt(1260250228, archive_entry_mtime(ae)); + assertEqualInt(1000, archive_entry_uid(ae)); + assertEqualInt(1000, archive_entry_gid(ae)); + assertEqualInt(0100644, archive_entry_mode(ae)); + + /* Read third entry. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("bar1", archive_entry_pathname(ae)); + assertEqualString(NULL, archive_entry_hardlink(ae)); + assertEqualInt(1260250228, archive_entry_mtime(ae)); + assertEqualInt(1000, archive_entry_uid(ae)); + assertEqualInt(1000, archive_entry_gid(ae)); + assertEqualInt(0100644, archive_entry_mode(ae)); + + /* Read fourth entry. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("bar2", archive_entry_pathname(ae)); + assertEqualString("bar1", archive_entry_hardlink(ae)); + assertEqualInt(1260250228, archive_entry_mtime(ae)); + assertEqualInt(1000, archive_entry_uid(ae)); + assertEqualInt(1000, archive_entry_gid(ae)); + assertEqualInt(0100644, archive_entry_mode(ae)); + + /* Verify that the format detection worked. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_NONE); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_SVR4_NOCRC); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); +} + + +DEFINE_TEST(test_compat_cpio) +{ + test_compat_cpio_1(); +} + + diff --git a/lib/libarchive/test/test_compat_cpio_1.cpio.uu b/lib/libarchive/test/test_compat_cpio_1.cpio.uu new file mode 100644 index 0000000..3f0ee52 --- /dev/null +++ b/lib/libarchive/test/test_compat_cpio_1.cpio.uu @@ -0,0 +1,19 @@ +$FreeBSD$ + +begin 644 test_compat_cpio_1.cpio +M,# $dir/f1 +echo "f2" > $dir/f2 +echo "f3" > $dir/f3 +mkdir $dir/d1 +echo "f1" > $dir/d1/f1 +echo "f2" > $dir/d1/f2 +echo "f3" > $dir/d1/f3 +(cd $dir; tar cf ../$name.tar f1 f2 f3 d1/f1 d1/f2 d1/f3) +rm -r $dir +} +mktarfile +$zcmd $name.tar +mv $name.tar.$zsuffix $name.$ztar_suffix +echo "This is unrelated junk data at the end of the file" >> $name.$ztar_suffix +uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu +rm -f $name.$ztar_suffix +# +# Use option -e +# +name=test_compat_lzma_2 +dir="$name`date +%Y%m%d%H%M%S`.$USER" +mktarfile +$zcmd -e $name.tar +mv $name.tar.$zsuffix $name.$ztar_suffix +uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu +rm -f $name.$ztar_suffix +# +# Use lzma command of LZMA SDK with option -d12. +# +name=test_compat_lzma_3 +zcmd=lzmasdk # Change this path to use lzma of LZMA SDK. +dir="$name`date +%Y%m%d%H%M%S`.$USER" +mktarfile +$zcmd e -d12 $name.tar $name.$ztar_suffix +rm -f $name.tar +uuencode $name.$ztar_suffix $name.$ztar_suffix > $name.$ztar_suffix.uu +rm -f $name.$ztar_suffix + +exit 0 +*/ + +/* + * Verify our ability to read sample files compatibly with unlzma. + * + * In particular: + * * unlzma will read multiple lzma streams, concatenating the output + * * unlzma will read lzma streams which is made by lzma with option -e, + * concatenating the output + * + * Verify our ability to read sample files compatibly with lzma of + * LZMA SDK. + * * lzma will read lzma streams which is made by lzma with option -d12, + * concatenating the output + */ + +/* + * All of the sample files have the same contents; they're just + * compressed in different ways. + */ +static void +compat_lzma(const char *name) +{ + const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; + struct archive_entry *ae; + struct archive *a; + int i, r; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); + r = archive_read_support_compression_lzma(a); + if (r == ARCHIVE_WARN) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); + return; + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + extract_reference_file(name); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); + + /* Read entries, match up names with list above. */ + for (i = 0; i < 6; ++i) { + failure("Could not read file %d (%s) from %s", i, n[i], name); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_next_header(a, &ae)); + assertEqualString(n[i], archive_entry_pathname(ae)); + } + + /* Verify the end-of-archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify that the format detection worked. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZMA); + assertEqualString(archive_compression_name(a), "lzma"); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); + + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); +} + + +DEFINE_TEST(test_compat_lzma) +{ + /* This sample has been added junk datas to its tail. */ + compat_lzma("test_compat_lzma_1.tlz"); + /* This sample has been made by lzma with option -e, + * the first byte of which is 0x5e. + * Not supported in libarchive 2.7.* and earlier */ + compat_lzma("test_compat_lzma_2.tlz"); + /* This sample has been made by lzma of LZMA SDK with + * option -d12, second byte and third byte of which is + * not zero. + * Not supported in libarchive 2.7.* and earlier */ + compat_lzma("test_compat_lzma_3.tlz"); +} diff --git a/lib/libarchive/test/test_compat_lzma_1.tlz.uu b/lib/libarchive/test/test_compat_lzma_1.tlz.uu new file mode 100644 index 0000000..3b63211 --- /dev/null +++ b/lib/libarchive/test/test_compat_lzma_1.tlz.uu @@ -0,0 +1,10 @@ +$FreeBSD$ + +begin 644 test_compat_lzma_1.tlz +M70``@`#__________P`S##P;IXPT!HUK`DO\DC[V2OB%Z^'=ZT59ANYMTD(/ +M^W;\8!%O7<+P&=#(9W<_!$Z.7/Y<&\(8+E0^,_-\Z"D^P'N0J^4-UH"WMJ<& +MV-P6=Y[-FY$IFNZ="RF24TO.B7EP[F]BGMJSP[]OZ_P9/#J'T=;7E&&A@J<[ +MA^C'Q*/Y&I)2^T930'MJTK-98U0D9R*-X2^5__6H:+A4:&ES(&ES('5N`W2"/3R1F1:P:&Q9A +MGH2JJI9$C?8.=WTE:O<1WA@X>DK-Y#SW;I2!P;NYG^2"-(D9/E(D_0XK_H,\ +95*/V"T#E9ZO][@'R,6E&^A([.##_\M#YU@`` +` +end diff --git a/lib/libarchive/test/test_compat_lzma_3.tlz.uu b/lib/libarchive/test/test_compat_lzma_3.tlz.uu new file mode 100644 index 0000000..b8d61b7 --- /dev/null +++ b/lib/libarchive/test/test_compat_lzma_3.tlz.uu @@ -0,0 +1,9 @@ +$FreeBSD$ + +begin 644 test_compat_lzma_3.tlz +M70`0````'``````````S##P;IXPT!HUK`DO\DC[V2OB%Z^'=ZT59ANYMTD(1 +M$Y^=;\4%U_CXKQ*F$OFZKEQUG)1U8="](V<2K"U1\Z6%H(UNQ[Y3.=D'>_G- +MCO71X+M*7WH7$D1&E9Y$XHW,(`[X";GGTO+,'&1?F%<@`.$-OV;8P1?*M$A" +:MA+1XONREMK,1('455L=X1>WC#1YW"('I@`` +` +end diff --git a/lib/libarchive/test/test_compat_solaris_tar_acl.c b/lib/libarchive/test/test_compat_solaris_tar_acl.c index ec3955e..af4f9d3 100644 --- a/lib/libarchive/test/test_compat_solaris_tar_acl.c +++ b/lib/libarchive/test/test_compat_solaris_tar_acl.c @@ -50,9 +50,9 @@ DEFINE_TEST(test_compat_solaris_tar_acl) /* Archive has 1 entry with some ACLs set on it. */ assertA(0 == archive_read_next_header(a, &ae)); - failure("Basic ACLs should set mode to 0640, not %04o", + failure("Basic ACLs should set mode to 0644, not %04o", archive_entry_mode(ae)&0777); - assertEqualInt((archive_entry_mode(ae) & 0777), 0640); + assertEqualInt((archive_entry_mode(ae) & 0777), 0644); assertEqualInt(7, archive_entry_acl_reset(ae, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); assertEqualInt(ARCHIVE_OK, archive_entry_acl_next(ae, @@ -77,7 +77,7 @@ DEFINE_TEST(test_compat_solaris_tar_acl) ARCHIVE_ENTRY_ACL_TYPE_ACCESS, &type, &permset, &tag, &qual, &name)); assertEqualInt(ARCHIVE_ENTRY_ACL_TYPE_ACCESS, type); - assertEqualInt(000, permset); + assertEqualInt(004, permset); assertEqualInt(ARCHIVE_ENTRY_ACL_OTHER, tag); assertEqualInt(-1, qual); assert(name == NULL); diff --git a/lib/libarchive/test/test_entry.c b/lib/libarchive/test/test_entry.c index b79e822..bd946c4 100644 --- a/lib/libarchive/test/test_entry.c +++ b/lib/libarchive/test/test_entry.c @@ -51,13 +51,40 @@ DEFINE_TEST(test_entry) const char *xname; /* For xattr tests. */ const void *xval; /* For xattr tests. */ size_t xsize; /* For xattr tests. */ - int c; wchar_t wc; long l; assert((e = archive_entry_new()) != NULL); /* + * Verify that the AE_IF* defines match S_IF* defines + * on this platform. See comments in archive_entry.h. + */ +#ifdef S_IFREG + assertEqualInt(S_IFREG, AE_IFREG); +#endif +#ifdef S_IFLNK + assertEqualInt(S_IFLNK, AE_IFLNK); +#endif +#ifdef S_IFSOCK + assertEqualInt(S_IFSOCK, AE_IFSOCK); +#endif +#ifdef S_IFCHR + assertEqualInt(S_IFCHR, AE_IFCHR); +#endif +/* Work around MinGW, which defines S_IFBLK wrong. */ +/* sourceforge.net/tracker/?func=detail&atid=102435&aid=1942809&group_id=2435 */ +#if defined(S_IFBLK) && !defined(_WIN32) + assertEqualInt(S_IFBLK, AE_IFBLK); +#endif +#ifdef S_IFDIR + assertEqualInt(S_IFDIR, AE_IFDIR); +#endif +#ifdef S_IFIFO + assertEqualInt(S_IFIFO, AE_IFIFO); +#endif + + /* * Basic set/read tests for all fields. * We should be able to set any field and read * back the same value. @@ -414,7 +441,7 @@ DEFINE_TEST(test_entry) skipping("ACL preserved by archive_entry_clone()"); #else /* Verify ACL was copied. */ - assertEqualInt(4, c = archive_entry_acl_reset(e2, + assertEqualInt(4, archive_entry_acl_reset(e2, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); /* First three are standard permission bits. */ assertEqualInt(0, archive_entry_acl_next(e2, @@ -455,7 +482,7 @@ DEFINE_TEST(test_entry) skipping("xattr data preserved by archive_entry_clone"); #else /* Verify xattr was copied. */ - assertEqualInt(1, c = archive_entry_xattr_reset(e2)); + assertEqualInt(1, archive_entry_xattr_reset(e2)); assertEqualInt(0, archive_entry_xattr_next(e2, &xname, &xval, &xsize)); assertEqualString(xname, "xattr1"); assertEqualString(xval, "xattrvalue"); @@ -539,7 +566,7 @@ DEFINE_TEST(test_entry) skipping("ACL held by clone of archive_entry"); #else /* Verify ACL was unchanged. */ - assertEqualInt(4, c = archive_entry_acl_reset(e2, + assertEqualInt(4, archive_entry_acl_reset(e2, ARCHIVE_ENTRY_ACL_TYPE_ACCESS)); /* First three are standard permission bits. */ assertEqualInt(0, archive_entry_acl_next(e2, @@ -807,7 +834,7 @@ DEFINE_TEST(test_entry) /* * Exercise the character-conversion logic, if we can. */ - if (NULL == setlocale(LC_ALL, LOCALE_DE)) { + if (NULL == LOCALE_UTF8 || NULL == setlocale(LC_ALL, LOCALE_UTF8)) { skipping("Can't exercise charset-conversion logic without" " a suitable locale."); } else { diff --git a/lib/libarchive/test/test_entry_strmode.c b/lib/libarchive/test/test_entry_strmode.c index 5ede8b6..70c0e75 100644 --- a/lib/libarchive/test/test_entry_strmode.c +++ b/lib/libarchive/test/test_entry_strmode.c @@ -31,11 +31,11 @@ DEFINE_TEST(test_entry_strmode) assert((entry = archive_entry_new()) != NULL); - archive_entry_set_mode(entry, S_IFREG | 0642); + archive_entry_set_mode(entry, AE_IFREG | 0642); assertEqualString(archive_entry_strmode(entry), "-rw-r---w- "); /* Regular file + hardlink still shows as regular file. */ - archive_entry_set_mode(entry, S_IFREG | 0644); + archive_entry_set_mode(entry, AE_IFREG | 0644); archive_entry_set_hardlink(entry, "link"); assertEqualString(archive_entry_strmode(entry), "-rw-r--r-- "); @@ -44,22 +44,22 @@ DEFINE_TEST(test_entry_strmode) assertEqualString(archive_entry_strmode(entry), "hrw-r----- "); archive_entry_set_hardlink(entry, NULL); - archive_entry_set_mode(entry, S_IFDIR | 0777); + archive_entry_set_mode(entry, AE_IFDIR | 0777); assertEqualString(archive_entry_strmode(entry), "drwxrwxrwx "); - archive_entry_set_mode(entry, S_IFBLK | 03642); + archive_entry_set_mode(entry, AE_IFBLK | 03642); assertEqualString(archive_entry_strmode(entry), "brw-r-S-wT "); - archive_entry_set_mode(entry, S_IFCHR | 05777); + archive_entry_set_mode(entry, AE_IFCHR | 05777); assertEqualString(archive_entry_strmode(entry), "crwsrwxrwt "); - archive_entry_set_mode(entry, S_IFSOCK | 0222); + archive_entry_set_mode(entry, AE_IFSOCK | 0222); assertEqualString(archive_entry_strmode(entry), "s-w--w--w- "); - archive_entry_set_mode(entry, S_IFIFO | 0444); + archive_entry_set_mode(entry, AE_IFIFO | 0444); assertEqualString(archive_entry_strmode(entry), "pr--r--r-- "); - archive_entry_set_mode(entry, S_IFLNK | 04000); + archive_entry_set_mode(entry, AE_IFLNK | 04000); assertEqualString(archive_entry_strmode(entry), "l--S------ "); archive_entry_acl_add_entry(entry, ARCHIVE_ENTRY_ACL_TYPE_ACCESS, diff --git a/lib/libarchive/test/test_extattr_freebsd.c b/lib/libarchive/test/test_extattr_freebsd.c index 19881c2..de3ae2a 100644 --- a/lib/libarchive/test/test_extattr_freebsd.c +++ b/lib/libarchive/test/test_extattr_freebsd.c @@ -85,7 +85,7 @@ DEFINE_TEST(test_extattr_freebsd) n = extattr_set_fd(fd, EXTATTR_NAMESPACE_USER, "testattr", "1234", 4); if (n != 4) { - skipping("Restoring xattr to an unwritable file (broken in some versions of FreeBSD"); + skipping("Restoring xattr to an unwritable file seems to be broken on this platform"); extattr_privilege_bug = 1; } close(fd); @@ -114,17 +114,15 @@ DEFINE_TEST(test_extattr_freebsd) archive_entry_set_size(ae, 0); archive_entry_set_mode(ae, 0); archive_entry_xattr_add_entry(ae, "user.bar", "123456", 6); - if (extattr_privilege_bug) - /* If the bug is here, write_header will return warning. */ - assertEqualIntA(a, ARCHIVE_WARN, - archive_write_header(a, ae)); - else - assertEqualIntA(a, ARCHIVE_OK, - archive_write_header(a, ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); archive_entry_free(ae); /* Close the archive. */ - assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + if (extattr_privilege_bug) + /* If the bug is here, write_close will return warning. */ + assertEqualIntA(a, ARCHIVE_WARN, archive_write_close(a)); + else + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_finish(a)); /* Verify the data on disk. */ diff --git a/lib/libarchive/test/test_fuzz.c b/lib/libarchive/test/test_fuzz.c index 9c5a056..7e3f28d 100644 --- a/lib/libarchive/test/test_fuzz.c +++ b/lib/libarchive/test/test_fuzz.c @@ -44,86 +44,87 @@ __FBSDID("$FreeBSD$"); * post-failure diagnostics. */ -/* Because this works for any archive, I can just re-use the archives - * developed for other tests. I've not included all of the compressed - * archives here, though; I don't want to spend all of my test time - * testing zlib and bzlib. */ -static const char * -files[] = { - "test_fuzz_1.iso", - "test_compat_bzip2_1.tbz", - "test_compat_gtar_1.tar", - "test_compat_tar_hardlink_1.tar", - "test_compat_zip_1.zip", - "test_read_format_gtar_sparse_1_17_posix10_modified.tar", - "test_read_format_tar_empty_filename.tar", - "test_read_format_zip.zip", - NULL +/* Because this works for any archive, we can just re-use the archives + * developed for other tests. */ +static struct { + int uncompress; /* If 1, decompress the file before fuzzing. */ + const char *name; +} files[] = { + {0, "test_fuzz_1.iso.Z"}, /* Exercise compress decompressor. */ + {1, "test_fuzz_1.iso.Z"}, + {0, "test_compat_bzip2_1.tbz"}, /* Exercise bzip2 decompressor. */ + {1, "test_compat_bzip2_1.tbz"}, + {0, "test_compat_gtar_1.tar"}, + {0, "test_compat_gzip_1.tgz"}, /* Exercise gzip decompressor. */ + {0, "test_compat_gzip_2.tgz"}, /* Exercise gzip decompressor. */ + {0, "test_compat_tar_hardlink_1.tar"}, + {0, "test_compat_xz_1.txz"}, /* Exercise xz decompressor. */ + {0, "test_compat_zip_1.zip"}, + {0, "test_read_format_ar.ar"}, + {0, "test_read_format_cpio_bin_be.cpio"}, + {0, "test_read_format_gtar_sparse_1_17_posix10_modified.tar"}, + {0, "test_read_format_mtree.mtree"}, + {0, "test_read_format_tar_empty_filename.tar"}, + {0, "test_read_format_zip.zip"}, + {1, NULL} }; -#define UnsupportedCompress(r, a) \ - (r != ARCHIVE_OK && \ - (strcmp(archive_error_string(a), \ - "Unrecognized archive format") == 0 && \ - archive_compression(a) == ARCHIVE_COMPRESSION_NONE)) - DEFINE_TEST(test_fuzz) { - const char **filep; const void *blk; size_t blk_size; off_t blk_offset; + int n; - for (filep = files; *filep != NULL; ++filep) { + for (n = 0; files[n].name != NULL; ++n) { + const size_t buffsize = 30000000; + const char *filename = files[n].name; struct archive_entry *ae; struct archive *a; char *rawimage, *image; size_t size; - int i, r; - - extract_reference_file(*filep); - rawimage = slurpfile(&size, *filep); - assert(rawimage != NULL); - image = malloc(size); - assert(image != NULL); - srand(time(NULL)); + int i; - assert((a = archive_read_new()) != NULL); - assert(0 == archive_read_support_compression_all(a)); - assert(0 == archive_read_support_format_all(a)); - assert(0 == archive_read_open_memory(a, rawimage, size)); - r = archive_read_next_header(a, &ae); - if (UnsupportedCompress(r, a)) { - skipping("Skipping GZIP/BZIP2 compression check: " - "This version of libarchive was compiled " - "without gzip/bzip2 support"); - assert(0 == archive_read_close(a)); - assert(0 == archive_read_finish(a)); - continue; - } - assert(0 == r); - if (r == ARCHIVE_OK) { - char buff[20]; - - r = archive_read_data(a, buff, 19); - if (r < ARCHIVE_OK && strcmp(archive_error_string(a), - "libarchive compiled without deflate support (no libz)") == 0) { - skipping("Skipping ZIP compression check: %s", - archive_error_string(a)); - assert(0 == archive_read_close(a)); - assert(0 == archive_read_finish(a)); + extract_reference_file(filename); + if (files[n].uncompress) { + int r; + /* Use format_raw to decompress the data. */ + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_compression_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_format_raw(a)); + r = archive_read_open_filename(a, filename, 16384); + if (r != ARCHIVE_OK) { + archive_read_finish(a); + skipping("Cannot uncompress %s", filename); continue; } - while (0 == archive_read_data_block(a, &blk, - &blk_size, &blk_offset)) + assertEqualIntA(a, ARCHIVE_OK, + archive_read_next_header(a, &ae)); + rawimage = malloc(buffsize); + size = archive_read_data(a, rawimage, buffsize); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_next_header(a, &ae)); + assertEqualInt(ARCHIVE_OK, + archive_read_finish(a)); + assert(size > 0); + failure("Internal buffer is not big enough for " + "uncompressed test file: %s", filename); + if (!assert(size < buffsize)) + continue; + } else { + rawimage = slurpfile(&size, filename); + if (!assert(rawimage != NULL)) continue; - } - assert(0 == archive_read_close(a)); - assert(0 == archive_read_finish(a)); + image = malloc(size); + assert(image != NULL); + srand((unsigned)time(NULL)); for (i = 0; i < 100; ++i) { - int j, fd, numbytes; + FILE *f; + int j, numbytes; /* Fuzz < 1% of the bytes in the archive. */ memcpy(image, rawimage, size); @@ -133,11 +134,10 @@ DEFINE_TEST(test_fuzz) /* Save the messed-up image to a file. * If we crash, that file will be useful. */ - fd = open("after.test.failure.send.this.file." - "to.libarchive.maintainers.with.system.details", - O_WRONLY | O_CREAT | O_TRUNC, 0744); - write(fd, image, (off_t)size); - close(fd); + f = fopen("after.test.failure.send.this.file." + "to.libarchive.maintainers.with.system.details", "wb"); + fwrite(image, 1, (size_t)size, f); + fclose(f); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, diff --git a/lib/libarchive/test/test_fuzz_1.iso.Z.uu b/lib/libarchive/test/test_fuzz_1.iso.Z.uu new file mode 100644 index 0000000..6044296 --- /dev/null +++ b/lib/libarchive/test/test_fuzz_1.iso.Z.uu @@ -0,0 +1,495 @@ +$FreeBSD$ + +begin 644 test_fuzz_1.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GA0%`(,)$`4'QT(0``F'H@``@"(PJ)`"(A"04(6#"0" +M`!P4E..+`;'(Q@(6),!``^"$>&)`*`+0X9),-NGDDU!&*>645%9IY9589JGE +MEEQ>V<0224SQA!%3@!#F$R#D8(,-,+R`!)D@&)$$$T5,D<445!2AH1!5S$E$ +M$5*`8`((%Q8QQ!-2/"A@"U*\0(05BDI11!!4(`H""D.D`$(,.>0P`PA%N)#% +M$U4X<0010=!Y:::;=GH#"$JX`,6D4HCIQ`NQ3C$$$G,RD82I708K;+`R$(A# +M##'(4&P.R<8P`X'@%`O#L,L<,Y`&"#VP#``,`7`"!A=L(.`SPV +M$P"4G'`69%/1=\8,'UR%V`#PO7#)%CML`L,3+VQQR1-C;/'"$E/<0L5S4VP% +MQ9E/#D`074-=^M2G,QTNLN.6>VZVJU=+[K70>FO[MN`:R[JUYF(+3KKV!B_\ +M\,07;_SQR",K`QD.-`Z!A(B#`%B'0`800A3Z\(_\A4#DAM%<""0&[YR%0&3PSE8(!)D8/85` +MM(K14`BD!N_AM%*".0&[WR$0'#PSD0(I&T8'81`K(K1/@AD!^^\@T!X +M\,XX"*0'[UR#0'SP3H(%Y)<8I5M`I(I1P`6$=!A-6$`.AE&-!61B&#V"0!:& +M4=(%I&08A>V_WHG9@$@7HX`-B-TPF@*!C`VCYA"($MZ)U8"$#:/>$`C?,(H- +M@6@,H](0B!/>R0R!8`RCQA`(%-X)#(&0"*.Z$(C%,$H+@20,HZX0B.`PB@J! +M'`ZCHA#(YS#*"8&D$J.6$(A0,0H)@0`.HXH0B!;>20B!;.&=?A`(%]Z)!X&4 +M$J,,!(!/,.>2`A.&=*PZ(&-XIN("$$J/[#8A.,6JW@!`, +MHP<+2)`Q2MN`G.&=;PL(&MXIMX!T$J-L#8A-,7H.@>@6HUP-2(\Q^@V!M.&= +MV1"(&]XY#8%D$J/-$(A,,7H,@=@6H\$0B,`PN@N!S.&=M1`('=[Y"H%4$J.I +M$(A+,3H*@<@6HYT02(TQ>@F!Y.&=D1"('MZY"(%$$J.%$(A*,?H'@;@6HZ<. +M2(PQ^NB`U!JC=PX((-[YY8`T$J-'#HA),?KB@*@6HX<+2(LQBK&`Q!JC8PN( +M(=XYL8`D$J.X#8A(,0K:@)@6HX@-2(HQ"M>`M!JCZ!`((][YN(`4$J/@$(A' +M,:H-@8@6H]002(DQZ@R!I!JCR!"()-XI#($$$J.\$(A&,6H+@7@6H[`02(@Q +MJ@J!E!JCI!`()M[I"8'T$:,C#TA%,;KP@&@6H_,.2( +M@$@6HPL+2(4QRMN`9!JCI`U(QS'*V(#$$:-T#4A"K3O!NMO][GC/>WBDAZ,C +M^3T@&0P`#@7R0<%_\_`CS-E/3]3"%\9PA@.IH0`&'Q`=#@#QF/\[`(9(`-(5 +M42!)[#P3!^)$T1?H\P&9HNFM.!`LFGZ+`^FBZ;\XD#":?HP#*:/ISSB0-)I^ +MC0-IH^G?.)`XFGZ.`ZFCZ>\XD#R:?H\#Z:/I_SB00)I^D`,II.D/.9!$FGZ1 +M`VFDZ1\YD$B:?I(#J:3I+SF03)I^DP/II.D_.9!0FGZ4`RFEZ4\YD%2:?I4# +M02*F)TL#$3:FATL#43*FUTL#\4NF%TP#T3:F9TP#@4RFITP#L3FF]TP#$4VF +M-TT#44T%0'D`H$T&@'F(IWDW<@`8)1#GE``M&!#LI``Q"$\`L``U6$\,4(/Y +MU``UV$\.4(,!]0`U6%`04(,)%0$UV%`24(,1-0$U6%$44(,:50$UZ%$64(,B +M=0$U:%(84(,JE0$UZ%(:4(,RM0$U:%,<4(,ZU0$UZ%,>4(-"]0$UV#@UR#90(U*%8G4(-FA0(U2%4J4(-NM0(U*%=0,U*%HX4(.FE0,UJ%HZ4(.NM0,U*%L\4(.VU0,UJ%L^4(,$\P,U2#=` +M4(,G5H,)(P0UJ#%#4(/2A2J:1SJ3HGFP900UB%E'4(.`A00U6%Y)4(/II00U +MB%5+4(/QQ00U6%]-4(/YY00UV%]/4(,!!@4U6&!14(,))@4UV&!34(,11@4U +M6&%54(,99@4UV&%74(,AA@4U6&)94(,II@4UV&);4(,QQ@4U6&-=4(,"XP4U +MV&-?4(-!!@8U.&1A4(,K)@8U*#AC4(/[108U:#=E4(,'8P8U2%MG4(-O@P8U +M*#=I4(-LI08UV&9K4(-+4(/QQ@@U^#B-4(/YY@@UV&^/4(,!!PDU +M6'"14(,))PDUV'"34(,11PDU6'&54(,99PDUV'&74(,AAPDU6'*94(,CIPDU +MN'";4(/SQ@DUN&V=4(/#Y@DUN&J?4(.3!@HUN&>A4(-C)@HUN&2C4(,S1@HU +M^#FE4(,#9@HUN%ZG4(,+@PHUR%NI4(.DI0HUR%BK4(-TQ0ITIW<8FJ$:NJ$< +MRAL'4C,7!``A`@LH,SK#=@LEBEQ&I*(LNJ(NVJ(P^J(R&J,T.J,V6J,X>J,Z +M&@0A$@LF8B1!,&RX8"(\M*-&FJ-(>J1*FJ1,NJ0K&B*R8"*?%Z0`D`LF^J0`,`LFPDVC$R*T8"(OPJ,`4`LFPC)E"@"V8"+N]*;O($_' +M%2+P8$]W"@#QH$][*@_^M*?S(%![2@\&M:?UH%![:@\.M:?W(%%[B@\6M:?Y +ML%%[J@\?M:?[,%)[R@\GM:?]L%)[Z@\OM:?_,%-[ZG<6I*9)`@`\]:8"8"(K +M]*8#8"(=]*8$$#1[6@`F,D1O:@`F(DYJ>@`FHE9JB@`FTEYJF@`F$F=JJ@`F +M4F]JN@`F$DUOR@`F(E9OV@`F4EYOZ@`FDF9J^@`FTFYJ"@$F$G=J&@$FPDQJ +M*@$FXE5O.@$F$EYJ2@$F4F9J6@$FDFYJ:@$FTG9J>@$F@DQOB@$FHE5OF@$F +MTEUJJ@$F$F9JN@$F4FYJR@$FDG9JV@$F,DQJZ@$F8E5O^@$FHEUJ"@(FTF5J +M&@(F$FYJ*@(F4G9J.@(F\DMO2@(F(E5O6@(F8EUJ:@(FDF5J>@(FTFUJB@(F +M$G9JF@(FHDMJJ@(FXE1JN@(F(EUOR@(F4F5JV@(FDFUJZ@(FTG5J^@(F0DMJ +M"@,FHE1JZB^$\Z8R8")1IJ8S8"+5IJ8T8")9IZ8U8"*MI*8V8")&I:8W8"+* +MI:8X8")-IJ8Y8"+1IJ8Z8")5IZ8[8"*I]*8\8")"]:8]8"+&I:8^8"))IJ8_ +M8"+-IJ9`8")1IZ9!8"*E]*9"8"(^]:9#8"+"I:9$8")%IJ9%8"+)IJ9&8")- +MIZ9'8"*A]*9(8"(Z]:9)8"*^I:9*8")!]J9+8"+%IJ9,8"))IZ9-8"*=]*9. +M8"(V]:9/8"*Z]:908"(]]J918"+!IJ928")%IZ938"*9]*948"(R]:958"*V +M]:8@&#![>@4FTFMJB@4F$G1JF@4F4DEOJ@4FXE)ON@4F(EMOR@4F4F-OV@4F +MDFMJZ@4FTG-J^@4F$DEO"@8FHE)O&@8FXEIO*@8F$F-O.@8F4FMO"GD`D'-J +M6@8FTDAO:@8F8E)O>@8FHEIOB@8FTF)OF@8F$FMOJ@8F4G-JN@8FDDAOR@8F +M(E)OV@8F8EIOZ@8FDF)O^@8FTFIO"@@@@FTFEOB@@F$G)OF@@F4D=OJ@@F +MTE!ON@@F(EEOR@@F4F%OV@@FDFEOZ@@FTG%O^@@F$D=O"@DFDE!O&@DFXEAO +M*@DF$F%O.@DF4FEO2@DFDG%O6@DFTD9O:@DF4E!O>@DFHEAOB@DFTF!OF@DF +M$FEOJ@DF4G%ON@DFDD9OR@DF$E!OV@DF8EAOZ@DFDF!O^@DFTFAO"@HF$G%O +M&@HF4D9O*@HFTD]O.@HF(EAO2@HF4F!O6@HFDFAO:@HFTG!O>@HF$D9OB@HF +MDD]OF@HFXE=OJ@HF$F!ON@HF4FAOR@HFDG!OV@HFTD5OZ@HF4D]O^@HFHE=& +MU*%F?=9HG=;LP7$K=>%?=@WRMD^DW:?[1-J`^D^D/:@#1=J&>E"DG:@+1=J,^E"D_:@3 +M1=J2>E%\#0"5RE&DC:D@-=R;2E*D[:DH-=RARE*D3:HP-=RG2E.=;2(XI=@' +MPE/9'2)`I=@\1%2*741(I=C7Q%2*S4U0I=CD1%79S2)8E=TLPU79[4Y@I=CS +M1%:*?4]HI=C[5%[9_4]LE=T#!5?9?5!TE=T+A5>*_5!\I=@3!5C9/2.$I=@< +MA5C972.,E=TD!5F*#3.4I=@LA5G9+3.*+3B#IMB'H3.L'\] +M(_\!C0````4@`32`"%`!%H0&^``!0`0\"!30`G9`#0@#B<00U!D`((,0A`R" +M,^H?S\!_%P1%!($:&``2@1-H`L!J=-S``'``!T("[($0T`$.A!\X`2M@`+B` +M19`(/D$UF`$!@*3Z(`3A@S3!%[@&9>")H$,HZ)M002O8!`2:X06P4,%[()9<@6S$I>L`VHE8$P`L3@#D$'KC`,!L$S.`1K81IT?[@P%^K" +MQG`%W5@W*83`,!@*PQ&R!;N@0/B"!2$"]D`R6!!F(1I<@[9P#>[":4@-JZ$U +MO(8X(HX$3$@AOD(OK#X180!,!&9(8$X1TBQ)VX!D7B@9@T3H0@.)&46`>C +MH.E!+"Z1(L;$T#C0T02NZ2,:V'2L+'LDR.9(^/HD621/+)(9/@BT>-:5(_L\3^* +M2+@(`*A8]VF2%Q)@K,C\:!ZKY)"\DC(R2Q[)$)&Z$)79C3OY&.VDE!X).Q(YJTCTRL/3C)T_$^K&//E)* +MDDD.22C/I*%DBXA22]9(+EF_VD^C#`#O!U)&R049)!LD1_R0$+(P6I'):ITC@>QLK5?Y(E#-@OS))2OL([>2FQI*;$E5FQE00@:VDY +MH&2LG)2E,E@^2SQ)+%5E5J0E!HPXF1EUT4)"Q#T8*=$FQUR70K-=2L.E23@+I^$\G)DAR-Q- +M@7`C\B:*I)K[T&^>S+E9,PVFFI2'FZ<@0$T8(37UY@RLFANR7D+,CADX/V;/ +M0()J,R!0%<=Y"04/WQR5H?-J:L2L63DG)HA$G+@S=^K.W=D8@DSJ!`"K,VK> +MQA,A#B-G['R86)-@UDZ5>3L59T%HG,)S;)X,?6@#C^??I)D`P&9>SEO88]K+ +M0,`JK#,<1D1>Q0?/)9U$GK-3>69/RZDO;R'O?)_P,W[*S[D09+SG5?F4Q;-Z +MRLKK23G7I^V$C0#`=ZI#_$D]`P`_1)>R,SB23JTI.-M@CXDS`X&KA$^R.3Y! +M(>S,0))6$(Z@^*2"F:!O6L\BVC:/:,\8`G$S`.S,L=)$^Z@?_:.`M",$F3T: +M$*+)#P4:)U1RVE`SFD/;H,#PF@``;%9"Z2E&>=79/)Z_HZT&@E@YI,2S@@K1'SDH1^<579Y;T#0[2@F!(P>C4K*0&5)&646#:2$]GC_%6`Z&\H%(I^#K-9RM- +MGA$3EC;0TWE+NZDW_::!-,A`4X$@38VIYR2>B72.+E)FVDF%*0#0I0'AE)K3 +MQXE,4>@U39_9U'\R3P#:8]+,0&`KT]1U!E$Y2D9=*?;DI+<3G"K4A0 +M\:<"`:#.T]:93@LJ-EV@VC2+YAMQ6A#**><!=2>`LME6E*;J1;M,7%G(-`5EEI-A^@]M:('E7VV4VYZ4[NJ5_VJZR_( +M1-6YPE.3J3IEJD#5I`I5E%H05NI$#8=)59D:U!NJ56]G&EVC!\&-4E`XZE)' +M*EHMG3(U`^)1;.4R[PI8/:R(-;%FCR!36`/"Y@BH%=6G_E4L&EA/YR,M")+4 +M&W9.>HI4S2;:S*1L,ZTZ57#P20/`6`T(=*7'R*N!X%6HZD"]H))UKC+2K:I% +M%:MMO:VX-3\$F=6Z5\JJ4FV6LI6=-D\`T%B)*P$5J5DQX&0B` +MQ;62S[Z:7&FG/HVE:C*W:M?MREWM0Y!YKG_%M\K5B_I*K^LV7:N\-2"TUK=* +M-N/J60VN396V-M>X41#DAG2UH-9TJ<)7T2I?NZM__:\`UCP$F3(S$.PK>X6< +M/=6O[M?EJE8W*@``KP$ANA[8>CI>\2E&-:\:%0FFFX&`6.[K*I64"I:\9M7_ +MR34#K(D]L2BV.@29#7M8Q.M[%;%TE<3*T@%;7X]K+PVQ%K:\(E1^"BX*`F/Q +ML-15O\+8V9I04ZR1/;)(EC@$F;8S$'[LA$6GR%7(YM@1NT^YYHHM"!WVR8;4 +M&UM=-VE=!:!W=2`$`#9*$/0J$.55<12VXEBL&F.K[(PF<[K:?]M(D3`%#:R>)B+>J4;;/8]5MN43T+`/BL +MEBV;7%;*LEDBRV.[RT#`+)!NYUJK*6N5*69FKL/VVX#;<&H8@8VTW +MR[%=L]PVHU;6M5IL`P*N?;9^5ELF6_YZ.WM,N1D(H"7;LM)MVVB_K*\5MP`W +MX`I<^@D`[NUG.;>9]L)NVNQ*;@L"MH6WL7;72EMERV/3SD`@+?H6Q"9<'>MO +M.>W`_;@@-^22A2!C<4<+PN6W7E;&,MR"6Q#R+<1-L!N7RJ9:(PD`PJP&(;,# +MP5I$KM$]NDA7*009HAL0VD:?C;@_=^+26T$; +M23&KH0V;F[5U%E!%2T49;HS(&@A6)>-66*G+8$=KTGV[ +M<#?NZH0@L*MJ):_K?;VPMR0$&=,[6RZOZ)RW;;>_4MZ"D'@_[]K-O*.7YO:8 +M<#,0<$OJ1;:,=^HZWMC+?)NO\XT(08;XWA;;FT"!+^NEN;.W(*!>W[MXV6ZW +M;;!(L.P,!-YR?-'MZIVY>O7YJM_URWX'0I`1O[N%^E91ZXM^;V'T+0C&E_NJ +MWJ];?]$H`%"C8A;G"@2=FTKY*J9%N9I6\WY+.*LP!4(#;K\0.`(?W2#S@`'` +M+WFZ,!&WZ)<(_),@/A +M8$!A,CR$,^P5?L-P&-P&&30L$-0P$(ZWMS?YYM[AFOZ,2$"%MDF8_IIA`-!M +M!L+$6,.AMPWOW3C,B!NQIPTRA5@@'.([#'7SL!+6N]YV#A<$.VQ41?"6'<.) +M&`5?WR/88\+.0%@8B-@2"V(W[(A;L2M&L4'&%$^7+0Q3]S``A<0%81)WXC`Z +M@D&Q*B[#&=;F(@D!+&[9<"`1J_XFE,C6]JD)'& +M@P,#!]Y`#(P7L0?FAE@7I,):2_I9U>$JWKNE518'A(718YS*0``8J;CZ=F-O +M6XWKL3U>J$'&'0L$>$R)?;$\5L29>'`0A)+QA_'P/V;&@]AJ#03I$H_G[SP& +MO_!L+882<8?-Q0>#'N_B8]F*-3(-[K2SM,55F(-B- +MALR%E:_'G<@P.2;7TB"3D@7"2L[(H/<7`V3P6Y$+`D8.R>?T$Y/D*"QS!W&V +M&0AC@R77XN_K=F6R4W[*?33('&7S0HM_JBVVLG6C(-QDH,Q9A7)./L@;>`KK +M4`#0=0;">E'*5IDI]U>HS);;L@<-,F59O53ER;J$>3+B(`A)&0EOY+`\BF^A +M,#X1Q'BS@I`"_`F3\;Y=QGRY&=_1/`HO!4)C=LN0.3)?PR#SF`%`V-#&7]DA +M[V2W^XV_)@C6K.)XZY9C@J!).3(ZSJ-Q.2"LEQZC5`8"WT#+=!D30V3)3)MK +MS:8YS+0-`8L)DWU^6F;)N;LW.>AD'& +M.-N7W8Q[>_,M3AP%X34'9Z)<@S-LCXDR`V&_).?JO)S7\G,^S^A9_049\*Q? +MJ+,>MLY863H'!.2\G1&S%.[+8[G:#`2,,9[?*[/H3@Q#^*L,Q`&3'].T!PX_0[H#]N_/&;SJC'>N0;8YZ9H":U1X:RX-#`=.D?K:/\09&YT0"`1 +MF/GW/F3.7'4)[6>^NJ'9LV)2],-@A"PK#231I`;^DY3:?I0Y!1 +M+@/A38?I[GNEW6Z7+@A@FBMK78.LF54T^.TQ3<90XL^6>H#5='=>Q'4Z4DMJ +M]Q!D$K6$$=%Q^CKC:0>#IC-S2[[*)QD`1)N!<#C@])B6TY,Z5:OJ\!!D1K6% +MP=2G^CI;ZIK9J<6TH7:[/:;J#(3/8:IOM7E>U<`Z6&N'(*.K-0RL]M7#U54' +MA%*-HL'R?5;,6I1%!V8"3$T+T$P[(`QMJAV;%?01E-8N +M>J8>8\.L<;GSV1Z"91L!X09TV-BUT#P*5Q[.'MMO\VY._>XU3$%`7/OZ<+]L,ETX`8` +M@YMM*V?9#+&%RT"@&YF["V=7STV[:_=B"#*NV\>8;%H(,_Q8(_MM]"V?9K6K5=T%HW_5[AE9B9XVSP2_< +M-@C46J"BV6L=H>$WZ+M(?F%TK +M;I',N)`=P$T[$B[A3"#(^7"``<05NMWDW +MYDSA*WQ[^^?\S6-]RT`@&$&QR.%^0)[K`).<1..@-A +MS"CR#,W('[DI/^4V(QE!WL)+MUW]OW@5@[]HPKS! +M&[4EO]MI$,ZR2H$PS%&Y,3_F(B'(%',`T$E8^/NNX_U572?NK"N\27#C7IOH +M>D:6UE4N9I!@^!H(-F64BV4DBLS+N3G?"$'FFPN$<.[**?@E)]/+O)E+<0P] +MSD]J^1H(ND6NO]-7SHWC +MKU5&NW-@/E/_N46_Z!0AR#CT`4S0R;=!%^@!(9_/@+O*`+7P!0=`;"GDGI%]NE"_6A#L=[NIZ9 +MZ4+R+O(4" +M@,`>$/1Z8G?AH3K'*!J(/EU]^2O'Z@!TLJOV[<#]D0>9W>YH,#LIU^RN'8!MKY6B7M`Z.VX/:Z#65P>@.,V.9_;'/RT._=;"6<7 +MI:6Q[O!]@`<9]QX0*DEL+^.S_19*\R,]PX,R6W?K?1&NH_9'FT>S>T"8-#T& +M@@T$ES+=[7A\?_"V.\@H>$VSW??YZ9SO!<&^A_(KN0`%`KAD(IZ;&IW8U.!TV:[3WS9YO[GFG:NB=],^T;6\,\96 +M?-+5B/D]'[.#3)X/")'DOO]R.V]9T;IGEN'4W'Y; +M@\(&@DKY\B^9SVMZ5&_YO%[F^>>`("%#037@NF'^*9_ +M]1H[R*AZ6P/J`[*G#PB7/LOG][$,PP9"C&GUFQO6"WN,'61ZO4#X]5*>>!/V +ME3OK`P*KU_6G?BS3L(%0:X`]S1WVV%Y@!YEI+Q"J?;+'WYG=G1I[75/J!_VN +M+_)R32`,&VNOH;.]NP?602;="YM:;Y>YO:\I]^J=RD?K-S^,XWQMW:O6FLY/ +M>4+O`?-HFQ0(!__=*_P<'602/@!H)((^WQ/\?+/?$7V27O2+EDDK]D>?1^7] +M#4."0&P@F!1V7\H7OLD/T`RO((S\;U^UE[U!=_@0']J;=5(,`(C80%`M)+^B +MG_R=KZ6#C,T7"#B?Y;?MX^Y.0[Y`6/D1G,*R<="^V)'80&@Q.9^?\_RIS_`! +M@-,7"%!?Z*_N<%_E?[ZSP?=U_MR?5"8V$&)-U.>J5#_M;^@@0_8%@MG7^MR; +MZZ_5JR]MP/[`%_M/%0#4G(&P;<[^OU?[@#\]!YF]+Q#Z/MR?XG+?P;9]:V/W +ME7WBM_(`&,[K^D2RMA%_;($$L-A!$BM]?Z:`_]\/D($/[!8+M/_STW,*OU=&? +M2)9[FC;WT;[(<[&!8%INO^Y__I(YR"Q_@=#\@3])Q\J]7]PT?G"?^?,^&!L( +M*<;Y0__QSY:#S/<7".'?^COZ!3W]S0L8'0:L0_^;__,3G(S'^! +M4/_5O^O'G.>?NO'^#7WNA:.N6O_W36G.EU_VEP>]0`&!/-&CP''#`0>A0)X`@Z!$EB0\0/J&Q'@ +M<*4"LH`R'TVWT]$Q`X%H(002@53@&Q9D0('^1A)XG1V!`4$0V`0F=3L='C,0 +ME!A38!5H!N9@0888*'!H@5@9%A@02(%?H,NWT_$Q`T&J40:>@7A@^Q5DT($& +M!QOHA:F!`0$9&`?&?P!`RS$0+!QW8!ZH"#I?088AJ'#X@2L7'Q@0V(&#X`4( +M^>5R4AWEQ\MU@`(?YE<`PEDWDL.Q"(Z"D5>0$0H&!(%$"WCW@8!:5,4W`WIB +M-2#K=P.N?RH8MN((!@0+1X^!R`P$&D4B2`K^@B!7D+$+2AR0H$%W"@(`J6`E +M6``B08S,0.!9^(+`8#3X=@49S:#%40PN:,-@0-`+*H/"WWP%R0P$(08T*`V. +M@R)7D/$-:AS7(.94#08$SR`WJ.+U&)3,0%!JB(/D8#TH<`49\:#'D0Z><>=@ +M0!`.NH.#6,HQ$(P<]*`]:!#*80"`0"AR[(.:73X8$,R#`&$PQN\!9O[>2C?G +M77[81Y5()L=!Z!$&6T$&1Q@0]!&JH"?8#79-5I?%1P.*9K(@\(0#AEUY +ME$(8$(P%.Z!0F64&&4B@0,(5!86Z'E?F$*H=1B/@AA0``*C,0=!A-X5,H%L)B +M76%!`!96A>(=5B85NAQ:8?#W#@(`K,Q`$&J$A6-A7?A?!1EQH4`P%Z*%'-[* +MY14*!&=ATC>2>6H9X4G88\`R`T')01?:A8RA=A5D((8"@6+(%\)X*U=>:'.T +MA2^AJI4!YEP;(,_E`:Z"+^`:!&=-2`(!:=@8GH:X59!A&@(`>41)6!BJ>*Z@ +M6D?#Q8(9WPU'"Z9!I15DJ',@0;C,0!!1+(:H87`(3@49O:%`\!M.AOJ>@[4: +MMH81X2+68_`R`X%E`1P*A]2A315D0(<"@72('$Y\6U1Q*'1@AK?A6`;,#`09 +MQG18'9Z'^%B+4!"4A]LAWN=@88=&!WCX_Z%ZQ,Q`T&F8A^AA?MA-!1GUH4!P +M'[:'K*"#-1X*!.RA8.B5V6I68:B&S`P$(0=^J!\^B+-4D+$@"@0-(H`8&KI3 +M_:'3(1\*A3379CB`=88QFC*&_%V((>"`)!"8B!!BBFA+!1DH(@!01[B&\)\E +M&!N"9BNADE8;-GKSH2>51TV(4@<2!,T,!`V%@Z@B#HF\4Y#Q(PH$0:*%Z`1B +M3BWBB]@<,F$``#4S$$@60B*1:"6^95%B04`E*HE@(.9T)&H=&V*"N-AA,P-! +MA5$E7HEH(OP49)")`H&9R"7*@9B3E"@0;(D&(EM'&,:(RV"/P*;^/BMB06!FU@G`F(+77*(!($S`T''X2<"BI1BX11D0(H" +M@:1H*%J"@F)!4"@NBO<;GG@2>HC%F"9(U7&"&*&HJ-+!6?"10-`J5HJP8I'X +M'A4$<02,2`">A#-BNP8+LH0W8NO'(=:"`0"FJ'8@0>C,0)!03(JQ8K(85@$` +MQ:)`<"QNBLM@D/$JSHK&WYUX*[Z%[,Q`X%@@B\IBM[@+!1G9HD"P+4*+)V&0 +MT2S*'6%B6ABJP3,#083!+7J+\&+[$V2PBP*!NT@NJGC@8D$P+H**G)Q)^!;2 +M,P-!I?$NQHL$8UH39`",`H'`>"_Z>```O1@0V(O\(G/G+PYBC9!`D'$,C`5C +MQLBA!!D58T!P,2Z,(1O"&!`HC!'C\2?QN8>78'DW^9UWE5]5)R*>C`$BG,4= +M"00SH\9H,]YF`$#-F#,RA(Y4##C-77RK7Z\X"^:(&5!IU3$"`!E'CP'0#`0% +M!<9X,SZ-UD.0L30*!$TCR!CJZ8QM1+6((*J+BQU!,Q`H%DXCU"@V0A!!AMF8.6)REF-`@#DJ +MCDN?F*@93H0MVLHHY[6,J.++&#IVB<%<'H4<"03#8^IH/$X004;Q"`"D$;8B +MW(@K^HRHW^<(X#E%`AYER/%A*ZQC0%!Q]!@8S4`04)R.QV/XN!X$&=VC0/`] +MOHYDFO+(/#Z)A1Q',Q`8%N"C^"@_,$V2'BCM,:B&CY^8Z@H>AXYP4`M)%`$$2ND$2D;@4`#)%'9`?9"D*/*N&N +M:"-V71K?KX@;YE$N9$`04<:='1D0&!'\I%L'HF8]_$T`T&B,4@6DICD)#E?`34#0<-Q26:2K*1Q$&2@D@*!*OE)8DZ< +M9$#@29*2(Z(/>3J1BH+9&[5#SG$PHRD)9WE&`@$QV4H>DZP:`&!,*I-*),7' +M1+Z":QVO"$7:AD1CSU!:P9(!0 +M!]4,!`&&/$E/'I2S09`Q4`H$!:4^Z4[=DP%!/OE/_HYP(JI'U0P$A89!B5!N +ME*Y!D'%1"@09I4-9Y2V4`4%#.5'VD'YDD8?5#`0)AT;)4;Z4J4&0L5(*!"VE +M2+E6?90!04AY4DZ,$F'DU^_ICO_>165!P%<*EJKB(!9H$`2!!F*I6&Z6 +MD4&0<5D.!)DE9`D`-)8"P6-)6>:-;%K!01`4')HE9^E:,@9!AFHY$+"6HN5G +M*1"$EJ>E\ZCB\9(9G&?8"0Z6-5H>)1>U'J]E<5D;!!G#I4!`%_65N6)_UY71 +MAM,DCBA%ZHC8BFPI$!0E=IF\VR'8)52*7!<%RF5L>A7&C +M74$0V!7=Y7?I7OH%089Z.1"PEZ*E=CD0<)?L(\267Q`$^45[^5[^EWE!D+%? +M#@3]I6@I7PH$].5YN17&C7T&0=!G^)<`9H1)%P09#>9`\&"*E@.F0%!@*IAN +MX2`6$*6&.F&]!D/%A#@0AIFA980H$%R:'F1G>D#XE10A46H2\(]VV +M.*J1>%L>M14-!#LFB>EC:@9!1H^9>D"5S67JEVC9@"YA>%@TYE$GID`07$$0R!54II5I9H8%08:8 +M.1"0F:)EEBD0;)DNII)Y4M47!$%]46:>F7@F5Q!DT)D#@9TI6JJ9`@&;&6=6 +MDWE?GD$0Y!EW9IZI:%X%08:A.1`@FJ(EGRD0^)F#YG19Y/4;!$&_D6@NFIRF +M5!!D8)H#@:8I6CJ:`@&D66EBE6Y>C)D[9H(LXR9H8]:08*9HF$<%1:1'IVEK +M%@9!!JTI$`Q%S.4S*1OZ=]*D54E-6IK69!X%:@H$_4:/<4X0!.?$IGEK/IL] +M09"Q;`X$S:9HJ6L&!+SFJ6E#TGQN!4'@5CB;T&:X210$&=WF0/!MBI;3I@OR +M9>*8J%Y\01#$%^"FN"EO_@1!AKLY$,";HF6Y*1"HF7@*1`,GF4G7`D`M!D$09O1 +M>#Z>H&=&MWD6!)ZG:"EY"@249^89(")! +MJJ71SE-2T7L:7PV!4$&'#00R$%.)SWD5N9`4V=` +M$!`1FUJ4I*)#$`0ZQ#2%!PU#C)H?Q'U^G^!G^%D('4(!@#I0$)B?!L'1>#0> +MGW=E+[1!B)_P9_QI0MR8CB+[:7]F!T'&]3D09)^BI?))>*R;CJ*D<@(-!-J$ +M]@E^OD[>I_RI@"Z@\"?YR0X4!`]H^ED0K)_WYU+I?OY"#&@&"@RA33AGU:GS +M5:`@:-)9@IA`\E<'JG,Z6/JG0,!_YIX!I=$9@KZ@KL&-`*(,!#<#$":#V@P$ +M%%9!HHA9'Z.!>$.HARB*F+4^&H@'#V5CA$HV2*B3`H,NH7+!C5"G$`1U"F1U +M(\0I8I;KN"AB%7D*09"G3%,_*!/JA4H0-T(6.A!LH39H:5,01*'/%E;1IQ`$ +M?0H76M9\H7!H`W$CK*$#01M:AHJA`@$9>H4"`(`*00"HN*%]6!PJB#8/-T(? +M.A#\H64H'2H0V*%[Z*!"$`PJ@.@@*HE2#S>"(SH00*)EJ"$J$""B>ZBA0A`8 +M*I'H)"J*X@LW@B@L*HS:!S>"+SH0`*-EJ"TJ$."B>^BC0A`\*L'H,"J- +MQ@@X*H^>!S>".SH0P*-EJ#DJ$*"C>RBF0A!@*O'H/"J0B@VBH0A"$*B'I2"J33@E0*I4F +M!S>"4SH00*5EJ%$J$""E>ZCF@:9H65WH5"J6/@?BQ`CD`@F.56E!@)7NH:T* +M(A65CJ5P*7!P([2EZ)04&J+X'7\85A&KB%DAPEL:E_ZEN\&-L)=J$'UI&4J7 +M)@EYJ0\T`O$0?BE@ZIC:!C="K2)F,:9EZ&"*)!2F>^A(I$$4$8WI8^J9Q@8W +M@F:*&YE0D>EBFH,"`+R*F'5-=*:?:6O*&MP(J:D&L9J6H:*IHW2:9D$:!#?! +MFKJFO.EI<"/@IDB";EJ&QJ9(PFRZAQ(K8A8YL9OVILRI:+""C$#*:1D*G)X( +MPND>BJR(62S"=0>,T`F6G92ARJD%$IWLHLR)FL0S:*7>JGF(&-X)Y +MJD&@IV7H=:I!@*=[*+0B9KD3Z>EZJI].!C>"?:I!X*=EJ'N*),"G>RBU(F;- +M$_GI?JJ@.@8W@H&J02"H9:A_BB0`J'LHMB)FW1,)ZH*JH28&-X*%JD%@J&6H +M@XHD0*A[J"BD0>P3&>J&JJ(2!C>"B8HDH*AEJ(>*)("H>RBX(F;]$RGJBJJC +M_@4W@HVJ0>"H9:B+>B+`J'LHN2)F#10YZHZJI.H%-X*1JD$@J66HCXHD`*E[ +M*+HB9AT42>J2JJ76!3>"E:I!8*EEJ).*)$"I>RB[(F8M%%GJEJJFP@4W@IFJ +M0:"I9:B7BB2`J7LHO")F/11IZIJJIZX%-X*=JD'@J66HFXHDP*E[*+TB9DT4 +M>>J>JJB:!3>"H:I!(*IEJ)^*)`"J>RB^(F;-"(GJHJJIA@4W@J6J06"J9:BC +MBB1`JGLHOR)F<129ZJ:JJG(%-X*IJD&@JF6HIXHD@*I[*,`B9M4(J>JJJJM> +M!3>"K:I!X*IEJ*N*),"J>RC!(F:1%+GJKJJL2@4W@K&J02"K9:BOBB0`JWLH +MPB)FP0S)ZK*JK38%-X*UJD%@JV6HLXHD0*M[*,,B9K$4V>JVJJXB!3>"N:I! +MH*MEJ+>*)("K>RC$(F;)#.GJNJJO#@4W@KVJ0>"K9:B[BB3`JWLHQ2)FT13Y +MZKZJL/H$-X+!JD$@K&6HOXHD`*Q[*,8B9D6=GJ.[%I8NK!RK5W`C6*P:!,9J +M#]&``$##.@)!K'LHQR)F\10):\?JLM8$-X+*JD&PK&4HR(HDB*R,D<^)58`L +M8M8*T;*^K$`K3'`C\*P:A,]:ALJL2`+-NH>2+&)6!_&S!JU0ZTIP(S"M&H33 +M6H82K4B"T;J'HBQBEL/PM$:M8*M)<"-PK1J$UUJ&4JU(@M6ZA[(L8M;FE+%Z +M8AMKV"JW)@4W`MNJ0;BM(RLL6+(J"2.0V;J'PBQB%O3D@[ZA&O."FQB%32+F!4\#:Z!J.&JN3*LP-,(=+DRKK/AWIJX +M(@F+:]X:36(5.(N8!4-AKIMKZQH4W`BIJP:QNH*N_MW>6KEJ$)^KZ:JSPA.\CVL:R*`LIILW#`"9;*,+%*%5;PM8I:3%\LB";FL+XLB8!5WBYCE;`VSQ.PD>R-$ +MLQK$-)O*'K,:1#+KS.ZQ>XN8]6Y1L]4L('LCA+,:Q#B;RF*S2((V^\UB%7^+ +MF/5PD;/EK!M[(\2S&L0\F\JBLTB".OO.%EPCD,M%S]:S7.R-,+B(60)M*HO/ +M(@GZ[#][N(A9&-<62]`2LS?"0ZM!1+3;ZT&K022T_^SB(F;]70/M1'O#W@@> +MK08!TJ:R%BV2@-'JL5C%XR)F>5XAK4A+PMX(+JT&`=.FLB4MDG#2_K.3BYC5 +M>\6T,NT#>R/TM!K$3YO*UK1(PDW[SUXN8M;V!=0&M?CKC<#4:A!.;2I+U"() +M1NT_N[F(6?G74PO5DJ\WPE:K072UJ>Q4BR14M?_LYR)FD5\2[5<;R`(Y(Q!; +MN[V*M4@"6?O/CBYBUA'FU;JUU>N-@-=J$'IM*JO6:A!R+4O[A8U`/]A>R]<" +MKS?"Z2)F);:I[%^+)`2V_^SJ(F8]86WM8MO%0A4C$&:[O3JV&@1D^\^^+F(6 +M)W;&-K":[4AK,(Q`IJTSN[=:MAJ$9VO8SBYBEBYVVHJPJ:T->R/0MAJ$;>O: +MW@BDK0;1V@JQ&^SM(F:A8IEM;JO:&K<:!'*[O?*V2()O2]RV5UC%[B)F$63) +MK7([T_8-(Q!VN[TRMTB"B.0MQJ$>?O;,0%N9?7O?ZK8#KIA5X+ZW +M^BV2P-\&N(VLV#`"Y66*[8$+MMX(RXN81>&FLL>+@GN:/B]BUEF6W5JX8"U9 +M-@*)N-MKAJM!;+C_[/0B9@%G%2Z)&[3>""ZN!@'CIK(@K@:!XAJVUXN8I9W% +MN#+NRWHC]+@:Q(^;RM:X2,*-^\]N+V(6?0;D!KD=ZXW`Y&H03FXJ2^0B"4;N +M/_N]B%D/VI,+Y2ZL-\*6JT%TN:GLE(LD5+G_[/@B9IUH7NZ7NZ_>"&JN!L'F +MIK)B+I)`YOZSYXN89:&-N&YNZWHCY+D:Q)Z[O<:Y2,*<^\^N+V(6D,;G]KF: +MZXV`Z&H0BN[V"N@B"8*N8?N^B%F!FH'+Z`:O-\*EJT%DNN_MHXLD1+J&[?PB +M9NEI;>ZFJZW>"*:N!H'JIK*>+I(`ZD*XKFSV-`()#E^KJKNDW@CWBYB%ZY:A +MK2Z2\.K^L_N+F,6LI;JZ[JYZ(Q2[&L2QF\KVNAK$K[N'_B](`J^VZ":[%RX` +M0.V>"-;N]LKL(@G.[C\KP(A9#!NRB^VJJC?"N*M!E+NI[+8;`'2[AJT!(V:5 +M;.;NN:NIW@CRK@9![Z:RZBZ2P.[^LPJ,F,6SU;OVKJ)Z(P2\&L3`F\KFNTC" +MOOO/.C!BUM1&\!:\>NJ-`/%J$!)O*HOP(@D*[S\KP8A9:]O$2_&JJ3?"QZM! +MA+RI[,6+)&2\_ZP%(V9M;=?NR!OE8FTC$,R[O9J\2`+*^\]J,&)6ZB;RRKR[ +M+NHV`OF\J:S+JT'8O(:M!R-F`6^:+M`+M=X(2J\&P?2^MSRO!D'T_K,BC)BE +MO?V\3J^.>B-DO1K$UIO*1KU(PM1+Z_ZR)HR81;\UO5VOD`L`I+T:Q-K[WH*] +M2(+8^\^J,&(6!,?VMKTS+]ZK0>B][RWZ@1(V:UL`8!`I>A +M%C"2@`'_LUJ,F-742<`B\%]Z([3`&L0+G,J6P$C"";R'>C%BUD\7\\;`!B]/ +M-P+YP-LK#8PDV,#_K!@C9B%V,#`0/);>"$JP!L$$I[(\L`9!!!NV9HR8Y=DU +MP4[P5'HC9,$:Q!:+)/>"(:P!H$( +MI[)^,.-QFMHQ8I9TIP(61I>(HP)3Z0W +MPBBL093"J>PFC"1TPH:M'R-FN7BF\"D\D-X(LK`&00NGLJHPDL`*_[."C)@E +MY-7"MO`\>B,$PQK$,)S*YL)(PB[\SQHR8A:61PP7P^/HC0`-:Q#2<"J+#",) +MRO`_J\B(65'>-$P-3Z,WPC>L083#J>PUC"1DP_^L(R-F>7F7\#B\H-X([K`& +M`0]OK^8PDH`._[.2C)@5Z,7#\O!^>B/TPQK$/[R]UL-(PCULV%HR8E:N)PX' +MQ+/HC<`0:Q`.<2I+$",)!K%AJ\F(6<_>0PP1CZ(WPD:L073$J>Q$C"14Q/^L +M)R-F(7L>\4<\B=X(*K$&P1*GLB(QDD`2_[.BC)CE[;7$+O$@>B/DQ!K$3IS* +MQL1(PDS\SYHR8M:Z!Q#WQ-CO#3,"*<7;*U",)`C%_ZPJ(V;%?#PQ4PR'W@A6 +ML0:!%:>R2+$&`14;MJZ,F(7T[;U:\3P,`)3%&L19_-YVQ4C"5_S/RC)B5M"7 +M%:?%3.B-0!=K$'9Q*LL6(PEN<>6+5=@R8E;6=Q?CQ3#HC4`8:Q"&<2J[%R,) +M??$_J\N(66_?88P8AZ`WPF2L053&J>QBC"0TQO^L+R-F&7Z6\65<@=X(HK$& +M01JGLIHQDL`9_[/"C)A5_"W%IC$%W"6-0+/Q]IH:(PFK\3]KS(A9OU]I7!NS +MGS?";ZQ!!,>I;&RL0>3&AJTR(V95?\+Q<&Q\W@C.L08!':>RQC&2@!S_L\Z, +MF)7^1QY(W3'&L1WG,I6QTC"=?S/2C-B5O\''H?'H.>-P!YK$.YQ*DL> +M(PGF\3]KS8A9"2!M#!\_P0#`?JQ!],?;ZWR,)-3'_ZPV(V8Q@>_Q?^QWW@@* +ML@;!(*>R`C*20"`;MMZ,F.4%-L@.-@")K$"IR*@LB(PDB\C]KSHA9@N"*S"(CG3?"C:Q!Y,BI[(N,),3( +M_ZPZ(V91@CKRCAQSW@A&L@:!)*>R/C*2`"3_L^Z,F(4(^L=*\B)<"(Y`5_+V +MVB0C"4_R/RO/B%G)8)*<)5N<-\*8K$&4R:ELE:Q!=,F&K3TC9FV#9O*93'#> +M"'*R!D$GI[)J,I+`)O^S^HR8U0[6R7:RO'DC!,H:Q*"_,_Z,V+6 +M/T@H%\KAYHT`*6L0DG(JBR@C"8KR/RO0B%D0X:1,*3^;-\*GK$&$RJGLI8PD +M9,K_K$$C9A&$6/*H;`PGA",0K+R]FLI(`JK\SRHT8A9)&"O+RM4PB30"^RO+(&02P;MA*-F$45-LO.LJ)Y +M(V3+&L2VG,I&RTC"M/S/6C1B5F"(%G?+0NF-@"YK$.KR>PLN(PGB\C^KT8A9 +M>R&WS"Z?F3?"O:Q!Y,NI[+N,),3+@C$`X-&(69*AOKPO6YDWPL&L023,J:R_ +MC"0`S/^L2"-F,8<*\\+\8]X(%K,&@3&GL@XSD@`Q_[,FC9AU'&;,&C.)>2.4 +MS!K$R9S*=LQ(PL?\SZHT8I9VB#*GS!+FC4`S:Q`VR=C.2@#?_LT*-F$4G&LV",SD< +M)8Y`C_-[6S@C"8?S/VO4B%F*(N0<.0^C-\+FK$%TSN]MXZQ!5,X%LU(C9GV* +MGO/G'!$#`*JS!L$ZO[>B,Y)`.A?,3HV8I2D&SJZS8GDCY,X:Q.Z".:S!H$^O[?>,Y(`/O^S7HV8!3&FS^JS +M('HCU,\:Q/W\WK;/2,+[7#"+-6(6R8@_Y\];,0!`0&L0!O1[RS\C"?YSY8M` +MZ[Y(XPC4@Z:R,ZA`4(/NH3Z*F)4U+L\3M/UY(W30&L0'O;WNH&_-:1JEB%EM +MXP$=0C?/`,`*K4&TT.\M"8TDF-"&K9@B9B6.+O0+_8+>"#JT!L%#O[]M%JU!A-$%\Q,Z$*"AVC,; +M/4_>"$&H!C&$8M`XZ!^680PI8A;_>,86H4EH(GV$+M(QBAXM-MX(A+0&84B_ +MMWTTDO!'?[,9AI4B9D&0AS0C[4DKTJ`T;NM(%XPW@B:M07#2[VTDC21,TA+T +M*/V8`@KM0`"@`%`!P@P`E`1``5\`I\`L4`I(0!$``F`(0\`2\$LG`43`$>!+ +M_PIY@A2P*P0!IH(O#05@")7"H<`$@`#/]!-@!1#3=4+W4`5``5``HD`%Q`F6 +M0C<]!20!6$"<,"?XTG8"GJ`G=`]Z`C--!20!0\`4`#=-"E.`+WTH.`$.R1#P +M31,!8<(00$U7`4*`KS`%]-*!@A%@*N5*_]1`=5`M5`_51'51;50? +MU4AU4JU4+]5,=5/M5#_54'54+55/U51U56U57]58=5:M56_57'57[55_U6!U +M6"U6C]5D=5EM5I_5:'5:K5:OU6QU6^U6O]5P=5PM5\_5='5=;5??U7AU7JU7 +M[]5\=5_M5__5@'5@+5@/UH1U86U8']:(=6*M6"_6C'5C[5@_UI!U9"U93]:4 +M=65M65_6F'5FK5EOUIQU9^U9?]:@=6@M6H_6I'5I;5J?UJAU:JU:K]:L=6OM +M6K_6L'5L+5O/UK1U;6U;W]:X=6ZM6^_6O'5O[5O_UL!U<"U<#]?$=7%M7!_7 +MR'5RK5POU\QU<^U6U>G]?H=7JM7J_7['5[[5Z_U_!U?"U?S]?T=7UM7]_7^'5^K5_O +MU_QU?^U?_]<`=H`M8`_8!':!;6`?V`AV@JU@+]@,=H/M8#_8$':$+6%/V!1V +MA6UA7]@8=H:M86_8'':'[6%_V"!VB"UBC]@D=HEM8I_8*':*K6*OV"QVB^UB +4O]@P=HPM8\_8-':-;6/?V#BVW0$` +` +end diff --git a/lib/libarchive/test/test_open_fd.c b/lib/libarchive/test/test_open_fd.c index 0aec1d5..7551dd0 100644 --- a/lib/libarchive/test/test_open_fd.c +++ b/lib/libarchive/test/test_open_fd.c @@ -25,6 +25,13 @@ #include "test.h" __FBSDID("$FreeBSD$"); +#if defined(_WIN32) && !defined(__CYGWIN__) +#define open _open +#if !defined(__BORLANDC__) +#define lseek _lseek +#endif +#define close _close +#endif DEFINE_TEST(test_open_fd) { @@ -33,7 +40,11 @@ DEFINE_TEST(test_open_fd) struct archive *a; int fd; - fd = open("test.tar", O_RDWR | O_CREAT, 0777); +#if defined(__BORLANDC__) + fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY); +#else + fd = open("test.tar", O_RDWR | O_CREAT | O_BINARY, 0777); +#endif assert(fd >= 0); if (fd < 0) return; diff --git a/lib/libarchive/test/test_open_file.c b/lib/libarchive/test/test_open_file.c index e931163..7e6c571 100644 --- a/lib/libarchive/test/test_open_file.c +++ b/lib/libarchive/test/test_open_file.c @@ -32,7 +32,7 @@ DEFINE_TEST(test_open_file) struct archive *a; FILE *f; - f = fopen("test.tar", "w"); + f = fopen("test.tar", "wb"); assert(f != NULL); if (f == NULL) return; @@ -73,7 +73,7 @@ DEFINE_TEST(test_open_file) /* * Now, read the data back. */ - f = fopen("test.tar", "r"); + f = fopen("test.tar", "rb"); assert(f != NULL); if (f == NULL) return; diff --git a/lib/libarchive/test/test_pax_filename_encoding.c b/lib/libarchive/test/test_pax_filename_encoding.c index 45f9848..5affe9f 100644 --- a/lib/libarchive/test/test_pax_filename_encoding.c +++ b/lib/libarchive/test/test_pax_filename_encoding.c @@ -107,9 +107,10 @@ test_pax_filename_encoding_2(void) * de_DE.UTF-8 seems to be commonly supported. */ /* If it doesn't exist, just warn and return. */ - if (NULL == setlocale(LC_ALL, LOCALE_DE)) { + if (LOCALE_UTF8 == NULL + || NULL == setlocale(LC_ALL, LOCALE_UTF8)) { skipping("invalid encoding tests require a suitable locale;" - " %s not available on this system", LOCALE_DE); + " %s not available on this system", LOCALE_UTF8); return; } @@ -151,11 +152,7 @@ test_pax_filename_encoding_2(void) archive_entry_free(entry); assertEqualInt(0, archive_write_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_write_finish(a); -#else assertEqualInt(0, archive_write_finish(a)); -#endif /* * Now read the entries back. @@ -181,11 +178,7 @@ test_pax_filename_encoding_2(void) assertEqualString(longname, archive_entry_pathname(entry)); assertEqualInt(0, archive_read_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_read_finish(a); -#else assertEqualInt(0, archive_read_finish(a)); -#endif } /* @@ -227,6 +220,15 @@ test_pax_filename_encoding_3(void) return; } + /* Skip test if archive_entry_update_pathname_utf8() is broken. */ + /* In particular, this is currently broken on Win32 because + * setlocale() does not set the default encoding for CP_ACP. */ + entry = archive_entry_new(); + if (archive_entry_update_pathname_utf8(entry, badname_utf8)) { + skipping("Cannot test conversion failures."); + return; + } + assert((a = archive_write_new()) != NULL); assertEqualIntA(a, 0, archive_write_set_format_pax(a)); assertEqualIntA(a, 0, archive_write_set_compression_none(a)); @@ -274,11 +276,7 @@ test_pax_filename_encoding_3(void) archive_entry_free(entry); assertEqualInt(0, archive_write_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_write_finish(a); -#else assertEqualInt(0, archive_write_finish(a)); -#endif /* * Now read the entries back. @@ -322,11 +320,7 @@ test_pax_filename_encoding_3(void) assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &entry)); assertEqualInt(0, archive_read_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_read_finish(a); -#else assertEqualInt(0, archive_read_finish(a)); -#endif } DEFINE_TEST(test_pax_filename_encoding) diff --git a/lib/libarchive/test/test_read_compress_program.c b/lib/libarchive/test/test_read_compress_program.c index 042c615..12e6afc 100644 --- a/lib/libarchive/test/test_read_compress_program.c +++ b/lib/libarchive/test/test_read_compress_program.c @@ -37,7 +37,6 @@ DEFINE_TEST(test_read_compress_program) int r; struct archive_entry *ae; struct archive *a; - const char *extprog; /* * First, test handling when a non-existent compression @@ -53,26 +52,23 @@ DEFINE_TEST(test_read_compress_program) assertEqualIntA(a, ARCHIVE_OK, r); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); assertEqualIntA(a, ARCHIVE_FATAL, - archive_read_next_header(a, &ae)); - assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a)); + archive_read_open_memory(a, archive, sizeof(archive))); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); /* * If we have "gzip -d", try using that. */ - if ((extprog = external_gzip_program(1)) == NULL) { - skipping("There is no gzip uncompression " - "program in this platform"); + if (!canGunzip()) { + skipping("Can't run gunzip program on this platform"); return; } assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_none(a)); assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_compression_program(a, extprog)); + archive_read_support_compression_program(a, "gunzip")); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, diff --git a/lib/libarchive/test/test_read_data_large.c b/lib/libarchive/test/test_read_data_large.c index 76b9e12..ecacf65 100644 --- a/lib/libarchive/test/test_read_data_large.c +++ b/lib/libarchive/test/test_read_data_large.c @@ -33,6 +33,11 @@ __FBSDID("$FreeBSD$"); * had a bug relating to this, fixed in Nov 2006). */ +#if defined(_WIN32) && !defined(__CYGWIN__) +#define open _open +#define close _close +#endif + char buff1[11000000]; char buff2[10000000]; char buff3[10000000]; @@ -43,6 +48,7 @@ DEFINE_TEST(test_read_data_large) struct archive *a; char tmpfilename[] = "largefile"; int tmpfilefd; + FILE *f; unsigned int i; size_t used; @@ -96,7 +102,11 @@ DEFINE_TEST(test_read_data_large) assertA(0 == archive_read_support_compression_all(a)); assertA(0 == archive_read_open_memory(a, buff1, sizeof(buff1))); assertA(0 == archive_read_next_header(a, &ae)); - tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT, 0777); +#if defined(__BORLANDC__) + tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY); +#else + tmpfilefd = open(tmpfilename, O_WRONLY | O_CREAT | O_BINARY, 0777); +#endif assert(tmpfilefd != 0); assertEqualIntA(a, 0, archive_read_data_into_fd(a, tmpfilefd)); assert(0 == archive_read_close(a)); @@ -107,11 +117,9 @@ DEFINE_TEST(test_read_data_large) #endif close(tmpfilefd); - tmpfilefd = open(tmpfilename, O_RDONLY); - assert(tmpfilefd != 0); - assertEqualIntA(NULL, sizeof(buff3), read(tmpfilefd, buff3, sizeof(buff3))); - close(tmpfilefd); + f = fopen(tmpfilename, "rb"); + assert(f != NULL); + assertEqualInt(sizeof(buff3), fread(buff3, 1, sizeof(buff3), f)); + fclose(f); assert(0 == memcmp(buff2, buff3, sizeof(buff3))); - - unlink(tmpfilename); } diff --git a/lib/libarchive/test/test_read_disk.c b/lib/libarchive/test/test_read_disk.c index cd87c5b..5666656 100644 --- a/lib/libarchive/test/test_read_disk.c +++ b/lib/libarchive/test/test_read_disk.c @@ -111,8 +111,10 @@ DEFINE_TEST(test_read_disk) if (archive_read_disk_set_standard_lookup(a) != ARCHIVE_OK) { skipping("standard uname/gname lookup"); } else { -#if defined(__CYGWIN__) - skipping("standard uname/gname lookup; typically no user with uid=0 on cygwin platform"); +#if defined(__CYGWIN__) || defined(__HAIKU__) + /* Some platforms don't have predictable names for + * uid=0, so we skip this part of the test. */ + skipping("standard uname/gname lookup"); i = 0; p = zero_groups[0]; /* avoid unused warnings */ #else diff --git a/lib/libarchive/test/test_read_disk_entry_from_file.c b/lib/libarchive/test/test_read_disk_entry_from_file.c index 8b3b6d7..652b5e4 100644 --- a/lib/libarchive/test/test_read_disk_entry_from_file.c +++ b/lib/libarchive/test/test_read_disk_entry_from_file.c @@ -45,7 +45,7 @@ DEFINE_TEST(test_read_disk_entry_from_file) { struct archive *a; struct archive_entry *entry; - int fd; + FILE *f; assert((a = archive_read_disk_new()) != NULL); @@ -57,10 +57,10 @@ DEFINE_TEST(test_read_disk_entry_from_file) assertEqualString(archive_read_disk_gname(a, 0), "FOOGROUP"); /* Create a file on disk. */ - fd = open("foo", O_WRONLY | O_CREAT, 0777); - assert(fd >= 0); - assertEqualInt(4, write(fd, "1234", 4)); - close(fd); + f = fopen("foo", "wb"); + assert(f != NULL); + assertEqualInt(4, fwrite("1234", 1, 4, f)); + fclose(f); /* Use archive_read_disk_entry_from_file to get information about it. */ entry = archive_entry_new(); diff --git a/lib/libarchive/test/test_read_extract.c b/lib/libarchive/test/test_read_extract.c index 887ddfd..10bd014 100644 --- a/lib/libarchive/test/test_read_extract.c +++ b/lib/libarchive/test/test_read_extract.c @@ -32,22 +32,15 @@ DEFINE_TEST(test_read_extract) { struct archive_entry *ae; struct archive *a; -#if !defined(_WIN32) || defined(__CYGWIN__) - struct stat st; -#endif size_t used; - int i; + int i, numEntries = 0; char *buff, *file_buff; -#if !defined(_WIN32) || defined(__CYGWIN__) - int fd; - ssize_t bytes_read; -#endif buff = malloc(BUFF_SIZE); file_buff = malloc(FILE_BUFF_SIZE); /* Force the umask to something predictable. */ - umask(022); + assertUmask(022); /* Create a new archive in memory containing various types of entries. */ assert((a = archive_write_new()) != NULL); @@ -55,12 +48,14 @@ DEFINE_TEST(test_read_extract) assertA(0 == archive_write_set_compression_none(a)); assertA(0 == archive_write_open_memory(a, buff, BUFF_SIZE, &used)); /* A directory to be restored with EXTRACT_PERM. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "dir_0775"); archive_entry_set_mode(ae, S_IFDIR | 0775); assertA(0 == archive_write_header(a, ae)); archive_entry_free(ae); /* A regular file. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "file"); archive_entry_set_mode(ae, S_IFREG | 0755); @@ -71,49 +66,53 @@ DEFINE_TEST(test_read_extract) assertA(FILE_BUFF_SIZE == archive_write_data(a, file_buff, FILE_BUFF_SIZE)); archive_entry_free(ae); /* A directory that should obey umask when restored. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "dir"); archive_entry_set_mode(ae, S_IFDIR | 0777); assertA(0 == archive_write_header(a, ae)); archive_entry_free(ae); /* A file in the directory. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "dir/file"); archive_entry_set_mode(ae, S_IFREG | 0700); assertA(0 == archive_write_header(a, ae)); archive_entry_free(ae); /* A file in a dir that is not already in the archive. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "dir2/file"); archive_entry_set_mode(ae, S_IFREG | 0000); assertA(0 == archive_write_header(a, ae)); archive_entry_free(ae); /* A dir with a trailing /. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "dir3/."); archive_entry_set_mode(ae, S_IFDIR | 0710); assertA(0 == archive_write_header(a, ae)); archive_entry_free(ae); /* Multiple dirs with a single entry. */ + ++numEntries; assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "dir4/a/../b/../c/"); archive_entry_set_mode(ae, S_IFDIR | 0711); assertA(0 == archive_write_header(a, ae)); archive_entry_free(ae); /* A symlink. */ - assert((ae = archive_entry_new()) != NULL); - archive_entry_copy_pathname(ae, "symlink"); - archive_entry_set_mode(ae, S_IFLNK | 0755); - archive_entry_set_symlink(ae, "file"); - assertA(0 == archive_write_header(a, ae)); - archive_entry_free(ae); + if (canSymlink()) { + ++numEntries; + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "symlink"); + archive_entry_set_mode(ae, AE_IFLNK | 0755); + archive_entry_set_symlink(ae, "file"); + assertA(0 == archive_write_header(a, ae)); + archive_entry_free(ae); + } /* Close out the archive. */ assertA(0 == archive_write_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_write_finish(a); -#else assertA(0 == archive_write_finish(a)); -#endif /* Extract the entries to disk. */ assert((a = archive_read_new()) != NULL); @@ -125,75 +124,44 @@ DEFINE_TEST(test_read_extract) assertA(0 == archive_read_next_header(a, &ae)); assertA(0 == archive_read_extract(a, ae, ARCHIVE_EXTRACT_PERM)); /* Rest of entries get restored with no flags. */ - for (i = 0; i < 7; i++) { - failure("Error reading entry %d", i+1); + for (i = 1; i < numEntries; i++) { + failure("Error reading entry %d", i); assertA(0 == archive_read_next_header(a, &ae)); + failure("Failed to extract entry %d: %s", i, + archive_entry_pathname(ae)); assertA(0 == archive_read_extract(a, ae, 0)); } assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae)); assert(0 == archive_read_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_read_finish(a); -#else assert(0 == archive_read_finish(a)); -#endif -#if !defined(_WIN32) || defined(__CYGWIN__) /* Test the entries on disk. */ /* This first entry was extracted with ARCHIVE_EXTRACT_PERM, * so the permissions should have been restored exactly, * including resetting the gid bit on those platforms * where gid is inherited by subdirs. */ - assert(0 == stat("dir_0775", &st)); failure("This was 0775 in archive, and should be 0775 on disk"); - assertEqualInt(st.st_mode, S_IFDIR | 0775); + assertIsDir("dir_0775", 0775); /* Everything else was extracted without ARCHIVE_EXTRACT_PERM, * so there may be some sloppiness about gid bits on directories. */ - assert(0 == stat("file", &st)); - failure("st.st_mode=%o should be %o", st.st_mode, S_IFREG | 0755); - assertEqualInt(st.st_mode, S_IFREG | 0755); - failure("The file extracted to disk is the wrong size."); - assert(st.st_size == FILE_BUFF_SIZE); - fd = open("file", O_RDONLY); - failure("The file on disk could not be opened."); - assert(fd != 0); - bytes_read = read(fd, buff, FILE_BUFF_SIZE); - close(fd); - failure("The file contents read from disk are the wrong size"); - assert(bytes_read == FILE_BUFF_SIZE); - failure("The file contents on disk do not match the file contents that were put into the archive."); - assert(memcmp(buff, file_buff, FILE_BUFF_SIZE) == 0); - assert(0 == stat("dir", &st)); - failure("This was 0777 in archive, but umask should make it 0755"); + assertIsReg("file", 0755); + assertFileSize("file", FILE_BUFF_SIZE); + assertFileContents(file_buff, FILE_BUFF_SIZE, "file"); /* If EXTRACT_PERM wasn't used, be careful to ignore sgid bit * when checking dir modes, as some systems inherit sgid bit * from the parent dir. */ - assertEqualInt(0755, st.st_mode & 0777); - assert(0 == stat("dir/file", &st)); - assert(st.st_mode == (S_IFREG | 0700)); - assert(0 == stat("dir2", &st)); - assertEqualInt(0755, st.st_mode & 0777); - assert(0 == stat("dir2/file", &st)); - assert(st.st_mode == (S_IFREG | 0000)); - assert(0 == stat("dir3", &st)); - assertEqualInt(0710, st.st_mode & 0777); - assert(0 == stat("dir4", &st)); - assertEqualInt(0755, st.st_mode & 0777); - assert(0 == stat("dir4/a", &st)); - assertEqualInt(0755, st.st_mode & 0777); - assert(0 == stat("dir4/b", &st)); - assertEqualInt(0755, st.st_mode & 0777); - assert(0 == stat("dir4/c", &st)); - assertEqualInt(0711, st.st_mode & 0777); - assert(0 == lstat("symlink", &st)); - assert(S_ISLNK(st.st_mode)); -#if HAVE_LCHMOD - /* Systems that lack lchmod() can't set symlink perms, so skip this. */ - assert((st.st_mode & 07777) == 0755); -#endif - assert(0 == stat("symlink", &st)); - assert(st.st_mode == (S_IFREG | 0755)); -#endif + failure("This was 0777 in archive, but umask should make it 0755"); + assertIsDir("dir", 0755); + assertIsReg("dir/file", 0700); + assertIsDir("dir2", 0755); + assertIsReg("dir2/file", 0000); + assertIsDir("dir3", 0710); + assertIsDir("dir4", 0755); + assertIsDir("dir4/a", 0755); + assertIsDir("dir4/b", 0755); + assertIsDir("dir4/c", 0711); + if (canSymlink()) + assertIsSymlink("symlink", "file"); free(buff); free(file_buff); diff --git a/lib/libarchive/test/test_read_format_ar.ar.uu b/lib/libarchive/test/test_read_format_ar.ar.uu new file mode 100644 index 0000000..70507cc --- /dev/null +++ b/lib/libarchive/test/test_read_format_ar.ar.uu @@ -0,0 +1,12 @@ +$FreeBSD$ + +begin 755 test_read_format_ar.ar +M(3QA7ET='1S= 1009000 -/* - * This "archive" is created by "GNU ar". Here we try to verify - * our GNU format handling functionality. - */ -static unsigned char archive[] = { -'!','<','a','r','c','h','>',10,'/','/',' ',' ',' ',' ',' ',' ',' ', -' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -' ',' ',' ',' ',' ','4','0',' ',' ',' ',' ',' ',' ',' ',' ','`',10, -'y','y','y','t','t','t','s','s','s','a','a','a','f','f','f','.','o', -'/',10,'h','h','h','h','j','j','j','j','k','k','k','k','l','l','l', -'l','.','o','/',10,10,'/','0',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -' ',' ',' ',' ','1','1','7','5','4','6','5','6','5','2',' ',' ','1', -'0','0','1',' ',' ','0',' ',' ',' ',' ',' ','1','0','0','6','4','4', -' ',' ','8',' ',' ',' ',' ',' ',' ',' ',' ',' ','`',10,'5','5','6', -'6','7','7','8','8','g','g','h','h','.','o','/',' ',' ',' ',' ',' ', -' ',' ',' ',' ','1','1','7','5','4','6','5','6','6','8',' ',' ','1', -'0','0','1',' ',' ','0',' ',' ',' ',' ',' ','1','0','0','6','4','4', -' ',' ','4',' ',' ',' ',' ',' ',' ',' ',' ',' ','`',10,'3','3','3', -'3','/','1','9',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ', -'1','1','7','5','4','6','5','7','1','3',' ',' ','1','0','0','1',' ', -' ','0',' ',' ',' ',' ',' ','1','0','0','6','4','4',' ',' ','9',' ', -' ',' ',' ',' ',' ',' ',' ',' ','`',10,'9','8','7','6','5','4','3', -'2','1',10}; - -char buff[64]; -#endif DEFINE_TEST(test_read_format_ar) { -#if ARCHIVE_VERSION_NUMBER < 1009000 - skipping("test_read_support_format_ar()"); -#else + char buff[64]; + const char reffile[] = "test_read_format_ar.ar"; struct archive_entry *ae; struct archive *a; + + extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_support_compression_all(a)); assertA(0 == archive_read_support_format_all(a)); - assertA(0 == archive_read_open_memory(a, archive, sizeof(archive))); + assertA(0 == archive_read_open_file(a, reffile, 7)); /* Filename table. */ assertA(0 == archive_read_next_header(a, &ae)); @@ -110,10 +83,5 @@ DEFINE_TEST(test_read_format_ar) /* Test EOF */ assertA(1 == archive_read_next_header(a, &ae)); assert(0 == archive_read_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_read_finish(a); -#else assert(0 == archive_read_finish(a)); -#endif -#endif } diff --git a/lib/libarchive/test/test_read_format_cpio_bin_bz2.c b/lib/libarchive/test/test_read_format_cpio_bin_bz2.c index 90270c8..f7c4efb 100644 --- a/lib/libarchive/test/test_read_format_cpio_bin_bz2.c +++ b/lib/libarchive/test/test_read_format_cpio_bin_bz2.c @@ -36,10 +36,15 @@ DEFINE_TEST(test_read_format_cpio_bin_bz2) { struct archive_entry *ae; struct archive *a; + int r; assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_support_compression_all(a)); + r = archive_read_support_compression_bzip2(a); + if (r != ARCHIVE_OK) { + skipping("bzip2 support unavailable"); + archive_read_close(a); + return; + } assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); diff --git a/lib/libarchive/test/test_read_format_cpio_bin_lzma.c b/lib/libarchive/test/test_read_format_cpio_bin_lzma.c new file mode 100644 index 0000000..26c0440 --- /dev/null +++ b/lib/libarchive/test/test_read_format_cpio_bin_lzma.c @@ -0,0 +1,60 @@ +/*- + * Copyright (c) 2009 Michihiro NAKAJIMA + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +static unsigned char archive[] = { + 93, 0, 0,128, 0,255,255,255,255,255,255,255,255, 0, 99,156, + 62,160, 67,124,230, 93,220,235,118, 29, 75, 27,226,158, 67,149, +151, 96, 22, 54,198,209, 63,104,209,148,249,238, 71,187,201,243, +162, 1, 42, 47, 43,178, 35, 90, 6,156,208, 74,107, 91,229,126, + 5, 85,255,136,255, 64, 0 +}; + +DEFINE_TEST(test_read_format_cpio_bin_lzma) +{ + struct archive_entry *ae; + struct archive *a; + int r; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); + r = archive_read_support_compression_lzma(a); + if (r == ARCHIVE_WARN) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); + return; + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, archive, sizeof(archive))); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_LZMA); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_CPIO_BIN_LE); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); +} + diff --git a/lib/libarchive/test/test_read_format_iso.iso.Z.uu b/lib/libarchive/test/test_read_format_iso.iso.Z.uu new file mode 100644 index 0000000..2f5cbd7 --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso.iso.Z.uu @@ -0,0 +1,26 @@ +$FreeBSD$ + +begin 644 test_read_format_iso.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1G@0#`6!Z-&!``1`XH$((`"``@4I,$%"%0PD`@`7%%2C +MB@*IF,8"!UR``0O@"!#0B0=V:.212":IY)),-NGDDU!&*>645%9IY952-K%$ +M$E,\8<04('#Y!`@YV&`##"\@\24(1B3!1!%39#$%%45H*$05;A)1A!0@F`#" +MA44,\804#PK8@A0O$&%%H5(4$005@X*`PA`I@!!##CG,`$(1+F3Q1!5.'$%$ +M$&]*2JFEF-X`@A(N0.&H%%TZ\0*K4PR!A)M,)!$JEKSVRJL,!-800PPPW"## +M##+04,,-!((#+`S"$FLLLLHR"P,X!&:K[;8$`O!LM,4>F^RRS1;IZ[GHIJON +MNNRVZ^Z[\,8K+Y/_U;O8/P(2:*"]_/;K[[\`!UR=EDF`T,0;;H#@Q!MV0*CJ +ML3HDJ\.R('RK0!MKI#''&V;,4;$+,+B@:0MO@$!'&7/0T8*"89#QA1EOR-%& +M&'2XH'')80BL\\X\]^SSSV<=6..00!=M]-%()ZWTTDPW[?334$?=&XD!U4BU +MU%AGK?767'?M]==@ARWVV%K/./1`-PZD(X\^`BEDB4,>:+:-`.`8T-H]_A@D +MT26:2/;?@`N^>:<=^[Y +MYZ"'+OKHI)=N^NFHIZ[ZZJRW[OKKL,O_/+,-^_\\]!'+_WTU%=O_?789Z_]]MQW[_WWX(BGK_[Z[+?O_OOPQR___/37;__]^.>O__[\]^___P`,H``'2,`"&O"`]`,` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_gz.c b/lib/libarchive/test/test_read_format_iso_gz.c index 73c8415..2289379 100644 --- a/lib/libarchive/test/test_read_format_iso_gz.c +++ b/lib/libarchive/test/test_read_format_iso_gz.c @@ -29,20 +29,13 @@ DEFINE_TEST(test_read_format_iso_gz) { struct archive_entry *ae; struct archive *a; - int r; - const char *name = "test_read_format_iso_gz.iso.gz"; + const char *name = "test_read_format_iso.iso.Z"; extract_reference_file(name); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); - r = archive_read_support_compression_gzip(a); - if (r == ARCHIVE_WARN) { - skipping("gzip reading not fully supported on this platform"); - assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); - return; - } assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, @@ -50,7 +43,7 @@ DEFINE_TEST(test_read_format_iso_gz) assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt(archive_compression(a), - ARCHIVE_COMPRESSION_GZIP); + ARCHIVE_COMPRESSION_COMPRESS); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); diff --git a/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu new file mode 100644 index 0000000..b6ac252 --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_joliet.iso.Z.uu @@ -0,0 +1,66 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_joliet.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$PDX4056(#@X(,01BBA +MA`)*\403$V:HX8,'X5*0AQX="$``(AZ(``(`6%"0!10DI*)`(@#`04$SHB@0 +MBD8$(,"!`1`@0$`E'KCAD$06:>212":IY)),-NGDDU!&*>645#YY1!%.)#'% +M$TDT$<25(&CY!`@YV&`##"\@8<04(!B1!!-%3)'%%%04@>$04A01!!5/2`$" +M"D.D`$(,.>0P`PA%N)#%$U4X<0010<#Y9Z"#%GI#"S(0:`,(2K@`A9Y2;.G$ +M"YU.,002;R;HZ*2"9@J##9@2>`,(%2Z1!!4@U!D$AE7VZJN3KN8`0Z8TR!!# +M#3+,0`.!!`0[+`S%'IOLLC`00."UV&9+(`#.$FLLLLHR*^2OY)9K[KGHIJON +MNNRVZ^Z[2?XG[V(""$B@@0$Q`4`2`#@!0!4`8`$`"`,73/#!!B=,\!``$`&` +M%``\`4`3"E>,\,4=?EC""T5P%"20`)P(``8%84`R0AH,%*,'!;%L8T`XZLBC +MCR"/*"+&.%NL<\X\[^QSST#_+'301`]M=-%('ZUTTDPO[7334#\M-<9'`-"Q +MO_Q.$?&^$P,0!`!5=TQPUEL3G`,`-J`-``P`?`$`$@`8`8#6!,O-K[X=:YW% +MW`!08777"S_\]]=^2PPQP2@`P'`*!<<`P-EGSU!PQRX`L+?$`/M;M<-?XSVU +MT9\7';K0W4+[[;3,EAXMN-1:J^WKVZI^>KC5C@OO[;CGKOONO/?N^^]'SBO\ +M8?_86Z"(PR>O_/+,-^_\\]!'+_WTU%=O?50'SE@S``,`T(%`!Q*1!,37EV_^ +M^>BGK_[Z[+?O_OOPQT\8\C*.&%#W`GT?@/CDR^___P`,H``'2,`"&O"`"$Q@ +M>P[$LNT9```?`%]`R`"`-`!`#@K,H`8WR,$.>O"#(`RA"$=(PJ'0CV4B>J!` +M(G@@"EH0@R6,H0QG2,,:VO"&.,RA#G<('D34CR`U&DC,=C0BFMG/9G.#P@$" +MX(MW/$P*!0A`(*"`!1($H!U?$T@0VH&_@0R`?D#Z$4$$0`4C:"``#L@1$7ND +MQIFU00`$J``-1$"`(12!`P$@&$'T6)!V]-$,/QQ($&\4-YD548Q!"H`4H"A% +M*EH1BP/98A<%\L6"Z*@@9#0C&MM81$[VZ(UQG",!```'[Q7D>R\+62'7:,02 +M#8!_BXQB(IS0!`2T,`UR<.05LQB0+8IQ($0DR"7'6,8SIM&0;$0F`4`I1SH" +M@`\`"$%!0J#"@1@@1Y6$HP1'M``D!$$*1%#5$ERP@QC$,@"S;$(##H2&,,B! +M#&Q(@QO6H$M2!&(@@2#%+P42S($,$YC%W&0`LDD`;!X(CLP4I26B.L_^"+H$<5EG<6O=`"0N@@2)8"J'^%F*/M"%%^060PE"S8)`E*#;#``$`(`& +M`(0AO11D0P4!X`8`K`$`7ECO0-I+D/=*-+X\`(!^W\!?`)P!`"T`@!H`P&#] +M6K`,`*`#A&6[7_UB.,+]O6\;`(#ARFD8PWC(,(V2NTOD*EOY +MREB67A&DT(X`*(`*A]AM$J#P!4+E(`9[0D(10&"A(2R!S4D@`I@45"J9"$(4P!"G`*PA36[&^F0406&&C56C" +MFI5M*FE#@4^S=G2I3YWJ9]/:2YR^:.6RS.YVN_O=2D%#&=A@4@7`^][XSK>^ +M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W +MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT +M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +(&(_R.(_T:!4` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu new file mode 100644 index 0000000..9babf69 --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_joliet_long.iso.Z.uu @@ -0,0 +1,71 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_joliet_long.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GA0+@6!Z-&!``1`XH$((`"`!@5I0$%"%@PD`@`<%%2C +MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ +M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A +M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ +MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<1`(`XPX!!# +M##7D0"`)O\(0[+#%'IOLL@16:^VU!`+0[+/%1HNLLC"00&2OY)9K[KGHIJON +MNNRVZ^Z[2_XG[V(""$B@@0$9`8`<`)31+P!"`#`%`$0``(+!"!^L<,((#T$P +M`%(`\`0`33"\\,46(VR0B`/E4L(+17`TI)``I`@`.`6!@T%"+`HTXP<%P8QC +M0#KRZ&,`0))<(HD8]YRQST#_+'301`]M=-%('ZUTTDPO[7334#\M==143VUU +MU557O`0`20@L,8)>']SUP!,?G`,`-J`-``P`?`$`$F`/?+"^73,!0,@#9^$U +M%7=3C'#`57`-@-T%AQSQP28T_'#$(3L\<<0%'^QPP2U`W/;#5CPLN>4A!W&U +MU)\W';K3VPK;K;'?+ELZM*A/&RZVL%>K+;"F$]LZN.(:#._NO/?N^^_`!R_\ +M\$K.:_QA_]A;((G'-^_\\]!'+WUQ628!`A5HU`'"$V/0`2$.(!2KP[$Z)`O" +MM@K(X$*!Z\<0A@V9MJ`$""VH\08;:91!1PMLO.'&&?2K0QK(4"GZG6&`YP.! +M"Q;X@C3,X0W3BZ`$)TC!"EK0*;B8P8%JI+.2`<`#`CE0#&0P`QK4P`8WP,$% +M5\C"%KKPA3",H0QG2,,:VO"&CF$>C4I$LX&`,``C+.$)4XC#(AKQB$A,HA*7 +MR,0F.O&)4+S/@6#606=HC(<`B(&V`#`#`-```#50VPT`H,*SL4V+,N"B%\$H +M1C("P(Q9W&(7OQC&M(VQC&N+8QKGR$8[NA&.:%0C'=N(QS/*<8UU!,`=WYC' +M0/(QD8L$Y"$'Z<="ZE&0?53D'QLYR4Q&,H]D`$`:]A7%4IKRE*A,I2I7R%[4@SE"D,WLJ3,3!4`*`1UH00^:T($PU*$$@6A!>%20BMHHHQOM +MZ$Y!*E($D-2D5;TJ`'#QP8*`<&8>].C-M=\RK$M/)UKG@MD%[]*MB^TK6P@/WK7A&[6#*D00XJ96D' +M"C)9@^B+(/K2!0!F1!`1&*`@!A#KCT(HI`78-:TNV$$,UAJ`MKXUKH8-[&D/ +M.UO9#I:VM[5M;!5+V-KR%K>[+6QD`U#9@73@L@,Q`G(%HB]";+8@G@6M:'%& +MVA(M``E!&!2NG+"$U*XVJ*YMP('0$`8YD`%_;EC#4`-`BD`,)!"DF*A`!!#1 +M$LDW(`+@K(R@RM'IDL"_)[5J2=M)X`*+<[U%76@[[@L`^BZ5P0(`(4$\P%^I +M?O2_4\4J2DFPWO:^-[Y-K2]3"9)?Z%;8OP#.ZH`-S.(6N_C%\JJIA'V(TQ[Z +M]YXC8RU!#8I0A0:$H1`6,81G+!`*:[2_&0[P594\X)I:5"#RS.F->VHB'2/8 +MQP`XZD.%W-0G!P2C1[;P6)FL80&3`,9H3K.:UYR9E\6LQF'-,(Z%="`W$T1F +M\]3IA>>\LP#`X[F=_2Q!0IOAZ@;`BMNL)C2I.4QM1O.8S!2F-(.I3$A/4]*6 +MIC0VNWE-;EHST8V.=*6S*6H`_/E@!#D86.DY5CX?NM.*=C2C)PWK4%]ZU)P& +M-:UUG>E:[_K1I+[UIC\-;$Y_DY1IU*_+!#T00E_8T!```!H`$`92AI(-H@1` +M3=?`YFY[^]M!"("YFI,4:A4$4!T<"AAZ5*"8 +M``*,/\$*#7\3"*90!2A`05!46!.D3CZ%)&!A36TZ.)SD1*>1TZGB5$C"$*8` +M!3<%80H'#Y03J!"$(:2<"%L:0L>K(`1<3<'@>S("I'@.J"2P:0B.2L(3G#!R +M3TU\4Q`"^L69[G2H@RE/0[=Z$O0$)JYC/`E-R&X60&"%)S"A"DTX>)YH]6\H +M/"KJD!(ZT8W>=JE+(>XYW[H+[,WXQCO^\4%!0QG8T#\%0/[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT +M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. +M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L +MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* +MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H +MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& +4>9B(F9B*N9B,V9B.^9B0&9F2J90` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu new file mode 100644 index 0000000..fdccb0c --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_joliet_rockridge.iso.Z.uu @@ -0,0 +1,68 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_joliet_rockridge.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1G@0+@6!Z-&!``1`XH$((`"`!0590$%"+`HD`@`<%%2C +MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ +M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A +M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ +MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<1`(`XQU""# +M##340"`)O\(0[+#%'IOLL@16:^VU!`+0[+,P$&LLLLK"0`*1O99K[KGHIJON +MNNRVZ^Z[\"[YW[R+"2`@@08&9`0`<@!0AK\`"`'`%``0`0`(!R>,\,(*)SQ$ +MP0!(`<`3`#31,,,87YRP02(.A$L)+Q3!T9!"`I`B`!@4A$'*"&DPT(P>%!0S +MC@'IR*./`0!927BQP$ +MUE.#[K3H3V\K;+?1@KNLZ=!^.ZVXV,9>K;;`GNZMM.&.>W"\O/?N^^_`!R_\ +M\,0K2>_QA_US;X$D(N_\\]!'+_WTQ669!`A4H%$'"$^,00>$.%1:@P['ZI`L +M"-LJ((,+!;(?0Q@V9-J"$B"T4$<:9%1:_QGXHP^""P!\01KF\`;J&?"`"$R@ +M`A>X%5QHX$`UVAD`!@"`#@CD0$1(@L08R,$.>O"#(`RA"$=(PA*:\(0HE$SS +M:%2B@%!0(!8,0`8WF,(:VO"&.,RA#G?(PQ[Z\(=`U,^!8B9!`P#@`Q<,"!D` +MD`9^!?&)4(RB%*=(Q2I:\8I8S*(6H;+"F)'(B`)!XH&6V,1^;?&,:$RC&M?( +MQC:Z\8UPC"-[(,%"@MQH(#;KT8^"U$*>#0P*!PB`+]X1,2D4(`"!@`(66!"` +M=GQ.($%HQPL',H`5"HF/`Q%`!`?"`2H8X8$.V)$><]8&!2#@`19H`0E*>!``!!&$%H6I!VW=$,=.6DR/"+H9GO1)4(H29ZLT)2I5R*A@02Q(LUY>,YA]#,``9EC,0R;" +M"4U`P!C3(`=D-O*1`8DD)@4B`$N6:)\!$8`%"=*!:@8@E,#,V3E)J4U7`H`0 +M``A!04(`QH$88*'?%.8"D!"$0>'*"4MPP0YBT,X`O+,)#3@0&L(@!S*P(0UN +M6(,]21&(@02"%``%0#^AF5,!2)0@(3`H0D=)`HQVTY6>B.A$*RJ0BR8TH^ET +M`!.>`*HO*.$)3'#!G+`PTD*Z$YXC.!`;WN"&,[1`#6]X:1GHT`(SI($-96B! +M&\+0AC*X@`YEP`,=W`K7F=94(#?MJ3^C21"?3E2HJ0U6)"@#`XQ^0C2P\ +M#H+1))9(`7!JPD=#VM62-@*>##C0'/+0AI?&U)[M",5`0M&.P0ZVIX^-+&3A +M,04FE(!$'AAK6<^:UC2LM:UOC>M2A.[,$PN48_*S<5^4Y>;%,@=<_1+ +MHG972";Z+FKQ"0!F%N29!"%L)N,;D$Y^\J"*C2YTO5G=!COXP1!N#8!YHP06:VW:?>EV6N]S$+[/-L;*=+66?6F,'`&`. +M`,@#`,A\92`#0,@1#K2@!TWHHPJ"`%74TCUGHP`J6\#*@EL&H*C +MDD!58WO*UIN"T+AU[6YXRQM,>3(WOI.@)S`Y`=BB;D)'LP`"*V"U"DU0=9YH +M)6HH/&K>D"KWN=/M<'I+0>+I8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT +M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. +M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L +.V9(N^9(P&9,R.9,T^8(` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_multi_extent.c b/lib/libarchive/test/test_read_format_iso_multi_extent.c new file mode 100644 index 0000000..9697a4b --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_multi_extent.c @@ -0,0 +1,94 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2009 Michihiro NAKAJIMA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_read_format_iso_multi_extent) +{ + const char *refname = "test_read_format_iso_multi_extent.iso.Z"; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + int i; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Retrieve each of the 2 files on the ISO image and + * verify that each one is what we expect. */ + for (i = 0; i < 2; ++i) { + assertEqualInt(0, archive_read_next_header(a, &ae)); + + if (strcmp(".", archive_entry_pathname(ae)) == 0) { + /* '.' root directory. */ + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString("file", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(262280, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "head--head--head", 16); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else { + failure("Saw a file that shouldn't have been there"); + assertEqualString(archive_entry_pathname(ae), ""); + } + } + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + + diff --git a/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu new file mode 100644 index 0000000..3ce33dc --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_multi_extent.iso.Z.uu @@ -0,0 +1,67 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_multi_extent.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GB0#0<*%(`-'X48@(D`((````H4I``%"5DPD`@`<%"0 +MC2L*M*(1`0B0```!D"!`0"8>V.&12":IY)),-NGDDU!&*>645%9IY9583LE$ +M$D($(<402"1A11$@)#'%$R#D8(,-,(!@1!),%#%%%E-0482&5TB1A)U29.GG +MGX`&*FB2,A"80PP%WD!@#&PJ"@,)A<)P:**+-DH@"01FJNFF!`(0Z:0Q.,HH +M#(Z28.2@J*:JZJJLMNKJJ[#&*FN5_]6ZF``"+AJB$0#(`4`9OP(@!`!3`$`$ +M`"`@JVRRS"ZK[!#&`B`%`$\`T(2SS6:+K;(&@3C0B"6\4`1'11*9XHHM$J0` +M!@EI,",`'104;XX![=CCCT$."221(6KK[[;_!@SPP`(73/#!!B>,\,(*-\SP +MPPY'#/'$$E=,\<466\P$`$D("T`0T@(`+1(<`V`%`.,FVW&QU2:;`P`DD@B# +MLKQVO/&XQ69!+`!4H&RMLE>$W''/XTZ;,<9('ZUMT@\SK?"GB(9:*:F70DUI +M@98^RNG6F7IJ:-2B9FTJLK.6;?;9:*>M]MILIVWKVX?]DVN!(<)M]]UXYZWW +MWL4EX801:$X1!AT@/#$&X:&"0*`.C.I`*@B?*L!&&F*$(<<8:*1A1QF0NW"# +M"SD0&`8(:O_/+,-^_\\]"#5G>-^T9O_?789Z_]]MQW[_WWX(>O]X'Q#B_^ +M^>BGK_[Z[+?O_OOPQR__5]/'._W\^.>O__[\]^___P`,H`#S`PGJ$01'`[&7 +MCX`DI.&=B%A0.$``?/$.:4FA``$(!!2PP((`M`%D`@E"&_0U$`'<#T@D%(@` +MA#<0#E#!"!H(@`-XM,`@T1!?)&B#`B(```@<@`1#*`('`N"!@A31(.TH2#O< +M8,`6IBB!"+H7`_55I`!(X8(9W&`'/S@0$:8P("8L2(\*LL(;O3"&,Y2B#=68 +MPQWV\(<`X`,`/E`0.N+#1/B(8@U)``@''N!-<7+!#F)P10PFP@E-2,"!S)"& +MU&DQ2($82"#&1I`'5O*+`!``'0GR@3/*\(8,!&60=,A#'Y)`CEXH2"KO2*0\ +MBI*/?@1D$01)2"P>,I&+;&09'DF"2`IDDB>TY+> +M$@"=*$@G$`&!@4``$:\4$9'^"*=9#K*0`;BE(@'`2$=R$)*2I.2W@DG,:!*D +M$\E\)3/=:,H!VO.>^'P+C,(0GL`$KV+("DD@@IQ`,(4J0`$*3Y`" +M%=P45Z\^80I)P(*;NLE6.ME)0U.XTU:ID(0A3`$*<0I"8$$P5B=0(0A#F"L1 +MS#0$KU9!"%N:@E/[!+@^';8(0TC"FX;`U"0\P0EL?4(5OC1+"`663%"X;&8W +M6R:U.E:T2?!IF5#[U20TP4M9`($5R%J%)I!)K5,8@E'#RMFZ-O:QD=UM9W]+ +MV-.Z@*?8S:YVM]L7-)0A#&1H00N\"U[QDC>\X_TN>L]K7O6&X;WPC:]\YTO? +M^7+WOOC-KW[WR]_^^O>_``ZP@`=,X`(;^,`(3K""%\S@!COXP1".L(0G3.$* +M6_C"&,ZPAC?,X0Y[^,,@#K&(1TSB$IOXQ"A.L8I7S.(6N_C%,(ZQC&=,XQK; +M^,8XSK&.=\SC'OOXQT`.LI"'3.0B&_G(2$ZRDI?,Y"8[^_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 +MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. +MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV +MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ +M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W +MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/?FOJ2_SBTY<.86BD>)&O_!8PGPW+3S[TG2_]Z#=2^-C/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT +M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. +0^9`0&9$2.9$469$6>9%O"``` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu new file mode 100644 index 0000000..218631c --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_rockridge.iso.Z.uu @@ -0,0 +1,206 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_rockridge.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GA0#Q@,A$$/'QT(0``F'H@``@!84)`%$R14P4`B`'!! +M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$ +M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`" +M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$ +M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"8`PPYR'`# +MIC'4,$.P,)#`[+#%'IM#LLL22`*!V&:K+8$`/$NLL<@JRRP)1OYJ[KGHIJON +MNNRVZ^Z[\,;;Y'_T+O:/@`0:6.^^_/;K[[\`5[=E$B!,48<;!9-B(TX`J!C0#SZ"&0`0NY\XH%30'%` +M`+Z\`X`44A000"!08$%N.T$,%$0[5P\TP-0"^5B0`%08H4$`#O3X8Y!M)+#! +M!`^`0$+GGX=.PA!%2)1*((N."$&QX` +MXHHS7M#C!4E.$.668Z[YW*-[#KKHI$]/`@!P^%Q0B&^[C:#<0>Z>X@!;_QY` +M(DXT@<"!9*0A1^&')R[0XKL/)`#D1-8O$/.79PX^W<_CG/1,!P`Z`$`#!=$` +M%<+`BX#P(@R5^]_U[!:``[@)3B[800S,A[XF).!`9D@#&\H`OP"0(A`#"00I +M]!>0^R6/A0#@G_,D&$"Z5<]T?#A@`A?80``\,(*YFR#O3K0`)`2A4+IRPA(R +MN,'`G2]]#3@0&L(@!S*P(0UN6$,)3YC"%4X.?R>"H0S]%\0:1J]THC,$`$ZA +M,ZJ=XB!FC!R1%""G)B1QB1K\FQ,;D3X&'&@.>6C#%;-8PG:$8B"A:`<84?3" +MR4V!"0LP$0%".,+*]:]'`P"2`$B`24V>T7IK8^-`+O!&@]Q0='(D8AWO*`,F +MFH^/38@B```I2"RN00:%/*1`$KG(18KQD7[T'@`&0(X3B'P,YR#7,()>(5&3R?.E()CA` +M10$AIC$)``!D.D"9^!R@Z!CQS%%*DR#*3&4`MID%.W:3!N`4'"QE20Z#G,8AZS>??4YS*I)U)']%,@I(2C!`5*4(,JL08) +M#`&8'3:KAU7MFY.O= +M`F"^X,6O>(WC65D-"U(S)I:``(3JM`$V^[)5JZ%0J3Z*ZGWQG>^&?:O%#I\W@.[ +MP+0XSK&.=QPS-)2!#6QX@P)X3.0B&_G(2$ZRDI?,Y"8[^_G+8`ZSF,=,YC*;^,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 +MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. +MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV +MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ +M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W +MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT +M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. +M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L +MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* +MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H +MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& +M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F^9F@&9JB.9JD +M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S" +M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W^9W@ +M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^ +M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$< +MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z +MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58 +MFJ5:NJ5^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V +M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4 +M6JF6>JF8FJF:NJF^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR +M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0 +M&JW2.JW46JW6>JW8FJW:NJW^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N +M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`, +MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$^[$@&[(B.[(D6[(F>[(HF[(J +MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1( +MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5^[5@&[9B.[9D6[9F +M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$ +M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F^[F@&[JB +M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O` +M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W +M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\ +MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$: +MO,$_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X +MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56 +M?,58G,5:O,5_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T +M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2 +M/,F47,F6?,F8G,F:O,F_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP +M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S. +M_,S0',W2/,W47,W6?,W8G,W:O,W_,W@',[B/,[D7,[F?,[HG,[JO,[L +MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`* +MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$_=$@'=(B/=(D7=(F?=(H +MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1& +M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5_=5@'=9B/=9D +M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B" +M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F_=F@ +M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^ +M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W< +MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z +MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8 +MGN$:ON$_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V +M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54 +M7N56?N58GN5:ON5_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R +M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0 +M'NF2/NF47NF6?NF8GNF:ONF_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN +M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS, +MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW_NW@'N[B/N[D7N[F?N[HGN[J +MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`( +MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$__$@'_(B/_(D7_(F +M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$ +M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5__5@'_9B +M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>` +M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F +M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\ +MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W: +MO_W__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X +MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@! +M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P +M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27( +M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R# +M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)! +M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\ +MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K" +M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U +MO(;8,!MJPVW(#;NA-_R&X#`3R/Z#$]JL?U +MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\ +MD`@R02K(!Z2/ +M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ +MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2 +M2LI)22DKI:6\E)@R4VK*3RLMY22_KI;V\E_@R7^K+?Z?O_)W`,W@* +MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG +M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4AZI/_:E`-:@*U:%*5(NJ +M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L +MBM6Q2E;+JED]JV@UK:K5M#6OZM6]RE?[ +MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U +MLVK6SRZMY/:_H-;VJU_7* +M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_ZVO_;7`-M@*VV%+;(NML3VVR#;9 +M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;`NOX3V\B#?Q*M[% +MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D] +MO:@W]:K>UVNO[;V]N#?WZM[=RWM[K^_]O<`W^`K? +MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2; +ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X +M#:OA-#@/Z^$]S(?[L!_^PX`X$`OB04R( +M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GC0+06!Z-&!``1`XH$((`"`!059,$%"%0PD`@`7%%2C +MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ +M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A +M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ +MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<10H`PQR%## +MKV;"0,*O,`0[;+''PI`L"016:^VU!`+`K+/%0HLL@200V>NXY)9K[KGHIJON +MNNRVZ^Z2_\6[V#\"$FB@O/CFJ^^^_/9;799)@-#$&VZ`\,08=%0J@\(Z'*N# +MM"!LJX`,+A18<0QAV)"IH2"T4$<:9%3:\1D@1PR""RB_D,8<;_CK\LLPQRSS +MS&G=0L^!-0HIT```9"#0@40D(07-1!=M]-%()ZWTTDPW[?334+]&8D`UDLBS +M0#X'$/3047?M]==@ARWVV&27;?;9:"<-"8TV`H!C0#KRZ&,`0.I,&VP3=.%#EQSHAT0^3IKJL!'X2\"!YI"'-L3`CH@+Q4!"T0X_ +MFJ@@/"J(`"(Y24G"8PI,$(.)`K`%*_KREV'`(@3I41!Z=*$@77CD.VHI2;\9 +MY)+KTV06FD"Q^=4/E$T0)0!(V089H+(=JA0(*UWI2D`"0`#+9.8[<*E+$_42 +MF/"4HC`)@L/(!<\+!?'"(]W!S'^XPY)IQ*0TFS`#3PH.F]KDY@R^&!``40E*0(QD$"0@IRP +M-*<`P$>0#1B2>KTC@2*UISK\+0"E_U,I2P7B4I@2)):4NR!!.G!31>Z4D:8# +M`/X4`-3^";6E+X5H3&4)1()\H*EI?&KJ3(?+(9"(!QJ5(5@'X",!+'*L;]T> +M`'!)!!+U(*UJU=PA`\#6<\95=3PEJYM(Y`.\YG5Z.^JK6P/[UZB2]+&0C:QD +M$W*[00ZDC+M#8TY_)Z0#U8]X=SQ>0!@GTXA2SK)8`VM.&*B1A"'ES4Q"FP-U` +M.8$*01B"?X-&*_E600BXFL)V]V0$2.4-4$E@TQ`+ISB).@)3"]N;Q*:$`0I9`$$5G@"$ZK0!.[FB592J.ZC2`PI"V-8 +MPT`NL12([&`7NZ"Y8`ZSF,>L'S24@0UL>$.E:C`#!9#YS7".LYSG3.,[S>\R,9C7'X%ANUK.@!TWH0AOZT(A.M*(7S6BO\#G-:XY!H!M-Z4I;^M*8 +MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. +MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV +MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ +M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W +MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +(>(F8F(F:^!,` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu new file mode 100644 index 0000000..dd013ff --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_rockridge_new.iso.Z.uu @@ -0,0 +1,208 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_rockridge_new.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GA0#Q@,A$$/'QT(0``F'H@``@!84)`%$R14P4`B`'!! +M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$ +M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`" +M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$ +M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"8`PPYR'"# +M##/$,,.R!)(0++'$&HNLLLS"0`*!V&:K+8$`/#MLL<M]MI,0V(CC@#H&!"//@(9@)`^GWC@ +M%%`<$(`O[P`@A10%!!`(%%BP$$`[00P41#M:#S2`U0+Y6)``/0]T`15&:!"` +M`SW^&&0;"6QP00,AD$"ZZ:B3,$01'`2004&S&]1.0>VX\39!.0Y$M^AW#WDB +MD2@.7OCAB2_>N$"/1_XSY40*/Q#F.'+N.>AUCU[ZZ:FOSCT)`.`1=$$ARATW +M@MD'GW<``WAM?`").-$$`@>2D88B1:`A"`42E=.6`()34@X^,FO`0="0QCD0`8VI,$-:X"A#&EH +MP\L%<(?3\^%`@'@](C+0@T9,G2,``(]_^/&/\#B('2M')`7(J0E8U&()!=?% +M1LB/`0>:0Q[:8$8TPK`=H1A(*-KQQC?>4`!]_*,?X3$%)BS`1`1@H0L1B+T! +M`$D`=W0E#E6WO=9)`@#O$*4?`V<0(X(@BBE:P"$3B;$2OL^130`C`"1)R3.N +M00:7S*1`-ME)'7XRE[I\1RD=H**`#(`.;8!#0%B91UH^T)S?HP0`W*'+?[CC +M(*3#@`,*<`)@$DF864#DKI8P@RT>\XN1G&0EUS"#:&J2DSKTY.78J4MWE!(" +MW03`-\-)`(&0LY;=PR@Z6V<)`+2CG;?K92U_2<@I#G.?-/!G(P&Z3($ZDP8& +MG29""8(B:U[NH[IL1RDE<*"*#JFB$@6G.`%PT7.6LYP=94<[V2%(#Y8T`/C4 +M9Q9KH-+"(5.9S!QH#6(:$&HFU*8\5*HNV5'*"!SHAJEL81E8V2-9PK*MK]PH +M!#NZCG:N`YX)D"<][6G2?";2!E4-P%4#VDPTVH"K`/`J317*P[KJA$ +MAPI4H@;1`4?5:#G9AA[=&7!KY]L1^J`HO"(Q\GB77%Y`'O=)QD[OLP'!`%OQ +MJ%F-`D!WF1-([T1KQ](2+P#O0Y[^5`N`YA5DHVA$^<5``5#@%<*20!"E_`5`YB`"DD%`$$&!K"$M";!"(>5$YWL9#`[ +MU9<*21@"W^`4A"F<=U!.H$(0AH!@HMFJOU40@JZF8-X^&4%2?!-4$MPT!$@E +MX0E.,!BHYMLI"'GXOBE><8O%M*<0SS@)?!)3CO&;A"98,0L@L,(3F%"%)IQW +M3[;R+A0BY6))@5C$)%;RBZ7@9`SCV`763;.:U\SFFZ&A#&Q@PQL4T.8ZV_G. +M>,ZSGO?,YS[[^<^`#K2@!TWH0AOZT(A.M*(7S>A&._K1D(ZTI"=-Z4I;^M*8 +MSK2F-\WI3GOZTZ`.M:A'3>I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. +MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV +MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ +M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W +MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +M>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN(JLV(JN^(JP&(NR.(NT +M6(NV>(NXF(NZN(N\V(N^^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. +M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L +MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* +MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H +MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& +M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F^9F@&9JB.9JD +M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S" +M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W^9W@ +M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^ +M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$< +MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z +MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58 +MFJ5:NJ5^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V +M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4 +M6JF6>JF8FJF:NJF^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR +M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0 +M&JW2.JW46JW6>JW8FJW:NJW^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N +M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`, +MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$^[$@&[(B.[(D6[(F>[(HF[(J +MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1( +MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5^[5@&[9B.[9D6[9F +M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$ +M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F^[F@&[JB +M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O` +M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W +M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\ +MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$: +MO,$_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X +MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56 +M?,58G,5:O,5_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T +M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2 +M/,F47,F6?,F8G,F:O,F_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP +M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S. +M_,S0',W2/,W47,W6?,W8G,W:O,W_,W@',[B/,[D7,[F?,[HG,[JO,[L +MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`* +MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$_=$@'=(B/=(D7=(F?=(H +MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1& +M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5_=5@'=9B/=9D +M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B" +M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F_=F@ +M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^ +M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W< +MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z +MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8 +MGN$:ON$_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V +M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54 +M7N56?N58GN5:ON5_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R +M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0 +M'NF2/NF47NF6?NF8GNF:ONF_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN +M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS, +MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW_NW@'N[B/N[D7N[F?N[HGN[J +MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`( +MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$__$@'_(B/_(D7_(F +M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$ +M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5__5@'_9B +M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>` +M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F +M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\ +MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W: +MO_W__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X +MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@! +M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P +M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27( +M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R# +M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)! +M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\ +MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K" +M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U +MO(;8,!MJPVW(#;NA-_R&X#`3R/Z#$]JL?U +MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\ +MD`@R02K(!Z2/ +M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ +MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2 +M2LI)22DKI:6\E)@R4VK*3RLMY22_KI;V\E_@R7^K+?Z?O_)W`,W@* +MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG +M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4AZI/_:E`-:@*U:%*5(NJ +M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L +MBM6Q2E;+JED]JV@UK:K5M#6OZM6]RE?[ +MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U +MLVK6SRZMY/:_H-;VJU_7* +M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_ZVO_;7`-M@*VV%+;(NML3VVR#;9 +M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;`NOX3V\B#?Q*M[% +MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D] +MO:@W]:K>UVNO[;V]N#?WZM[=RWM[K^_]O<`W^`K? +MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2; +ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X +M#:OA-#@/Z^$]S(?[L!_^PX`X$`OB04R( +M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1G@0-2\,]`(U'QT(0``F'H@``@!04A`E$R14P4`B`'!! +M03>R*!"+1@0@0`(GDB!`0"D>V.&12":IY)),-NGDDU!&*>645%9IY9583MG$ +M$DE,\8014X#0Y1,@Y&"##3"\@`28(!B1!!-%3)'%%%04H:$05;Q)1!%2@&`" +M"!<6,<034CPH8`M2O$"$%89*44005!`*`@I#I`!"##GD,`,(1;B0Q1-5.'$$ +M$4'`.6FEEV9Z`PA*N`#%HU)XZ<0+K4XQ!!)O,I&$J%GVZFNO,A"80PP%RA`# +M#C/0(`,-!)(0+`S#%GMLLLLV2^"UV&9+(`#/1AN#L<@JRRP,)!CYZ[GHIJON +MNNRVZ^Z[\,8K;Y/_U;O8/P(2:*"]_/;K[[\`!US=EDF`T,0;;H#PQ!AT7"K# +MI3CHD*P.RX+0K0(RN%"@QC&$8<.FB(+00AUID'&IR&>4;#$(+K3\0AISO"'P +MS#37;//-.*>5BR8'WDBD0`0`P(%`!Q*1A!0QL(@!T0!((<4733QA11%$!-V! +M0$,:+84,06<@T```:(U#T!X`'?;1,P2M@4`%G"U%#D%_()`!;M/0]@8"'>`V +ML0`$#<*.;M<0=`@"*>"V#4'7&-`";M^0\^.01R[YY)17;OGEF&>N^>8PF1C0 +MC28&+=#0`6B=]$!+!^`TU%)3+7I`5PN@-=<#>3V`V*\#4#8!6J<]T-H%:`WW +M0'(;H+7=`^%]@.DP]#W0WPAH+?A`A"N@->(T`K"`UHYS[OWWX(BG;QDD-N((@(X!\>@CD`$(^?.)!TX!Q0$!^/).TU(H0``"`04LL"``[0C" +M0(+0#K`19`">(]J0""(`GPWD`E0P@@8"X(`>_2A(;5```R0@`@R0((0C+"$) +MAE`$#@1@!`6!H4':49!VN*%]!,G10.3WP?I-L$BJ"^``"WC`!"ZP@06!8$%\ +M5)`*XBB#&^S@_$`H0A*:$(56)`$`]""T@@P-?N]#T!1]>+\`\.YH,0"@`!/A +MA"8DX$!D2(,<8D!$!"I0(`QTX$"42!`F4G!H!.$`%#GH0?J1H)!43*$)^0`` +M+1*$!%0(`R\"PHLP9'",CCP1D0[@)CBY8`8(^,QG.D?C`AC81I[6+ +M:2\Q.<\BK%2?6,VJ5K?ZFAM"52`Z!:A'!XJB@B;5I'ED*$N?6I`,2+6'\*3I +M.[`!OX +MREC.LI;+`V]<2V]/+H,KQEM\'KW*D3?6I?$ +M*>V;DXFKT<^QV<4TI>O5"'*U.(MYO4"5P69).5\9C#BM9Q9N$P<]D`[XM\59 +MW+*F-\WI3D/EAI062*'#'"2]/KBD9LXNFK$6:MC].8O,[6(@GQL_,E>-Y'<`8M*8E$GY;#0!+SSN1L'8M%^5&$+DI&]T_/9ZSBRQ'&D@;X-5F./&T +M/>Q,A_OC(`^YR#MR0XT+Q.'G]JDLU7UG2*M:TA0T>4`^\&IYNEEW!3&WOB$N +MRWY?G->GI2"\=5?S*RH<`'\C"/123E:@UF#B\ZW!S]L==%LF_7DW1\[U +MKGO]ZP.YX=4%LO2=JYR@N5[W=3&^:I>./2`@*'I<,UWR@J#<["&N\]1?[NZ8 +MVUWN<^4BX0A"N(>?W8S7@[IGY6B#O9L8YK88$4 +MGNECUGN9V!O_G:DTSJ,E^5WVEL^[=)6N_5Q/[ARB3U>+D)6 +M(#4R?-.YI_C/WL#QU&X[<7\?$!%0?O<>U[STIT]]V-Z0^0`(/NC3/?M_`UW@ +M3<2^\W4_=YO;&P"H1__K>7AH7(M>UVO_/BV;F'[5DU_#6A0F//[!__[#XR`> +MM6.(=S1"Q5>9P&B+)P=(-7KQ1W7@1T'[UW_\!P_/5WXF-`2-%0#<=5/5UX$> +M^(&:PR?M$``*0`6'$$1)``5?@"G#`BE(4`0@@"%#L`0QF`1$<`0PN"MU(@6W +M$@2B`H-0@"&1,BA,``)!*#4V&"<@,`55``500"A4T":2\H13D`18T"9O`H-R +M0B=VLH1VXH-4D`1#H#]P$@13`(.#X@14$`1#$(5&8RM&6`5"H"M3\()]8@22 +MHC^"D@1N,@20D@1/X`1+""H\V"D0V(@4I&"EW*"EIN(9M.(EX*`67&(:!Z`(@.(NT +M6(NVF!%H4`9LP`9O8#BW^(O`&(S".(S$6(S&>(S(F(S*N(S,V(S.^(S0&(W2 +M.(W46(W6>(W8F(W:N(W^(W@&([B.([D6([F>([HF([JN([LV([N^([P +M&(_R.(_T6(_V>(_XF(_ZN(_\V(_^^(\`&9`".9`$69`&>9`(F9`*N9`,V9`. +M^9`0&9$2.9$469$6>9$8F9$:N9$^9$@&9(B.9(D69(F>9(HF9(JN9(L +MV9(N^9(P&9,R.9,T69,V>9,XF9,ZN9,\V9,^^9-`&91".91$691&>91(F91* +MN91,V91.^910&952.9546956>958F95:N95^95@&99B.99D699F>99H +MF99JN99LV99N^99P&9=R.9=T69=V>9=XF9=ZN9=\V9=^^9>`&9B".9B$69B& +M>9B(F9B*N9B,V9B.^9B0&9F2.9F469F6>9F8F9F:N9F^9F@&9JB.9JD +M69JF>9JHF9JJN9JLV9JN^9JP&9NR.9NT69NV>9NXF9NZN9N\V9N^^9O`&9S" +M.9S$69S&>9S(F9S*N9S,V9S.^9S0&9W2.9W469W6>9W8F9W:N9W^9W@ +M&9[B.9[D69[F>9[HF9[JN9[LV9[N^9[P&9_R.9_T69_V>9_XF9_ZN9_\V9_^ +M^9\`&J`".J`$6J`&>J`(FJ`*NJ`,VJ`.^J`0&J$2.J$46J$6>J$8FJ$:NJ$< +MVJ$>^J$@&J(B.J(D6J(F>J(HFJ(JNJ(LVJ(N^J(P&J,R.J,T6J,V>J,XFJ,Z +MNJ,\VJ,^^J-`&J1".J1$6J1&>J1(FJ1*NJ1,VJ1.^J10&J52.J546J56>J58 +MFJ5:NJ5^J5@&J9B.J9D6J9F>J9HFJ9JNJ9LVJ9N^J9P&J=R.J=T6J=V +M>J=XFJ=ZNJ=\VJ=^^J>`&JB".JB$6JB&>JB(FJB*NJB,VJB.^JB0&JF2.JF4 +M6JF6>JF8FJF:NJF^JF@&JJB.JJD6JJF>JJHFJJJNJJLVJJN^JJP&JNR +M.JNT6JNV>JNXFJNZNJN\VJN^^JO`&JS".JS$6JS&>JS(FJS*NJS,VJS.^JS0 +M&JW2.JW46JW6>JW8FJW:NJW^JW@&J[B.J[D6J[F>J[HFJ[JNJ[LVJ[N +M^J[P&J_R.J_T6J_V>J_XFJ_ZNJ_\VJ_^^J\`&[`".[`$6[`&>[`(F[`*N[`, +MV[`.^[`0&[$2.[$46[$6>[$8F[$:N[$^[$@&[(B.[(D6[(F>[(HF[(J +MN[(LV[(N^[(P&[,R.[,T6[,V>[,XF[,ZN[,\V[,^^[-`&[1".[1$6[1&>[1( +MF[1*N[1,V[1.^[10&[52.[546[56>[58F[5:N[5^[5@&[9B.[9D6[9F +M>[9HF[9JN[9LV[9N^[9P&[=R.[=T6[=V>[=XF[=ZN[=\V[=^^[>`&[B".[B$ +M6[B&>[B(F[B*N[B,V[B.^[B0&[F2.[F46[F6>[F8F[F:N[F^[F@&[JB +M.[JD6[JF>[JHF[JJN[JLV[JN^[JP&[NR.[NT6[NV>[NXF[NZN[N\V[N^^[O` +M&[S".[S$6[S&>[S(F[S*N[S,V[S.^[S0&[W2.[W46[W6>[W8F[W:N[W +M^[W@&[[B.[[D6[[F>[[HF[[JN[[LV[[N^[[P&[_R.[_T6[_V>[_XF[_ZN[_\ +MV[_^^[\`',`"/,`$7,`&?,`(G,`*O,`,W,`._,`0',$2/,$47,$6?,$8G,$: +MO,$_,$@',(B/,(D7,(F?,(HG,(JO,(LW,(N_,(P',,R/,,T7,,V?,,X +MG,,ZO,,\W,,^_,-`',1"/,1$7,1&?,1(G,1*O,1,W,1._,10',52/,547,56 +M?,58G,5:O,5_,5@',9B/,9D7,9F?,9HG,9JO,9LW,9N_,9P',=R/,=T +M7,=V?,=XG,=ZO,=\W,=^_,>`',B"/,B$7,B&?,B(G,B*O,B,W,B._,B0',F2 +M/,F47,F6?,F8G,F:O,F_,F@',JB/,JD7,JF?,JHG,JJO,JLW,JN_,JP +M',NR/,NT7,NV?,NXG,NZO,N\W,N^_,O`',S"/,S$7,S&?,S(G,S*O,S,W,S. +M_,S0',W2/,W47,W6?,W8G,W:O,W_,W@',[B/,[D7,[F?,[HG,[JO,[L +MW,[N_,[P',_R/,_T7,_V?,_XG,_ZO,_\W,_^_,\`'=`"/=`$7=`&?=`(G=`* +MO=`,W=`._=`0'=$2/=$47=$6?=$8G=$:O=$_=$@'=(B/=(D7=(F?=(H +MG=(JO=(LW=(N_=(P'=,R/=,T7=,V?=,XG=,ZO=,\W=,^_=-`'=1"/=1$7=1& +M?=1(G=1*O=1,W=1._=10'=52/=547=56?=58G=5:O=5_=5@'=9B/=9D +M7=9F?=9HG=9JO=9LW=9N_=9P'==R/==T7==V?==XG==ZO==\W==^_=>`'=B" +M/=B$7=B&?=B(G=B*O=B,W=B._=B0'=F2/=F47=F6?=F8G=F:O=F_=F@ +M'=JB/=JD7=JF?=JHG=JJO=JLW=JN_=JP'=NR/=NT7=NV?=NXG=NZO=N\W=N^ +M_=O`'=S"/=S$7=S&?=S(G=S*O=S,W=S._=S0'=W2/=W47=W6?=W8G=W:O=W< +MW=W>_=W@'=[B/=[D7=[F?=[HG=[JO=[LW=[N_=[P'=_R/=_T7=_V?=_XG=_Z +MO=_\W=_^_=\`'N`"/N`$7N`&?N`(GN`*ON`,WN`._N`0'N$2/N$47N$6?N$8 +MGN$:ON$_N$@'N(B/N(D7N(F?N(HGN(JON(LWN(N_N(P'N,R/N,T7N,V +M?N,XGN,ZON,\WN,^_N-`'N1"/N1$7N1&?N1(GN1*ON1,WN1._N10'N52/N54 +M7N56?N58GN5:ON5_N5@'N9B/N9D7N9F?N9HGN9JON9LWN9N_N9P'N=R +M/N=T7N=V?N=XGN=ZON=\WN=^_N>`'NB"/NB$7NB&?NB(GNB*ONB,WNB._NB0 +M'NF2/NF47NF6?NF8GNF:ONF_NF@'NJB/NJD7NJF?NJHGNJJONJLWNJN +M_NJP'NNR/NNT7NNV?NNXGNNZONN\WNN^_NO`'NS"/NS$7NS&?NS(GNS*ONS, +MWNS._NS0'NW2/NW47NW6?NW8GNW:ONW_NW@'N[B/N[D7N[F?N[HGN[J +MON[LWN[N_N[P'N_R/N_T7N_V?N_XGN_ZON_\WN_^_N\`'_`"/_`$7_`&?_`( +MG_`*O_`,W_`.__`0'_$2/_$47_$6?_$8G_$:O_$__$@'_(B/_(D7_(F +M?_(HG_(JO_(LW_(N__(P'_,R/_,T7_,V?_,XG_,ZO_,\W_,^__-`'_1"/_1$ +M7_1&?_1(G_1*O_1,W_1.__10'_52/_547_56?_58G_5:O_5__5@'_9B +M/_9D7_9F?_9HG_9JO_9LW_9N__9P'_=R/_=T7_=V?_=XG_=ZO_=\W_=^__>` +M'_B"/_B$7_B&?_B(G_B*O_B,W_B.__B0'_F2/_F47_F6?_F8G_F:O_F +M__F@'_JB/_JD7_JF?_JHG_JJO_JLW_JN__JP'_NR/_NT7_NV?_NXG_NZO_N\ +MW_N^__O`'_S"/_S$7_S&?_S(G_S*O_S,W_S.__S0'_W2/_W47_W6?_W8G_W: +MO_W__W@'_[B/_[D7_[F?_[HG_[JO_[LW_[N__[P'__R/__T7__V?__X +MG__ZO__\W__^__\`,``*P`%(``N@`3R`"#`!*L`%R``;H`-\@!`P`DK`"4@! +M*Z`%O(`8,`-JP`W(`3N@!_R`(#`$BL`12`)+H`D\@2@P!:K`%<@"6Z`+?($P +M,`;*P!E(`VN@#;R!.#`'ZL`=R`-[H`_\@4`P"`K!(4@$BZ`1/()(,`DJP27( +M!)N@$WR"4#`*2L$I2`6KH!6\@E@P"VK!+<@%NZ`7_()@,`R*P3%(!LN@&3R# +M:#`-JL$UR`;;H!M\@W`P#LK!.4@'ZZ`=O(-X,`_JP3W(!_N@'_R#@#`0"L)! +M2`@+H2$\A(@P$2K"1<@(&Z$C?(20,!)*PDE("2NA);R$F#`3:L)-R`D[H2?\ +MA*`P%(K"44@*2Z$I/(6H,!6JPE7("ENA*WR%L#`6RL)92`MKH2V\A;@P%^K" +M7<@+>Z$O_(7`,!@*PV%(#(NA,3R&R#`9*L-ER`R;H3-\AM`P&DK#:4@-JZ$U +MO(;8,!MJPVW(#;NA-_R&X#`3R/Z#$]JL?U +MR![;HWM\C_`Q/LK'^4@?ZZ-]O(_X,3_JQ_W('_NC?_R/`#)`"L@!22`+I($\ +MD`@R02K(!Z2/ +M_)%`,D@*R2%))(NDD3R22#))*LDER22;I)-\DE`R2DK)*4DEJZ25O))8,DMJ +MR2W));NDE_R28#),BLDQ22;+I)D\DV@R3:K)-#)/ZLD]R2?[I)_\DX`R4`K*04DH"Z6A/)2(,E$JRD7)*!NEHWR4D#)2 +M2LI)22DKI:6\E)@R4VK*3RLMY22_KI;V\E_@R7^K+?Z?O_)W`,W@* +MS^%)/(NG\3R>R#-Y*L_ER3R;I_-\GM`S>DK/Z4D]JZ?UO)[8,WMJS^W)/;NG +M]_R>X#-\BL_Q23[+I_D\G^@S?:K/]4I/ZZD]O:?X-)_JTWW*3_NI/_VG`#6@"M2!2E`+JD$]J`@UH2K4AZI/_:E`-:@*U:%*5(NJ +M43VJ2#6I*M6ERE2;JE-]JE`UJDK5J4I5JZI5O:I8-:MJU:W*5;NJ5_VJ8#6L +MBM6Q2E;+JED]JV@UK:K5M#6OZM6]RE?[ +MJE_]JX`UL`K6P4I8"ZMA/:R(-;$JUL7*6!NK8WVLD#6R2M;)2EDKJV6]K)@U +MLVK6SRZMY/:_H-;VJU_7* +M7MNK>WVO\#6^RM?Y2E_KJWV]K_@UO^K7_ZVO_;7`-M@*VV%+;(NML3VVR#;9 +M*MMERVR;K;-]MM`VVDK;:4MMJZVUO;;8-MMJVVW+;;NMM_VVX#;`NOX3V\B#?Q*M[% +MRW@;K^-]O)`W\DK>R4MY*Z_EO;R8-_-JWLW+>3NOY_V\H#?TBM[12WI+K^D] +MO:@W]:K>UVNO[;V]N#?WZM[=RWM[K^_]O<`W^`K? +MX4M\BZ_Q/;[(-_DJW^7+?)NO\WV^T#?Z2M_I2WVKK_6]OM@W^VK?[[`/_L%`.`@+X2%,A(NP$3["2#@)*^$ES(2; +ML!-^PE`X"DOA*4R%J[`5OL)8.`MKX2W,A;NP%_["8#@,B^$Q3(;+L!D^PV@X +M#:OA-#@/Z^$]S(?[L!_^PX`X$`OB04R( +M"[$A/L2(.!$KXD7,B!NQ(W[$D#@22^))3(DKL26^Q)@X$VOB3R^-Y +M3(_KL3V^Q_@X'^OC?[-O_LW`.3@+Y^%,G(NS<3[.R#DY*^?ES)R;LW-^SM`Y +M.DOGZ4R=J[-UOL[8.3MKY^W,G;NS=_[.X#D\B^?Q3)[+LWD^S^@Y/:OG] +MV[-[?L_P.3[+Y_E,G^NS?;[/^#D_Z^?]S)_[LW_^SP`Z0`OH`4V@"[2!/M`( +M.D$KZ`7-H!NT@W[0$#I"2^@)3:$KM(6^T!@Z0VOH#4VOZ[6]OM?X.E_KZWW-K_NUO_[7`#M@ +M"^R!3;`+ML$^V`@[82OLA[;/_ME`.V@+[:%-M(NVT3[:2#MI*^VES;2;MM-^VE`[:DOMJ4VU +MJ[;5OMI8.VMK[:W-M;NVU_[:8#MLB^VQ3;;+MMD^VV@[;:OMM#MOZ^V]S;?[MM_^VX`[<`ONP4VX"[?A/MR(.W$K[L7- +MN!NWXW[2OOYV#M[:^_MS;V[M_?^ +MWN`[?(OO\4V^R[?Y/M_H.WVK[_7-OMNW^W[?\#M^R^_Y3;_KM_V^W_@[?^OO +M_[DO_^7`/)@+\V%.S(NY,3_FR#R9*_-ESLR;N3-_YM`\FDOS:4[-J[DUO^;8 +M/)MK\VW.S;NY-__FX#R3_OZ#V]J_?USM[; +MNWM_[_`]OLOW^4[?Z[M]O^_X/;_K]_W.W_N[?__O`#[`"_@!3^`+O($_\`@^ +MP2OX!<_@&[R#?_`0/L)+^`E/X2N\A;_P&#[#:_@-S^$[O(?_\"`^Q(OX$4_B +M2[R)/_$H/L6K^!7/XEN\BW_Q,#[&R_@93^-KO(V_\3@^Q^OX'<_C>[R/__%` +M/L@+^2%/Y(N\D3_R2#[)*_DES^2;O)-_\E`^RDOY*4_EJ[R5O_)8/LMK^2W/ +MY;N\E__R8#[,B_DQ3^;+O)D_\V@^S:OY-<_FV[R;?_-P/L[+^3E/Y^N\G;_S +M>#[/Z_D]S^?[O)__\X`^T`OZ04_H"[VA/_2(/M$K^D7/Z!N]HW_TD#[22_I) +M3^DKO:6_])@^TVOZ3<_I.[VG__2@/M2+^E%/ZDN]J3_UJ#[5J_I5S^I;O:M_ +M];`^ULOZ64_K:[VMO_6X/M?K^EW/ZWN]K__UP#[8"_MA3^R+O;$_]L@^V2O[ +M9<_LF[VS?_;0/MI+^VE/[:N]M;_VV#[;:_MMS^V[O;?_]N`^W(O[<4_NR[VY +M/_?H/MVK^W7/[MN]NW_W\#[>R_MY3^_KO;V_]_@^W^O[?<_O^[V___<`/^`+ +M_(%/\`N^P3_X"#_A*_R%S_`;OL-_^!`_XDO\B4_Q*[[%O_@8/^-K_(W/\3N^ +MQ__X(#_DB_R13_)+OLD_^2@_Y:O\E<_R6[[+?_DP/^;+_)E/\VN^S;_Y.#_G +MZ_R=S_-[OL__^4`_Z`O]H4_TB[[1/_I(/^DK_:7/])N^TW_Z4#_J2_VI3_6K +MOM6_^E@_ZVO]K<_UN[[7__I@/^R+_;%/]LN^V3_[:#_MJ_VUS_;;OMM_^W`_ +M[LO]N4_WZ[[=O_MX/^_K_;W/]_N^W__[@#_P"_[!3_@+O^$__(@_\2O^Q<_X +M&[_C?_R0/_)+_LE/^2N_Y;_\F#_S:_[-S_D[O^?__*`_](O^T4_Z2[_I/_VH +M/_6K_M7/^EN_ZW_]L#_VR_[93_MKO^V__;@_]^O^W<_[>[_O__W`/_@+_^%/ +M_(N_\3_^R#_Y*__ES_R;O_-__M`_^DO_Z4_]J[_UO_[8/_MK_^W/_;N_]__^ +MX#_\B__Q3_[+O_D__^@__:O_]<_^V[_[?__P/_[+__E/_^N__;__^#__Z__] +MS__[O____P!@`"@`#H`$8`%H`!Z`"&`"J``N@`Q@`^@`/H`08`0H`4Z`%&`% +M:`%>@!A@!J@!;H`<8`?H`7Z`(&`(*`*.@"1@"6@"GH`H8`JH`JZ`+&`+Z`*^ +M@#!@#"@#SH`T8`UH`]Z`.&`.J`/N@#Q@#^@#_H!`8!`H!`Z!1&`1:`0>@4A@ +M$J@$+H%,8!/H!#Z!4&`4*`5.@51@%6@%7H%88!:H!6Z!7&`7Z`5^@6!@&"@& +MCH%D8!EH!IZ!:&`:J`:N@6Q@&^@&OH%P8!PH!\Z!=&`=:`?>@7A@'J@'[H%\ +M8!_H!_Z!@&`@*`@.@H1@(6@('H*(8"*H""Z"C&`CZ`@^@I!@)"@)3H*48"5H +M"5Z"F&`FJ`EN@IQ@)^@)?H*@8"@H"HZ"I&`I:`J>@JA@*J@*KH*L8"OH"KZ" +ML&`L*`O.@K1@+6@+WH*X8"ZH"^Z"O&`OZ`O^@L!@,"@,#H/$8#%H#!Z#R&`R +MJ`PN@\Q@,^@,/H/08#0H#4Z#U&`U:`U>@]A@-J@-;H/<8#?H#7Z#X&`X*`Z. +M@^1@.6@.GH/H8#JH#JZ#[&`[Z`Z^@_!@/"@/SH/T8#UH#]Z#^&`^J`_N@_Q@ +M/^@/_H,`84`H$`Z$!&%!:!`>A`AA0J@0+H0,84/H$#Z$$&%$*!%.A!1A16@1 +M7H0884:H$6Z$'&%'Z!%^A"!A2"@2CH0D84EH$IZ$*&%*J!*NA"QA2^@2OH0P +M84PH$\Z$-&%-:!/>A#AA3J@3[H0\84_H$_Z$0&%0*!0.A41A46@4'H5(85*H +M%"Z%3&%3Z!0^A5!A5"@53H54855H%5Z%6&%6J!5NA5QA5^@5?H5@85@H%HZ% +M9&%9:!:>A6AA6J@6KH5L85OH%KZ%<&%<*!?.A71A76@7WH5X85ZH%^Z%?&%? +MZ!?^A8!A8"@8#H:$86%H&!Z&B&%BJ!@NAHQA8^@8/H:0860H&4Z&E&%E:!E> +MAIAA9J@9;H:<86?H&7Z&H&%H*!J.AJ1A:6@:GH:H86JH&JZ&K&%KZ!J^AK!A +M;"@;SH:T86UH&]Z&N&%NJ!ONAKQA;^@;_H;`87`H'`Z'Q&%Q:!P>A\AA"@>CH?D +M87EH'IZ'Z&%ZJ!ZNA^QA>^@>OH?P87PH'\Z']&%]:!_>A_AA?J@?[H?\87_H +M'_Z'`&*`*"`.B`1B@6@@'H@(8H*H("Z(#&*#Z"`^B!!BA"@A3H@48H5H(5Z( +M&&*&J"%NB!QBA^@A?H@@8H@H(HZ()&*):"*>B"ABBJ@BKH@L8HOH(KZ(,&*, +M*"/.B#1BC6@CWH@X8HZH(^Z(/&*/Z"/^B$!BD"@D#HE$8I%H)!Z)2&*2J"0N +MB4QBD^@D/HE08I0H)4Z)5&*5:"5>B5ABEJ@E;HE<8I?H)7Z)8&*8*":.B61B +MF6@FGHEH8IJH)JZ);&*;Z":^B7!BG"@GSHET8IUH)]Z)>&*>J"?NB7QBG^@G +M_HF`8J`H*`Z*A&*A:"@>BHABHJ@H+HJ,8J/H*#Z*D&*D*"E.BI1BI6@I7HJ8 +M8J:H*6Z*G&*GZ"E^BJ!BJ"@JCHJD8JEH*IZ*J&*JJ"JNBJQBJ^@JOHJP8JPH +M*\Z*M&*M:"O>BKABKJ@K[HJ\8J_H*_Z*P&*P*"P.B\1BL6@L'HO(8K*H+"Z+ +MS&*SZ"P^B]!BM"@M3HO48K5H+5Z+V&*VJ"UNB]QBM^@M?HO@8K@H+HZ+Y&*Y +M:"Z>B^ABNJ@NKHOL8KOH+KZ+\&*\*"_.B_1BO6@OWHOX8KZH+^Z+_&*_Z"_^ +'BP!CP+@7`0`` +` +end diff --git a/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu b/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu new file mode 100644 index 0000000..00896e1 --- /dev/null +++ b/lib/libarchive/test/test_read_format_iso_zisofs.iso.Z.uu @@ -0,0 +1,63 @@ +$FreeBSD$ + +begin 644 test_read_format_iso_zisofs.iso.Z +M'YV0``(*'$BPH,&#"!,J7,BPH<.'$"-*G$BQHL6+&#-JW,BQH\>/($.*'$FR +MI,F3*%.J7,FRIO8,.*'4NVK-FS:-.J7//JW/'D"-+GDRYLN7+F#-KWLRY +ML^?/H$.+'DVZM.G3J%.K7LVZM>O7L&/+GDV[MNW;N'/KWLV[M^_?P(,+'TZ\ +MN/'CR),K7\Z\N?/GT*-+GTZ]NO7KV+-KW\Z]N_?OX,.+'T^^O/GSZ-.K7\^^ +MO?OW\./+GT^_OOW[^//KW\^_O_^_`0Q!!`PPQ!```$;(44890DQ!!`@01BCA +MA!1***`43S11X88<1GA0+`6!Z-&!``1`XH$((`"`!059,$%"%0PD`@`7%%2C +MB@*I:$0``B10(@D"!'3B@1T6:>212":IY)),-NGDDU!&*>645%9I991-+)'$ +M%$\8,04(6SX!0@XVV`##"TAX"8(123!1Q!193$%%$1H*446;1!0A!0@F@'!A +M$4,\(<6#`K8@Q0M$6$&H%$4$086@(*`P1`H@Q)!##C.`4(0+63Q1A1-'$!&$ +MFY%.6NFE-X"@A`M0-"H%ETZ\L.H40R#1)A-)@'KEKKSN*@.!.<`0K`PRQ$!# +M#300"`,)OPKK++'&(JLL"NXY)9K[KGHIJON +MNNRVZ^Z2_\6[V#\"$FB@O/CFJ^^^_/9;799)@'!%&62`,$49<$`H`PC%ZG"L +MPS`P#*P";:R1QAQOF#$'PRX4"(*A']>11L$Q?'S&R`Q_K`<(+K3\@AX7O^'O +MS#37;//-.)=U8(U""C0``!@(="`124B1\]%()ZWTTDPW[?334$M]MI,(T*CC0#@&)".//H8`)`]EWC@ +M%%`<$(`O[P`@A10%!!`(%%B$VTX0`P71CM8##6"UT$$2)``51F@0@`,[]OAC +M&PD(4$$+*)``NNBDDS!$$1P$D$%!KQO43D'MF/$V03<.1+?G=U<^9`"#%WYX +MX@$LWOCC!4E>$(\%79[YYIW;;7KHHY=^>O4D```'T`4%+7?<"-;]H^]"#N!U +M\`$DXD03"!Q(1AIR(*XXXP(Y7OE``DPNY/T".:\YY^*[6_0^1[W4`8`0`-!` +M031@`P,,Q``V&.#=A":D`[#)32[800S0I[XF).!`9D@#&\H@OP"0(A`#"00I +M^!>0_"V/A0#P'_0"2`()3@]UI=."$2`0`#CH@0`/H$(8>!$07H2!"HQ(X`(; +M^,`(TI"")5H`$H(P*%PY80D9W"#ATK>^!AP(#6&0`QG8D`8WK*&$)TSA"ING +MOQ+!4(8`Y-T-L7>]U.F0ASX$HA")"``C4L$0`-A`001I$!M",0`*@%,3K(A% +M#0INBXU8'P,.-(<\M(&,9BPA,$(QD%``HXTF>F'SIL"$!9"(`"$<(>;^MZ,! +M^$@`-0R`*V,XQ]2YC9`#P25!ZEBZ0RY`D8R401;1%\DF>!$`E;QD&=<@`TUR +M4B">!"4HWTC*28(/``.@0QO@L,K-\;*6UBM@Z101R$$>Y'0%^%GV\A:`7V9A +MD;E:P@R&"%HA4`^+TK&A-JUK7:A$]M0.15#B$ +M5I,`A2]8*@C``IO@$J"6P:@J.2\`0G&,Q3B-T4A&;+ +M6-\"5[A@RI-MD9L$/8')N8U-0A.HF`406.$)3*A"$_B:)UI)@:Z/&BZD:GO; +MW'Z7N%(8;VN;ZP*V^O>_``[PS&Y`CBE8(AG;L,8!]JC2!P0$'P4("!,!,.$* +M.Y#"%[:PA#/,X0U[&,,?UC"(1RSB$G>8Q"9 +MRE>VQG+7]8RF,I2F_K4J$ZUJE?-ZE:[^M6PCK6L9TWK6MOZUKC. +MM:YWS>M>^_K7P`ZVL(=-[&(;^]C(3K:RE\WL9CO[V=".MK2G3>UJ6_O:V,ZV +MMK?-[6Y[^]O@#K>XQTWNYVN_O=\(ZWO.=-[WK;^][XSK>^ +M]\WO?OO[WP`/N,`'3O""&_S@"$^XPA?.\(8[_.$0C[C$)T[QBEO\XAC/N,8W +MSO&.>_SC(`^YR$=.\I*;_.0H3[G*5\[REKO\Y3"/NI8S[K6M\[U +MKGO]ZV`/N]C'3O:RF_WL:$^[VM?.]K:[_>UPC[O^ +M^_WO@`^\X`=/^,(;_O"(3[SB%\_XQCO^\9"/O.0G3_G*6_[RF,^\YC?/^I7S_K6N_[UL(^][&=/^]K;_O:XS[WN=\_[WOO^ +M]\`/OO"'3_SB&__XR$^^\I?/_.8[__G0C[[TIT_]ZEO_^MC/OO:WS_WN>__[ +MX`^_^,=/_O*;__SH3[_ZU\_^]KO__?"/O_SG3__ZV__^^,^__O?/__[[__\` +M&(`".(`$6(`&>(`(F(`*N(`,V(`.^(`0&($2.($46($6>($8F($:N($ +M^($@&((B.((D6((F>((HF((JN((LV((N^((P&(,R.(,T6(,V>(,XF(,ZN(,\ +MV(,^^(-`&(1".(1$6(1&>(1(F(1*N(1,V(1.^(10&(52.(546(56>(58F(5: +MN(5^(5@&(9B.(9D6(9F>(9HF(9JN(9LV(9N^(9P&(=R.(=T6(=V>(=X +MF(=ZN(=\V(=^^(>`&(B".(B$6(B&>(B(F(B*N(B,V(B.^(B0&(F2.(F46(F6 +@>(F8F(F:N(F^(F@&(JB.(JD6(JF>(JHF(JJN'`` +` +end diff --git a/lib/libarchive/test/test_read_format_isojoliet_bz2.c b/lib/libarchive/test/test_read_format_isojoliet_bz2.c index 9ee87c9..b2f22a7 100644 --- a/lib/libarchive/test/test_read_format_isojoliet_bz2.c +++ b/lib/libarchive/test/test_read_format_isojoliet_bz2.c @@ -46,49 +46,39 @@ else TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/long-joliet-file-name.textfile /tmp/iso/dir TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink fi -mkhybrid -J -uid 1 -gid 2 /tmp/iso | bzip2 > test_read_format_isojoliet_bz2.iso.bz2 -F=test_read_format_isojoliet_bz2.iso.bz2 +F=test_read_format_iso_joliet.iso.Z +mkhybrid -J -uid 1 -gid 2 /tmp/iso | compress > $F uuencode $F $F > $F.uu exit 1 */ -static void -joliettest(int withrr) +DEFINE_TEST(test_read_format_isojoliet_bz2) { - const char *refname = "test_read_format_isojoliet_bz2.iso.bz2"; + const char *refname = "test_read_format_iso_joliet.iso.Z"; struct archive_entry *ae; struct archive *a; const void *p; size_t size; off_t offset; - int r; - - if (withrr) { - refname = "test_read_format_isojolietrr_bz2.iso.bz2"; - } extract_reference_file(refname); assert((a = archive_read_new()) != NULL); - r = archive_read_support_compression_bzip2(a); - if (r == ARCHIVE_WARN) { - skipping("bzip2 reading not fully supported on this platform"); - assertEqualInt(0, archive_read_finish(a)); - return; - } - assertEqualInt(0, r); + assertEqualInt(0, archive_read_support_compression_all(a)); assertEqualInt(0, archive_read_support_format_all(a)); assertEqualInt(ARCHIVE_OK, + archive_read_set_options(a, "iso9660:!rockridge")); + assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); /* First entry is '.' root directory. */ assertEqualInt(0, archive_read_next_header(a, &ae)); assertEqualString(".", archive_entry_pathname(ae)); - assert(S_ISDIR(archive_entry_stat(ae)->st_mode)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); assertEqualInt(2048, archive_entry_size(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(0, archive_entry_mtime_nsec(ae)); assertEqualInt(86401, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_stat(ae)->st_nlink); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); assertEqualInt(0, archive_entry_uid(ae)); assertEqualIntA(a, ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); @@ -97,100 +87,48 @@ joliettest(int withrr) /* A directory. */ assertEqualInt(0, archive_read_next_header(a, &ae)); assertEqualString("dir", archive_entry_pathname(ae)); - assert(S_ISDIR(archive_entry_stat(ae)->st_mode)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); assertEqualInt(2048, archive_entry_size(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(86401, archive_entry_atime(ae)); - if (withrr) { - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } /* A regular file with two names ("hardlink" gets returned * first, so it's not marked as a hardlink). */ assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("hardlink", archive_entry_pathname(ae)); - assert(S_ISREG(archive_entry_stat(ae)->st_mode)); + assertEqualString("long-joliet-file-name.textfile", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); assert(archive_entry_hardlink(ae) == NULL); assertEqualInt(6, archive_entry_size(ae)); assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt(6, (int)size); assertEqualInt(0, offset); assertEqualInt(0, memcmp(p, "hello\n", 6)); - if (withrr) { - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - /* TODO: Actually, libarchive should be able to - * compute nlinks correctly even without RR - * extensions. See comments in libarchive source. */ - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } /* Second name for the same regular file (this happens to be * returned second, so does get marked as a hardlink). */ assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString("hardlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); assertEqualString("long-joliet-file-name.textfile", - archive_entry_pathname(ae)); - assert(S_ISREG(archive_entry_stat(ae)->st_mode)); - assertEqualString("hardlink", archive_entry_hardlink(ae)); + archive_entry_hardlink(ae)); assert(!archive_entry_size_is_set(ae)); - if (withrr) { - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - /* TODO: See above. */ - assertEqualInt(2, archive_entry_nlink(ae)); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } /* A symlink to the regular file. */ assertEqualInt(0, archive_read_next_header(a, &ae)); assertEqualString("symlink", archive_entry_pathname(ae)); - if (withrr) { - assert(S_ISLNK(archive_entry_stat(ae)->st_mode)); - assertEqualString("long-joliet-file-name.textfile", - archive_entry_symlink(ae)); - } assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(172802, archive_entry_mtime(ae)); assertEqualInt(172802, archive_entry_atime(ae)); - if (withrr) { - assertEqualInt(1, archive_entry_nlink(ae)); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - } /* End of archive. */ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ - assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2); - if (withrr) { - assertEqualInt(archive_format(a), - ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); - } + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); /* Close the archive. */ assertEqualInt(0, archive_read_close(a)); assertEqualInt(0, archive_read_finish(a)); } - -DEFINE_TEST(test_read_format_isojoliet_bz2) -{ - joliettest(0); - - /* XXXX This doesn't work today; can it be made to work? */ -#if 0 - joliettest(1); -#else - skipping("Mixed Joliet/RR not fully supported yet."); -#endif -} - - - - diff --git a/lib/libarchive/test/test_read_format_isojoliet_long.c b/lib/libarchive/test/test_read_format_isojoliet_long.c new file mode 100644 index 0000000..acd220f --- /dev/null +++ b/lib/libarchive/test/test_read_format_isojoliet_long.c @@ -0,0 +1,141 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2009 Michihiro NAKAJIMA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* +Execute the following to rebuild the data for this program: + tail -n +35 test_read_format_isojoliet_long.c | /bin/sh + +rm -rf /tmp/iso +mkdir /tmp/iso +num=0 +file=""; +while [ $num -lt 100 ] +do + num=$((num+10)) + file="${file}1234567890" +done +dir="${file}dir" +mkdir /tmp/iso/${dir} +file="${file}123" +echo "hello" > /tmp/iso/${file} +ln /tmp/iso/${file} /tmp/iso/hardlink +if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h +TZ=utc touch -afm -t 197001020000.01 /tmp/iso /tmp/iso/${file} /tmp/iso/${dir} +else +TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/${file} /tmp/iso/${dir} +fi +F=test_read_format_iso_joliet_long.iso.Z +mkhybrid -J -joliet-long -uid 1 -gid 2 /tmp/iso | compress > $F +uuencode $F $F > $F.uu +rm -rf /tmp/iso +exit 1 + */ + +DEFINE_TEST(test_read_format_isojoliet_long) +{ + const char *refname = "test_read_format_iso_joliet_long.iso.Z"; + char pathname[104]; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + int i; + + for (i = 0; i < 100; i++) + pathname[i] = '0' + ((i+1) % 10); + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_set_options(a, "iso9660:!rockridge")); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* First entry is '.' root directory. */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString(".", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + assertEqualInt(86401, archive_entry_ctime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(0, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + + /* A directory. */ + pathname[100] = 'd'; + pathname[101] = 'i'; + pathname[102] = 'r'; + pathname[103] = '\0'; + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString(pathname, archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + + /* A regular file with two names (pathname gets returned + * first, so it's not marked as a hardlink). */ + pathname[100] = '1'; + pathname[101] = '2'; + pathname[102] = '3'; + pathname[103] = '\0'; + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString(pathname, archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assert(archive_entry_hardlink(ae) == NULL); + assertEqualInt(6, archive_entry_size(ae)); + assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(6, (int)size); + assertEqualInt(0, offset); + assertEqualInt(0, memcmp(p, "hello\n", 6)); + + /* Second name for the same regular file (this happens to be + * returned second, so does get marked as a hardlink). */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString("hardlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualString(pathname, archive_entry_hardlink(ae)); + assert(!archive_entry_size_is_set(ae)); + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + diff --git a/lib/libarchive/test/test_read_format_isojoliet_rr.c b/lib/libarchive/test/test_read_format_isojoliet_rr.c new file mode 100644 index 0000000..394df14 --- /dev/null +++ b/lib/libarchive/test/test_read_format_isojoliet_rr.c @@ -0,0 +1,159 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Based on libarchive/test/test_read_format_isorr_bz2.c with + * bugs introduced by Andreas Henriksson for + * testing ISO9660 image with Joliet extension. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* +Execute the following to rebuild the data for this program: + tail -n +35 test_read_format_isojoliet_rr.c | /bin/sh + +rm -rf /tmp/iso +mkdir /tmp/iso +mkdir /tmp/iso/dir +file="long-joliet-file-name.textfile" +echo "hello" >/tmp/iso/$file +ln /tmp/iso/$file /tmp/iso/hardlink +(cd /tmp/iso; ln -s $file symlink) +if [ "$(uname -s)" = "Linux" ]; then # gnu coreutils touch doesn't have -h +TZ=utc touch -afm -t 197001020000.01 /tmp/iso/hardlink /tmp/iso/$file /tmp/iso/dir +TZ=utc touch -afm -t 197001030000.02 /tmp/iso/symlink +TZ=utc touch -afm -t 197001020000.01 /tmp/iso +else +TZ=utc touch -afhm -t 197001020000.01 /tmp/iso/hardlink /tmp/iso/$file /tmp/iso/dir +TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink +TZ=utc touch -afhm -t 197001020000.01 /tmp/iso +fi +F=test_read_format_iso_joliet_rockridge.iso.Z +mkhybrid -J -uid 1 -gid 2 /tmp/iso | compress > $F +uuencode $F $F > $F.uu +exit 1 + */ + +DEFINE_TEST(test_read_format_isojoliet_rr) +{ + const char *refname = "test_read_format_iso_joliet_rockridge.iso.Z"; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* First entry is '.' root directory. */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString(".", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + + /* A directory. */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString("dir", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + + /* A regular file with two names ("hardlink" gets returned + * first, so it's not marked as a hardlink). */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString("long-joliet-file-name.textfile", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assert(archive_entry_hardlink(ae) == NULL); + assertEqualInt(6, archive_entry_size(ae)); + assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(6, (int)size); + assertEqualInt(0, offset); + assertEqualInt(0, memcmp(p, "hello\n", 6)); + assertEqualInt(86401, archive_entry_mtime(ae)); + /* mkisofs records their access time. */ + /*assertEqualInt(86401, archive_entry_atime(ae));*/ + /* TODO: Actually, libarchive should be able to + * compute nlinks correctly even without RR + * extensions. See comments in libarchive source. */ + assertEqualInt(2, archive_entry_nlink(ae)); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + + /* Second name for the same regular file (this happens to be + * returned second, so does get marked as a hardlink). */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString("hardlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualString("long-joliet-file-name.textfile", + archive_entry_hardlink(ae)); + assert(!archive_entry_size_is_set(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + /* TODO: See above. */ + assertEqualInt(2, archive_entry_nlink(ae)); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + + /* A symlink to the regular file. */ + assertEqualInt(0, archive_read_next_header(a, &ae)); + assertEqualString("symlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("long-joliet-file-name.textfile", + archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(172802, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_nlink(ae)); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + diff --git a/lib/libarchive/test/test_read_format_isorr_bz2.c b/lib/libarchive/test/test_read_format_isorr_bz2.c index 250019f..730c112 100644 --- a/lib/libarchive/test/test_read_format_isorr_bz2.c +++ b/lib/libarchive/test/test_read_format_isorr_bz2.c @@ -26,124 +26,178 @@ __FBSDID("$FreeBSD$"); /* +PLEASE use old cdrtools; mkisofs verion is 2.01. +This version mkisofs made wrong "SL" System Use Entry of RRIP. + Execute the following command to rebuild the data for this program: - tail -n +32 test_read_format_isorr_bz2.c | /bin/sh + tail -n +34 test_read_format_isorr_bz2.c | /bin/sh rm -rf /tmp/iso mkdir /tmp/iso mkdir /tmp/iso/dir echo "hello" >/tmp/iso/file -dd if=/dev/zero bs=1 count=12345678 >>/tmp/iso/file +dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file ln /tmp/iso/file /tmp/iso/hardlink (cd /tmp/iso; ln -s file symlink) +(cd /tmp/iso; ln -s /tmp/ symlink2) +(cd /tmp/iso; ln -s /tmp/../ symlink3) +(cd /tmp/iso; ln -s .././../tmp/ symlink4) +(cd /tmp/iso; ln -s .///file symlink5) +(cd /tmp/iso; ln -s /tmp//../ symlink6) TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir -TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink -mkhybrid -R -uid 1 -gid 2 /tmp/iso | bzip2 > test_read_format_isorr_bz2.iso.bz2 -F=test_read_format_isorr_bz2.iso.bz2 +TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink /tmp/iso/symlink5 +F=test_read_format_iso_rockridge.iso.Z +mkhybrid -R -uid 1 -gid 2 /tmp/iso | compress > $F uuencode $F $F > $F.uu exit 1 */ DEFINE_TEST(test_read_format_isorr_bz2) { - const char *refname = "test_read_format_isorr_bz2.iso.bz2"; + const char *refname = "test_read_format_iso_rockridge.iso.Z"; struct archive_entry *ae; struct archive *a; const void *p; size_t size; off_t offset; - int r; + int i; extract_reference_file(refname); assert((a = archive_read_new()) != NULL); - r = archive_read_support_compression_bzip2(a); - if (r == ARCHIVE_WARN) { - skipping("bzip2 reading not fully supported on this platform"); - assertEqualInt(0, archive_read_finish(a)); - return; - } - assertEqualInt(0, r); + assertEqualInt(0, archive_read_support_compression_all(a)); assertEqualInt(0, archive_read_support_format_all(a)); assertEqualInt(ARCHIVE_OK, archive_read_open_filename(a, refname, 10240)); - /* First entry is '.' root directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString(".", archive_entry_pathname(ae)); - assert(S_ISDIR(archive_entry_stat(ae)->st_mode)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(0, archive_entry_mtime_nsec(ae)); - assertEqualInt(86401, archive_entry_ctime(ae)); - assertEqualInt(0, archive_entry_stat(ae)->st_nlink); - assertEqualInt(0, archive_entry_uid(ae)); - assertEqualIntA(a, ARCHIVE_EOF, - archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt((int)size, 0); - - /* A directory. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("dir", archive_entry_pathname(ae)); - assert(S_ISDIR(archive_entry_stat(ae)->st_mode)); - assertEqualInt(2048, archive_entry_size(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); + /* Retrieve each of the 8 files on the ISO image and + * verify that each one is what we expect. */ + for (i = 0; i < 10; ++i) { + assertEqualInt(0, archive_read_next_header(a, &ae)); - /* A regular file. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("file", archive_entry_pathname(ae)); - assert(S_ISREG(archive_entry_stat(ae)->st_mode)); - assertEqualInt(12345684, archive_entry_size(ae)); - assertEqualInt(0, archive_read_data_block(a, &p, &size, &offset)); - assertEqualInt(0, offset); - assertEqualMem(p, "hello\n", 6); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - - /* A hardlink to the regular file. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("hardlink", archive_entry_pathname(ae)); - assert(S_ISREG(archive_entry_stat(ae)->st_mode)); - assertEqualString("file", archive_entry_hardlink(ae)); - assert(!archive_entry_size_is_set(ae)); - assertEqualInt(86401, archive_entry_mtime(ae)); - assertEqualInt(86401, archive_entry_atime(ae)); - assertEqualInt(2, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); - - /* A symlink to the regular file. */ - assertEqualInt(0, archive_read_next_header(a, &ae)); - assertEqualString("symlink", archive_entry_pathname(ae)); - assert(S_ISLNK(archive_entry_stat(ae)->st_mode)); - assertEqualString("file", archive_entry_symlink(ae)); - assertEqualInt(0, archive_entry_size(ae)); - assertEqualInt(172802, archive_entry_mtime(ae)); - assertEqualInt(172802, archive_entry_atime(ae)); - assertEqualInt(1, archive_entry_stat(ae)->st_nlink); - assertEqualInt(1, archive_entry_uid(ae)); - assertEqualInt(2, archive_entry_gid(ae)); + if (strcmp(".", archive_entry_pathname(ae)) == 0) { + /* '.' root directory. */ + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* Now, we read timestamp recorded by RRIP "TF". */ + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + /* Now, we read links recorded by RRIP "PX". */ + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString("hardlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(12345684, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello\n", 6); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { + /* A hardlink to the regular file. */ + /* Note: If "hardlink" gets returned before "file", + * then "hardlink" will get returned as a regular file + * and "file" will get returned as the hardlink. + * This test should tolerate that, since it's a + * perfectly permissible thing for libarchive to do. */ + assertEqualString("file", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualString("hardlink", archive_entry_hardlink(ae)); + assertEqualInt(0, archive_entry_size_is_set(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("file", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(172802, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp (an absolute path) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp/.. (with a ".." component) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp/..", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) { + /* A symlink to a path with ".." and "." components */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(".././../tmp", + archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink5", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file with "/" components. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(".///file", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(172802, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink6", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp//.. + * (with "/" and ".." components) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp//..", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else { + failure("Saw a file that shouldn't have been there"); + assertEqualString(archive_entry_pathname(ae), ""); + } + } /* End of archive. */ assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Verify archive format. */ - assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_BZIP2); + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); /* Close the archive. */ assertEqualInt(0, archive_read_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_read_finish(a); -#else assertEqualInt(0, archive_read_finish(a)); -#endif } diff --git a/lib/libarchive/test/test_read_format_isorr_ce.c b/lib/libarchive/test/test_read_format_isorr_ce.c new file mode 100644 index 0000000..c9cd059 --- /dev/null +++ b/lib/libarchive/test/test_read_format_isorr_ce.c @@ -0,0 +1,223 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2009 Michihiro NAKAJIMA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* +Execute the following command to rebuild the data for this program: + tail -n +32 test_read_format_isorr_ce.c | /bin/sh + +dirname=/tmp/iso +# +rm -rf $dirname +mkdir $dirname +# +num=0 +file="" +while [ $num -lt 150 ] +do + num=$((num+1)) + file="a$file" +done +# +num=0 +while [ $num -lt 3 ] +do + num=$((num+1)) + file="a$file" + echo "hello $((num+150))" > $dirname/$file + dd if=/dev/zero count=1 bs=4080 >> $dirname/$file + (cd $dirname; ln -s $file sym$num) +done +# +mkdir $dirname/dir +# +time1="197001020000.01" +time2="197001030000.02" +TZ=utc touch -afhm -t $time1 $dirname/dir $dirname/aaaa* +TZ=utc touch -afhm -t $time2 $dirname/sym* +TZ=utc touch -afhm -t $time1 $dirname +# +F=test_read_format_iso_rockridge_ce.iso.Z +mkisofs -R -uid 1 -gid 2 $dirname | compress > $F +uuencode $F $F > $F.uu +rm -rf $dirname +exit 1 + */ + +/* + * Test reading SUSP "CE" extension is works fine. + */ + +static void +mkpath(char *p, int len) +{ + int i; + + for (i = 0; i < len; i++) + p[i] = 'a'; + p[len] = '\0'; +} + +DEFINE_TEST(test_read_format_isorr_ce) +{ + const char *refname = "test_read_format_iso_rockridge_ce.iso.Z"; + char path1[160]; + char path2[160]; + char path3[160]; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + int i; + + mkpath(path1, 151); + mkpath(path2, 152); + mkpath(path3, 153); + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Retrieve each of the 8 files on the ISO image and + * verify that each one is what we expect. */ + for (i = 0; i < 8; ++i) { + assertEqualInt(0, archive_read_next_header(a, &ae)); + + if (strcmp(".", archive_entry_pathname(ae)) == 0) { + /* '.' root directory. */ + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* Now, we read timestamp recorded by RRIP "TF". */ + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + /* Now, we read links recorded by RRIP "PX". */ + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp(path1, archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString(path1, archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(4090, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello 151\n", 10); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp(path2, archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString(path2, archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(4090, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello 152\n", 10); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp(path3, archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString(path3, archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(4090, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello 153\n", 10); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("sym1", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(path1, archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("sym2", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(path2, archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("sym3", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(path3, archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else { + failure("Saw a file that shouldn't have been there"); + assertEqualString(archive_entry_pathname(ae), ""); + } + } + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + + diff --git a/lib/libarchive/test/test_read_format_isorr_new_bz2.c b/lib/libarchive/test/test_read_format_isorr_new_bz2.c new file mode 100644 index 0000000..5fa2492 --- /dev/null +++ b/lib/libarchive/test/test_read_format_isorr_new_bz2.c @@ -0,0 +1,204 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + + +/* +PLEASE use latest cdrtools at least mkisofs version is 2.01.01a63 or later. +Old version mkisofs made wrong "SL" System Use Entry of RRIP. + +Execute the following command to rebuild the data for this program: + tail -n +34 test_read_format_isorr_new_bz2.c | /bin/sh + +rm -rf /tmp/iso +mkdir /tmp/iso +mkdir /tmp/iso/dir +echo "hello" >/tmp/iso/file +dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file +ln /tmp/iso/file /tmp/iso/hardlink +(cd /tmp/iso; ln -s file symlink) +(cd /tmp/iso; ln -s /tmp/ symlink2) +(cd /tmp/iso; ln -s /tmp/../ symlink3) +(cd /tmp/iso; ln -s .././../tmp/ symlink4) +(cd /tmp/iso; ln -s .///file symlink5) +(cd /tmp/iso; ln -s /tmp//../ symlink6) +TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir +TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink +F=test_read_format_iso_rockridge_new.iso.Z +mkhybrid -R -uid 1 -gid 2 /tmp/iso | compress > $F +uuencode $F $F > $F.uu +exit 1 + */ + +DEFINE_TEST(test_read_format_isorr_new_bz2) +{ + const char *refname = "test_read_format_iso_rockridge_new.iso.Z"; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + int i; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Retrieve each of the 8 files on the ISO image and + * verify that each one is what we expect. */ + for (i = 0; i < 10; ++i) { + assertEqualInt(0, archive_read_next_header(a, &ae)); + + if (strcmp(".", archive_entry_pathname(ae)) == 0) { + /* '.' root directory. */ + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* Now, we read timestamp recorded by RRIP "TF". */ + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + /* Now, we read links recorded by RRIP "PX". */ + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString("hardlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(12345684, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello\n", 6); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { + /* A hardlink to the regular file. */ + /* Note: If "hardlink" gets returned before "file", + * then "hardlink" will get returned as a regular file + * and "file" will get returned as the hardlink. + * This test should tolerate that, since it's a + * perfectly permissible thing for libarchive to do. */ + assertEqualString("file", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualString("hardlink", archive_entry_hardlink(ae)); + assertEqualInt(0, archive_entry_size_is_set(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("file", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(172802, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp/ (an absolute path) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp/", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp/../ (with a ".." component) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp/../", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) { + /* A symlink to a path with ".." and "." components */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(".././../tmp/", + archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink5", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file with "/" components. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(".///file", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(172802, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink6", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp//../ + * (with "/" and ".." components) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp//../", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else { + failure("Saw a file that shouldn't have been there"); + assertEqualString(archive_entry_pathname(ae), ""); + } + } + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + + diff --git a/lib/libarchive/test/test_read_format_isorr_rr_moved.c b/lib/libarchive/test/test_read_format_isorr_rr_moved.c new file mode 100644 index 0000000..0aeb226 --- /dev/null +++ b/lib/libarchive/test/test_read_format_isorr_rr_moved.c @@ -0,0 +1,270 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * Copyright (c) 2009 Michihiro NAKAJIMA + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* +Execute the following command to rebuild the data for this program: + tail -n +32 test_read_format_isorr_rr_moved.c | /bin/sh + +dirname=/tmp/iso +rm -rf $dirname +mkdir -p $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10 +echo "hello" >$dirname/file +dd if=/dev/zero count=1 bs=12345678 >>$dirname/file +deepfile=$dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10/deep +echo "hello" >$deepfile +dd if=/dev/zero count=1 bs=12345678 >>$deepfile +time="197001020000.01" +TZ=utc touch -afhm -t $time $deepfile +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9/dir10 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8/dir9 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7/dir8 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6/dir7 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5/dir6 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4/dir5 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3/dir4 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2/dir3 +TZ=utc touch -afhm -t $time $dirname/dir1/dir2 +TZ=utc touch -afhm -t $time $dirname/dir1 +TZ=utc touch -afhm -t $time $dirname/file +TZ=utc touch -afhm -t $time $dirname +F=test_read_format_isorr_rockridge_moved.iso.Z +mkhybrid -R -uid 1 -gid 2 $dirname | compress > $F +uuencode $F $F > $F.uu +exit 1 + */ + +DEFINE_TEST(test_read_format_isorr_rr_moved) +{ + const char *refname = "test_read_format_iso_rockridge_rr_moved.iso.Z"; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + int i; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Retrieve each of the 8 files on the ISO image and + * verify that each one is what we expect. */ + for (i = 0; i < 13; ++i) { + assertEqualInt(0, archive_read_next_header(a, &ae)); + + if (strcmp(".", archive_entry_pathname(ae)) == 0) { + /* '.' root directory. */ + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* Now, we read timestamp recorded by RRIP "TF". */ + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + /* Now, we read links recorded by RRIP "PX". */ + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + } else if (strcmp("dir1", archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8/dir9", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8/dir9", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8/dir9/dir10", + archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8/dir9/dir10", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString("file", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(12345684, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello\n", 6); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8/dir9/dir10/deep", + archive_entry_pathname(ae)) == 0) { + /* A regular file. */ + assertEqualString("dir1/dir2/dir3/dir4/dir5/dir6/dir7" + "/dir8/dir9/dir10/deep", + archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(12345684, archive_entry_size(ae)); + assertEqualInt(0, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt(0, offset); + assertEqualMem(p, "hello\n", 6); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else { + failure("Saw a file that shouldn't have been there"); + assertEqualString(archive_entry_pathname(ae), ""); + } + } + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + + diff --git a/lib/libarchive/test/test_read_format_isozisofs_bz2.c b/lib/libarchive/test/test_read_format_isozisofs_bz2.c new file mode 100644 index 0000000..56c39c0 --- /dev/null +++ b/lib/libarchive/test/test_read_format_isozisofs_bz2.c @@ -0,0 +1,187 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* +Execute the following command to rebuild the data for this program: + tail -n +32 test_read_format_isozisofs_bz2.c | /bin/sh + +rm -rf /tmp/iso /tmp/ziso +mkdir /tmp/iso +mkdir /tmp/iso/dir +echo "hello" >/tmp/iso/file +dd if=/dev/zero count=1 bs=12345678 >>/tmp/iso/file +ln /tmp/iso/file /tmp/iso/hardlink +(cd /tmp/iso; ln -s file symlink) +(cd /tmp/iso; ln -s /tmp/ symlink2) +(cd /tmp/iso; ln -s /tmp/../ symlink3) +(cd /tmp/iso; ln -s .././../tmp/ symlink4) +TZ=utc touch -afhm -t 197001020000.01 /tmp/iso /tmp/iso/file /tmp/iso/dir +TZ=utc touch -afhm -t 197001030000.02 /tmp/iso/symlink +mkzftree /tmp/iso /tmp/ziso +TZ=utc touch -afhm -t 197001020000.01 /tmp/ziso /tmp/ziso/file /tmp/ziso/dir +TZ=utc touch -afhm -t 197001030000.02 /tmp/ziso/symlink +F=test_read_format_iso_zisofs.iso.Z +mkhybrid -R -uid 1 -gid 2 -z /tmp/ziso | compress > $F +uuencode $F $F > $F.uu +exit 1 + + */ + +DEFINE_TEST(test_read_format_isozisofs_bz2) +{ + const char *refname = "test_read_format_iso_zisofs.iso.Z"; + struct archive_entry *ae; + struct archive *a; + const void *p; + size_t size; + off_t offset; + int i; + + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualInt(0, archive_read_support_compression_all(a)); + assertEqualInt(0, archive_read_support_format_all(a)); + assertEqualInt(ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Retrieve each of the 8 files on the ISO image and + * verify that each one is what we expect. */ + for (i = 0; i < 8; ++i) { + assertEqualInt(0, archive_read_next_header(a, &ae)); + + if (strcmp(".", archive_entry_pathname(ae)) == 0) { + /* '.' root directory. */ + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + /* Now, we read timestamp recorded by RRIP "TF". */ + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + /* Now, we read links recorded by RRIP "PX". */ + assertEqualInt(3, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + } else if (strcmp("dir", archive_entry_pathname(ae)) == 0) { + /* A directory. */ + assertEqualString("dir", archive_entry_pathname(ae)); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); + assertEqualInt(2048, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("hardlink", archive_entry_pathname(ae)) == 0) { + int r; + /* A regular file. */ + assertEqualString("hardlink", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualInt(12345684, archive_entry_size(ae)); + r = archive_read_data_block(a, &p, &size, &offset); + if (r == ARCHIVE_FAILED) { + skipping("Can't read body of ZISOFS entry."); + } else { + assertEqualInt(ARCHIVE_OK, r); + assertEqualInt(0, offset); + assertEqualMem(p, "hello\n", 6); + } + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("file", archive_entry_pathname(ae)) == 0) { + /* A hardlink to the regular file. */ + /* Note: If "hardlink" gets returned before "file", + * then "hardlink" will get returned as a regular file + * and "file" will get returned as the hardlink. + * This test should tolerate that, since it's a + * perfectly permissible thing for libarchive to do. */ + assertEqualString("file", archive_entry_pathname(ae)); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); + assertEqualString("hardlink", archive_entry_hardlink(ae)); + assertEqualInt(0, archive_entry_size_is_set(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(86401, archive_entry_mtime(ae)); + assertEqualInt(86401, archive_entry_atime(ae)); + assertEqualInt(2, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink", archive_entry_pathname(ae)) == 0) { + /* A symlink to the regular file. */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("file", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(172802, archive_entry_mtime(ae)); + assertEqualInt(172802, archive_entry_atime(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink2", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp (an absolute path) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink3", archive_entry_pathname(ae)) == 0) { + /* A symlink to /tmp/.. (with a ".." component) */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString("/tmp/..", archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else if (strcmp("symlink4", archive_entry_pathname(ae)) == 0) { + /* A symlink to a path with ".." and "." components */ + assertEqualInt(AE_IFLNK, archive_entry_filetype(ae)); + assertEqualString(".././../tmp", + archive_entry_symlink(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualInt(1, archive_entry_stat(ae)->st_nlink); + assertEqualInt(1, archive_entry_uid(ae)); + assertEqualInt(2, archive_entry_gid(ae)); + } else { + failure("Saw a file that shouldn't have been there"); + assertEqualString(archive_entry_pathname(ae), ""); + } + } + + /* End of archive. */ + assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify archive format. */ + assertEqualInt(archive_compression(a), ARCHIVE_COMPRESSION_COMPRESS); + assertEqualInt(archive_format(a), ARCHIVE_FORMAT_ISO9660_ROCKRIDGE); + + /* Close the archive. */ + assertEqualInt(0, archive_read_close(a)); + assertEqualInt(0, archive_read_finish(a)); +} + + diff --git a/lib/libarchive/test/test_read_format_mtree.c b/lib/libarchive/test/test_read_format_mtree.c index b13034f..5001e4d 100644 --- a/lib/libarchive/test/test_read_format_mtree.c +++ b/lib/libarchive/test/test_read_format_mtree.c @@ -25,34 +25,16 @@ #include "test.h" __FBSDID("$FreeBSD$"); -/* Single entry with a hardlink. */ -static unsigned char archive[] = { - "#mtree\n" - "file type=file uid=18 mode=0123 size=3\n" - "dir type=dir\n" - " file\\040with\\040space type=file uid=18\n" - " ..\n" - "file\\04with\\040space type=file\n" - "dir2 type=dir\n" - " dir3a type=dir\n" - " indir3a type=file\n" - "dir2/fullindir2 type=file mode=0777\n" - " ..\n" - " indir2 type=file\n" - " dir3b type=dir\n" - " indir3b type=file\n" - " ..\n" - " ..\n" - "notindir type=file\n" - "dir2/fullindir2 mode=0644\n" -}; - -DEFINE_TEST(test_read_format_mtree) +static void +test_read_format_mtree1(void) { + const char reffile[] = "test_read_format_mtree.mtree"; char buff[16]; struct archive_entry *ae; struct archive *a; - int fd; + FILE *f; + + extract_reference_file(reffile); /* * An access error occurred on some platform when mtree @@ -60,29 +42,28 @@ DEFINE_TEST(test_read_format_mtree) * the routine which open a directory that we create * "dir" and "dir2" directories. */ - assertEqualInt(0, mkdir("dir", 0775)); - assertEqualInt(0, mkdir("dir2", 0775)); + assertMakeDir("dir", 0775); + assertMakeDir("dir2", 0775); assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_compression_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_memory(a, archive, sizeof(archive))); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_file(a, reffile, 11)); /* * Read "file", whose data is available on disk. */ - fd = open("file", O_WRONLY | O_CREAT, 0777); - assert(fd >= 0); - assertEqualInt(3, write(fd, "hi\n", 3)); - close(fd); + f = fopen("file", "wb"); + assert(f != NULL); + assertEqualInt(3, fwrite("hi\n", 1, 3, f)); + fclose(f); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_MTREE); assertEqualString(archive_entry_pathname(ae), "file"); assertEqualInt(archive_entry_uid(ae), 18); - assert(S_ISREG(archive_entry_mode(ae))); + assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); assertEqualInt(archive_entry_mode(ae), AE_IFREG | 0123); assertEqualInt(archive_entry_size(ae), 3); assertEqualInt(3, archive_read_data(a, buff, 3)); @@ -90,13 +71,13 @@ DEFINE_TEST(test_read_format_mtree) assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(archive_entry_pathname(ae), "dir"); - assert(S_ISDIR(archive_entry_mode(ae))); + assertEqualInt(AE_IFDIR, archive_entry_filetype(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(archive_entry_pathname(ae), "dir/file with space"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualString(archive_entry_pathname(ae), "file\\04with space"); + assertEqualString(archive_entry_pathname(ae), "file with space"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString(archive_entry_pathname(ae), "dir2"); @@ -125,11 +106,38 @@ DEFINE_TEST(test_read_format_mtree) assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_read_finish(a); -#else assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); -#endif } +static void +test_read_format_mtree2(void) +{ + static char archive[] = + "#mtree\n" + "d type=dir content=.\n"; + struct archive_entry *ae; + struct archive *a; + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_compression_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_format_all(a)); + 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); + assertEqualString(archive_entry_pathname(ae), "d"); + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); +} + + + +DEFINE_TEST(test_read_format_mtree) +{ + test_read_format_mtree1(); + test_read_format_mtree2(); +} diff --git a/lib/libarchive/test/test_read_format_mtree.mtree.uu b/lib/libarchive/test/test_read_format_mtree.mtree.uu new file mode 100644 index 0000000..9fa0d9b --- /dev/null +++ b/lib/libarchive/test/test_read_format_mtree.mtree.uu @@ -0,0 +1,13 @@ +$FreeBSD$ + +begin 644 test_read_format_mtree.mtree +M(VUT7!E/61I<@H@9FEL95PP-#!W:71H7#`T,'-P86-E('1Y<&4]9FEL +M92!U:60],3@*("XN"F9I;&5<,#0P=VET:%PP-#!S<&%C92!T>7!E/69I;&4* +M9&ER,B!T>7!E/61I<@H@9&ER,V$@='EP93UD:7(*("!I;F1I7!E/61I<@H@(&EN9&ER,V(@ +M='EP93UF:6QE"B`@+BX*("XN"FYO=&EN9&ER('1Y<&4]9FEL90ID:7(R+V9U +3;&QI;F1Ifilebytes > 0) { if (private->filebytes < skip) - skip = private->filebytes; + skip = (off_t)private->filebytes; private->filebytes -= skip; } else { skip = 0; diff --git a/lib/libarchive/test/test_write_compress_program.c b/lib/libarchive/test/test_write_compress_program.c index 713638e..34d0680 100644 --- a/lib/libarchive/test/test_write_compress_program.c +++ b/lib/libarchive/test/test_write_compress_program.c @@ -38,12 +38,9 @@ DEFINE_TEST(test_write_compress_program) size_t used; int blocksize = 1024; int r; - const char *compprog, *decompprog; - decompprog = external_gzip_program(1); - if ((compprog = external_gzip_program(0)) == NULL) { - skipping("There is no gzip compression " - "program in this platform"); + if (!canGzip()) { + skipping("Cannot run 'gzip'"); return; } @@ -51,7 +48,7 @@ DEFINE_TEST(test_write_compress_program) /* Write it through an external "gzip" program. */ assert((a = archive_write_new()) != NULL); assertA(0 == archive_write_set_format_ustar(a)); - r = archive_write_set_compression_program(a, compprog); + r = archive_write_set_compression_program(a, "gzip"); if (r == ARCHIVE_FATAL) { skipping("Write compression via external " "program unsupported on this platform"); @@ -91,8 +88,8 @@ DEFINE_TEST(test_write_compress_program) /* The compression_gzip() handler will fall back to gunzip * automatically, but if we know gunzip isn't available, then * skip the rest. */ - if (r != ARCHIVE_OK && decompprog == NULL) { - skipping("No gzip decompression is available; " + if (r != ARCHIVE_OK && !canGunzip()) { + skipping("No libz and no gunzip program, " "unable to verify gzip compression"); assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); return; diff --git a/lib/libarchive/test/test_write_disk.c b/lib/libarchive/test/test_write_disk.c index c0b22e5..f3f4e56 100644 --- a/lib/libarchive/test/test_write_disk.c +++ b/lib/libarchive/test/test_write_disk.c @@ -28,6 +28,14 @@ __FBSDID("$FreeBSD$"); #if ARCHIVE_VERSION_NUMBER >= 1009000 #define UMASK 022 +/* + * When comparing mode values, ignore high-order bits + * that are set on some OSes. This should cover the bits + * we're interested in (standard mode bits + file type bits) + * while ignoring extra markers such as Haiku/BeOS index + * flags. + */ +#define MODE_MASK 0777777 static void create(struct archive_entry *ae, const char *msg) { @@ -46,14 +54,15 @@ static void create(struct archive_entry *ae, const char *msg) #endif /* Test the entries on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); - failure("st.st_mode=%o archive_entry_mode(ae)=%o", - st.st_mode, archive_entry_mode(ae)); + failure("%s", msg); + +#if !defined(_WIN32) || defined(__CYGWIN__) /* When verifying a dir, ignore the S_ISGID bit, as some systems set * that automatically. */ if (archive_entry_filetype(ae) == AE_IFDIR) st.st_mode &= ~S_ISGID; -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(st.st_mode, archive_entry_mode(ae) & ~UMASK); + assertEqualInt(st.st_mode & MODE_MASK, + archive_entry_mode(ae) & ~UMASK & MODE_MASK); #endif } @@ -61,8 +70,6 @@ static void create_reg_file(struct archive_entry *ae, const char *msg) { static const char data[]="abcdefghijklmnopqrstuvwxyz"; struct archive *ad; - struct stat st; - time_t now; /* Write the entry to disk. */ assert((ad = archive_write_disk_new()) != NULL); @@ -96,28 +103,20 @@ static void create_reg_file(struct archive_entry *ae, const char *msg) assertEqualInt(0, archive_write_finish(ad)); #endif /* Test the entries on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - failure("st.st_mode=%o archive_entry_mode(ae)=%o", - st.st_mode, archive_entry_mode(ae)); -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); -#endif - assertEqualInt(st.st_size, sizeof(data)); + assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777); + assertFileSize(archive_entry_pathname(ae), sizeof(data)); /* test_write_disk_times has more detailed tests of this area. */ - assertEqualInt(st.st_mtime, 123456789); - failure("No atime was specified, so atime should get set to current time"); - now = time(NULL); - assert(st.st_atime <= now && st.st_atime > now - 5); + assertFileMtime(archive_entry_pathname(ae), 123456789, 0); + failure("No atime given, so atime should get set to current time"); + assertFileAtimeRecent(archive_entry_pathname(ae)); } static void create_reg_file2(struct archive_entry *ae, const char *msg) { const int datasize = 100000; char *data; - char *compare; struct archive *ad; - struct stat st; - int i, fd; + int i; data = malloc(datasize); for (i = 0; i < datasize; i++) @@ -137,26 +136,12 @@ static void create_reg_file2(struct archive_entry *ae, const char *msg) archive_write_data_block(ad, data + i, 1000, i)); } assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_write_finish(ad); -#else assertEqualInt(0, archive_write_finish(ad)); -#endif - /* Test the entries on disk. */ - assert(0 == stat(archive_entry_pathname(ae), &st)); - failure("st.st_mode=%o archive_entry_mode(ae)=%o", - st.st_mode, archive_entry_mode(ae)); -#if !defined(_WIN32) || defined(__CYGWIN__) - assertEqualInt(st.st_mode, (archive_entry_mode(ae) & ~UMASK)); -#endif - assertEqualInt(st.st_size, i); - compare = malloc(datasize); - fd = open(archive_entry_pathname(ae), O_RDONLY); - assertEqualInt(datasize, read(fd, compare, datasize)); - close(fd); - assert(memcmp(compare, data, datasize) == 0); - free(compare); + /* Test the entries on disk. */ + assertIsReg(archive_entry_pathname(ae), archive_entry_mode(ae) & 0777); + assertFileSize(archive_entry_pathname(ae), i); + assertFileContents(data, datasize, archive_entry_pathname(ae)); free(data); } @@ -268,7 +253,7 @@ DEFINE_TEST(test_write_disk) struct archive_entry *ae; /* Force the umask to something predictable. */ - umask(UMASK); + assertUmask(UMASK); /* A regular file. */ assert((ae = archive_entry_new()) != NULL); diff --git a/lib/libarchive/test/test_write_disk_failures.c b/lib/libarchive/test/test_write_disk_failures.c index 1befbac..f74c947 100644 --- a/lib/libarchive/test/test_write_disk_failures.c +++ b/lib/libarchive/test/test_write_disk_failures.c @@ -42,13 +42,13 @@ DEFINE_TEST(test_write_disk_failures) int fd; /* Force the umask to something predictable. */ - umask(UMASK); + assertUmask(UMASK); /* A directory that we can't write to. */ - assertEqualInt(0, mkdir("dir", 0555)); + assertMakeDir("dir", 0555); /* Can we? */ - fd = open("dir/testfile", O_WRONLY | O_CREAT, 0777); + fd = open("dir/testfile", O_WRONLY | O_CREAT | O_BINARY, 0777); if (fd >= 0) { /* Apparently, we can, so the test below won't work. */ close(fd); diff --git a/lib/libarchive/test/test_write_disk_hardlink.c b/lib/libarchive/test/test_write_disk_hardlink.c index 2ab2420..5756602 100644 --- a/lib/libarchive/test/test_write_disk_hardlink.c +++ b/lib/libarchive/test/test_write_disk_hardlink.c @@ -43,16 +43,16 @@ __FBSDID("$FreeBSD$"); */ DEFINE_TEST(test_write_disk_hardlink) { -#if ARCHIVE_VERSION_NUMBER < 1009000 - skipping("archive_write_disk_hardlink tests"); +#if defined(__HAIKU__) + skipping("archive_write_disk_hardlink; hardlinks are not supported on bfs"); #else static const char data[]="abcdefghijklmnopqrstuvwxyz"; struct archive *ad; struct archive_entry *ae; - struct stat st, st2; + int r; /* Force the umask to something predictable. */ - umask(UMASK); + assertUmask(UMASK); /* Write entries to disk. */ assert((ad = archive_write_disk_new()) != NULL); @@ -79,10 +79,12 @@ DEFINE_TEST(test_write_disk_hardlink) archive_entry_set_mode(ae, S_IFREG | 0642); archive_entry_set_size(ae, 0); archive_entry_copy_hardlink(ae, "link1a"); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); + if (r >= ARCHIVE_WARN) { + assertEqualInt(ARCHIVE_WARN, + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + } archive_entry_free(ae); /* @@ -107,10 +109,12 @@ DEFINE_TEST(test_write_disk_hardlink) archive_entry_set_mode(ae, S_IFREG | 0642); archive_entry_unset_size(ae); archive_entry_copy_hardlink(ae, "link2a"); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(ARCHIVE_WARN, - archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); + if (r >= ARCHIVE_WARN) { + assertEqualInt(ARCHIVE_WARN, + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + } archive_entry_free(ae); /* @@ -134,9 +138,12 @@ DEFINE_TEST(test_write_disk_hardlink) archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); archive_entry_copy_hardlink(ae, "link3a"); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); + if (r > ARCHIVE_WARN) { + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + } archive_entry_free(ae); /* @@ -164,34 +171,26 @@ DEFINE_TEST(test_write_disk_hardlink) archive_entry_set_mode(ae, S_IFREG | 0755); archive_entry_set_size(ae, sizeof(data)); archive_entry_copy_hardlink(ae, "link4a"); - assertEqualIntA(ad, 0, archive_write_header(ad, ae)); - assertEqualInt(sizeof(data), archive_write_data(ad, data, sizeof(data))); - assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); + if (r > ARCHIVE_FAILED) { + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + } archive_entry_free(ae); -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_write_finish(ad); -#else assertEqualInt(0, archive_write_finish(ad)); -#endif /* Test the entries on disk. */ /* Test #1 */ - assert(0 == stat("link1a", &st)); /* If the hardlink was successfully created and the archive * doesn't carry data for it, we consider it to be * non-authoritive for meta data as well. This is consistent * with GNU tar and BSD pax. */ - assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st.st_size, sizeof(data)); - assertEqualInt(st.st_nlink, 2); - - assert(0 == stat("link1b", &st2)); - assertEqualInt(st.st_mode, st2.st_mode); - assertEqualInt(st.st_size, st2.st_size); - assertEqualInt(st.st_nlink, st2.st_nlink); - assertEqualInt(st.st_ino, st2.st_ino); - assertEqualInt(st.st_dev, st2.st_dev); + assertIsReg("link1a", 0755 & ~UMASK); + assertFileSize("link1a", sizeof(data)); + assertFileNLinks("link1a", 2); + assertIsHardlink("link1a", "link1b"); /* Test #2: Should produce identical results to test #1 */ /* Note that marking a hardlink with size = 0 is treated the @@ -200,42 +199,21 @@ DEFINE_TEST(test_write_disk_hardlink) * relied on size == 0) and partly to match the model used by * common file formats that store a size of zero for * hardlinks. */ - assert(0 == stat("link2a", &st)); - assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st.st_size, sizeof(data)); - assertEqualInt(st.st_nlink, 2); - - assert(0 == stat("link2b", &st2)); - assertEqualInt(st.st_mode, st2.st_mode); - assertEqualInt(st.st_size, st2.st_size); - assertEqualInt(st.st_nlink, st2.st_nlink); - assertEqualInt(st.st_ino, st2.st_ino); - assertEqualInt(st.st_dev, st2.st_dev); + assertIsReg("link2a", 0755 & ~UMASK); + assertFileSize("link2a", sizeof(data)); + assertFileNLinks("link2a", 2); + assertIsHardlink("link2a", "link2b"); /* Test #3 */ - assert(0 == stat("link3a", &st)); - assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st.st_size, sizeof(data)); - assertEqualInt(st.st_nlink, 2); - - assert(0 == stat("link3b", &st2)); - assertEqualInt(st2.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st2.st_size, sizeof(data)); - assertEqualInt(st2.st_nlink, 2); - assertEqualInt(st.st_ino, st2.st_ino); - assertEqualInt(st.st_dev, st2.st_dev); + assertIsReg("link3a", 0755 & ~UMASK); + assertFileSize("link3a", sizeof(data)); + assertFileNLinks("link3a", 2); + assertIsHardlink("link3a", "link3b"); /* Test #4 */ - assert(0 == stat("link4a", &st)); - assertEqualInt(st.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st.st_size, sizeof(data)); - assertEqualInt(st.st_nlink, 2); - - assert(0 == stat("link4b", &st2)); - assertEqualInt(st2.st_mode & E_MASK, (S_IFREG | 0755) & ~UMASK); - assertEqualInt(st2.st_size, sizeof(data)); - assertEqualInt(st2.st_nlink, 2); - assertEqualInt(st.st_ino, st2.st_ino); - assertEqualInt(st.st_dev, st2.st_dev); + assertIsReg("link4a", 0755 & ~UMASK); + assertFileNLinks("link4a", 2); + assertFileSize("link4a", sizeof(data)); + assertIsHardlink("link4a", "link4b"); #endif } diff --git a/lib/libarchive/test/test_write_disk_perms.c b/lib/libarchive/test/test_write_disk_perms.c index 3d9be27..f53ce19 100644 --- a/lib/libarchive/test/test_write_disk_perms.c +++ b/lib/libarchive/test/test_write_disk_perms.c @@ -60,7 +60,7 @@ searchgid(void) _searched = 1; /* Create a file on disk in the current default dir. */ - fd = open("test_gid", O_CREAT, 0664); + fd = open("test_gid", O_CREAT | O_BINARY, 0664); failure("Couldn't create a file for gid testing."); assert(fd > 0); @@ -132,6 +132,8 @@ DEFINE_TEST(test_write_disk_perms) struct archive_entry *ae; struct stat st; + assertUmask(UMASK); + /* * Set ownership of the current directory to the group of this * process. Otherwise, the SGID tests below fail if the @@ -182,7 +184,7 @@ DEFINE_TEST(test_write_disk_perms) /* Overwrite an existing dir. */ /* For dir, the first perms should get left. */ - assert(mkdir("dir_overwrite_0744", 0744) == 0); + assertMakeDir("dir_overwrite_0744", 0744); /* Check original perms. */ assert(0 == stat("dir_overwrite_0744", &st)); failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); diff --git a/lib/libarchive/test/test_write_disk_secure.c b/lib/libarchive/test/test_write_disk_secure.c index d417489..74506f1 100644 --- a/lib/libarchive/test/test_write_disk_secure.c +++ b/lib/libarchive/test/test_write_disk_secure.c @@ -36,13 +36,13 @@ DEFINE_TEST(test_write_disk_secure) { #if ARCHIVE_VERSION_NUMBER < 1009000 skipping("archive_write_disk interface"); -#else +#elif !defined(_WIN32) || defined(__CYGWIN__) struct archive *a; struct archive_entry *ae; struct stat st; /* Start with a known umask. */ - umask(UMASK); + assertUmask(UMASK); /* Create an archive_write_disk object. */ assert((a = archive_write_disk_new()) != NULL); @@ -55,7 +55,6 @@ DEFINE_TEST(test_write_disk_secure) archive_entry_free(ae); assert(0 == archive_write_finish_entry(a)); -#if !defined(_WIN32) || defined(__CYGWIN__) /* Write a symlink to the dir above. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "link_to_dir"); @@ -150,7 +149,6 @@ DEFINE_TEST(test_write_disk_secure) assertEqualInt(0, lstat("link_to_dir4", &st)); assert(S_ISDIR(st.st_mode)); archive_entry_free(ae); -#endif /* * As above, but a link to a non-dir, so the link should get replaced. @@ -180,14 +178,8 @@ DEFINE_TEST(test_write_disk_secure) assert(S_ISDIR(st.st_mode)); archive_entry_free(ae); - -#if ARCHIVE_VERSION_NUMBER < 2000000 - archive_write_finish(a); -#else assert(0 == archive_write_finish(a)); -#endif -#if !defined(_WIN32) || defined(__CYGWIN__) /* Test the entries on disk. */ assert(0 == lstat("dir", &st)); failure("dir: st.st_mode=%o", st.st_mode); @@ -220,5 +212,4 @@ DEFINE_TEST(test_write_disk_secure) failure("link_to_dir2/filec: st.st_mode=%o", st.st_mode); assert((st.st_mode & 07777) == 0755); #endif -#endif } diff --git a/lib/libarchive/test/test_write_disk_sparse.c b/lib/libarchive/test/test_write_disk_sparse.c index c9c00d3..b613f56 100644 --- a/lib/libarchive/test/test_write_disk_sparse.c +++ b/lib/libarchive/test/test_write_disk_sparse.c @@ -40,7 +40,7 @@ verify_write_data(struct archive *a, int sparse) size_t buff_size = 64 * 1024; char *buff, *p; const char *msg = sparse ? "sparse" : "non-sparse"; - int fd; + FILE *f; buff = malloc(buff_size); assert(buff != NULL); @@ -78,12 +78,12 @@ verify_write_data(struct archive *a, int sparse) /* Test the entry on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); assertEqualInt(st.st_size, 8 * buff_size); - fd = open(archive_entry_pathname(ae), O_RDONLY); - if (!assert(fd >= 0)) + f = fopen(archive_entry_pathname(ae), "rb"); + if (!assert(f != NULL)) return; /* Check first block. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); failure("%s", msg); assertEqualMem(buff, data, sizeof(data)); for (p = buff + sizeof(data); p < buff + buff_size; ++p) { @@ -93,7 +93,7 @@ verify_write_data(struct archive *a, int sparse) } /* Check second block. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); for (p = buff; p < buff + buff_size; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (p == buff + buff_size / 2 - 3) { @@ -104,7 +104,7 @@ verify_write_data(struct archive *a, int sparse) } /* Check third block. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); for (p = buff; p < buff + buff_size - sizeof(data); ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) @@ -115,7 +115,7 @@ verify_write_data(struct archive *a, int sparse) /* XXX more XXX */ - assertEqualInt(0, close(fd)); + assertEqualInt(0, fclose(f)); archive_entry_free(ae); free(buff); } @@ -132,7 +132,7 @@ verify_write_data_block(struct archive *a, int sparse) size_t buff_size = 64 * 1024; char *buff, *p; const char *msg = sparse ? "sparse" : "non-sparse"; - int fd; + FILE *f; buff = malloc(buff_size); assert(buff != NULL); @@ -174,12 +174,12 @@ verify_write_data_block(struct archive *a, int sparse) /* Test the entry on disk. */ assert(0 == stat(archive_entry_pathname(ae), &st)); assertEqualInt(st.st_size, 8 * buff_size); - fd = open(archive_entry_pathname(ae), O_RDONLY); - if (!assert(fd >= 0)) + f = fopen(archive_entry_pathname(ae), "rb"); + if (!assert(f != NULL)) return; /* Check 100-byte gap at beginning */ - assertEqualInt(100, read(fd, buff, 100)); + assertEqualInt(100, fread(buff, 1, 100, f)); failure("%s", msg); for (p = buff; p < buff + 100; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); @@ -188,7 +188,7 @@ verify_write_data_block(struct archive *a, int sparse) } /* Check first block. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); failure("%s", msg); assertEqualMem(buff, data, sizeof(data)); for (p = buff + sizeof(data); p < buff + buff_size; ++p) { @@ -198,7 +198,7 @@ verify_write_data_block(struct archive *a, int sparse) } /* Check 100-byte gap */ - assertEqualInt(100, read(fd, buff, 100)); + assertEqualInt(100, fread(buff, 1, 100, f)); failure("%s", msg); for (p = buff; p < buff + 100; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); @@ -207,7 +207,7 @@ verify_write_data_block(struct archive *a, int sparse) } /* Check second block. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); for (p = buff; p < buff + buff_size; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (p == buff + buff_size / 2 - 3) { @@ -218,7 +218,7 @@ verify_write_data_block(struct archive *a, int sparse) } /* Check 100-byte gap */ - assertEqualInt(100, read(fd, buff, 100)); + assertEqualInt(100, fread(buff, 1, 100, f)); failure("%s", msg); for (p = buff; p < buff + 100; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); @@ -227,7 +227,7 @@ verify_write_data_block(struct archive *a, int sparse) } /* Check third block. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); for (p = buff; p < buff + buff_size - sizeof(data); ++p) { failure("offset: %d, %s", (int)(p - buff), msg); if (!assertEqualInt(0, *p)) @@ -237,7 +237,7 @@ verify_write_data_block(struct archive *a, int sparse) assertEqualMem(buff + buff_size - sizeof(data), data, sizeof(data)); /* Check another block size beyond last we wrote. */ - assertEqualInt(buff_size, read(fd, buff, buff_size)); + assertEqualInt(buff_size, fread(buff, 1, buff_size, f)); failure("%s", msg); for (p = buff; p < buff + buff_size; ++p) { failure("offset: %d, %s", (int)(p - buff), msg); @@ -248,7 +248,7 @@ verify_write_data_block(struct archive *a, int sparse) /* XXX more XXX */ - assertEqualInt(0, close(fd)); + assertEqualInt(0, fclose(f)); free(buff); archive_entry_free(ae); } diff --git a/lib/libarchive/test/test_write_disk_symlink.c b/lib/libarchive/test/test_write_disk_symlink.c new file mode 100644 index 0000000..861f3bf --- /dev/null +++ b/lib/libarchive/test/test_write_disk_symlink.c @@ -0,0 +1,117 @@ +/*- + * Copyright (c) 2003-2007 Tim Kientzle + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include "test.h" +__FBSDID("$FreeBSD$"); + +/* + * Exercise symlink recreation. + */ +DEFINE_TEST(test_write_disk_symlink) +{ + static const char data[]="abcdefghijklmnopqrstuvwxyz"; + struct archive *ad; + struct archive_entry *ae; + int r; + + if (!canSymlink()) { + skipping("Symlinks not supported"); + return; + } + + /* Write entries to disk. */ + assert((ad = archive_write_disk_new()) != NULL); + + /* + * First, create a regular file then a symlink to that file. + */ + + /* Regular file: link1a */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link1a"); + archive_entry_set_mode(ae, AE_IFREG | 0755); + archive_entry_set_size(ae, sizeof(data)); + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + + /* Symbolic Link: link1b -> link1a */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link1b"); + archive_entry_set_mode(ae, AE_IFLNK | 0642); + archive_entry_set_size(ae, 0); + archive_entry_copy_symlink(ae, "link1a"); + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); + if (r >= ARCHIVE_WARN) + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + + /* + * We should be able to do this in the other order as well, + * of course. + */ + + /* Symbolic link: link2b -> link2a */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link2b"); + archive_entry_set_mode(ae, AE_IFLNK | 0642); + archive_entry_unset_size(ae); + archive_entry_copy_symlink(ae, "link2a"); + assertEqualIntA(ad, 0, r = archive_write_header(ad, ae)); + if (r >= ARCHIVE_WARN) { + assertEqualInt(ARCHIVE_WARN, + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + } + archive_entry_free(ae); + + /* File: link2a */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "link2a"); + archive_entry_set_mode(ae, AE_IFREG | 0755); + archive_entry_set_size(ae, sizeof(data)); + assertEqualIntA(ad, 0, archive_write_header(ad, ae)); + assertEqualInt(sizeof(data), + archive_write_data(ad, data, sizeof(data))); + assertEqualIntA(ad, 0, archive_write_finish_entry(ad)); + archive_entry_free(ae); + + assertEqualInt(ARCHIVE_OK, archive_write_finish(ad)); + + /* Test the entries on disk. */ + + /* Test #1 */ + assertIsReg("link1a", -1); + assertFileSize("link1a", sizeof(data)); + assertFileNLinks("link1a", 1); + assertIsSymlink("link1b", "link1a"); + + /* Test #2: Should produce identical results to test #1 */ + assertIsReg("link2a", -1); + assertFileSize("link2a", sizeof(data)); + assertFileNLinks("link2a", 1); + assertIsSymlink("link2b", "link2a"); +} diff --git a/lib/libarchive/test/test_write_disk_times.c b/lib/libarchive/test/test_write_disk_times.c index 2891e36..13841cf 100644 --- a/lib/libarchive/test/test_write_disk_times.c +++ b/lib/libarchive/test/test_write_disk_times.c @@ -35,8 +35,6 @@ DEFINE_TEST(test_write_disk_times) { struct archive *a; struct archive_entry *ae; - struct stat st; - time_t now = time(NULL); /* Create an archive_write_disk object. */ assert((a = archive_write_disk_new()) != NULL); @@ -55,9 +53,8 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify */ - assertEqualInt(0, stat("file1", &st)); - assertEqualInt(123456, st.st_atime); - assertEqualInt(234567, st.st_mtime); + assertFileAtime("file1", 123456, 0); + assertFileMtime("file1", 234567, 0); /* * mtime specified, but not atime @@ -69,11 +66,8 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); - /* Verify: Current atime and mtime as specified. */ - assertEqualInt(0, stat("file2", &st)); - assertEqualInt(234567, st.st_mtime); - failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime); - assert(st.st_atime >= now && st.st_atime < now + 3); + assertFileMtime("file2", 234567, 0); + assertFileAtimeRecent("file2"); /* * atime specified, but not mtime @@ -86,10 +80,8 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify: Current mtime and atime as specified. */ - assertEqualInt(0, stat("file3", &st)); - assertEqualInt(345678, st.st_atime); - failure("now: %ld st.st_mtime: %ld", (long)now, (long)st.st_mtime); - assert(st.st_mtime >= now && st.st_mtime < now + 3); + assertFileAtime("file3", 345678, 0); + assertFileMtimeRecent("file3"); /* * Neither atime nor mtime specified. @@ -101,11 +93,8 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify: Current mtime and atime. */ - assertEqualInt(0, stat("file4", &st)); - failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime); - assert(st.st_atime >= now && st.st_atime < now + 3); - failure("now: %ld st.st_mtime: %ld", (long)now, (long)st.st_mtime); - assert(st.st_mtime >= now && st.st_mtime < now + 3); + assertFileAtimeRecent("file4"); + assertFileMtimeRecent("file4"); #if defined(__FreeBSD__) /* @@ -120,12 +109,8 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify */ - /* FreeBSD can only store usec resolution, hence rounding here. */ - assertEqualInt(0, stat("file10", &st)); - assertEqualInt(1234567, st.st_atime); - assertEqualInt(23000, st.st_atimespec.tv_nsec); - assertEqualInt(2345678, st.st_mtime); - assertEqualInt(4000, st.st_mtimespec.tv_nsec); + assertFileMtime("file10", 2345678, 4567); + assertFileAtime("file10", 1234567, 23456); /* * Birthtime, mtime and atime on FreeBSD @@ -141,14 +126,9 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify */ - /* FreeBSD can only store usec resolution, hence rounding here. */ - assertEqualInt(0, stat("file11", &st)); - assertEqualInt(1234567, st.st_atime); - assertEqualInt(23000, st.st_atimespec.tv_nsec); - assertEqualInt(3456789, st.st_birthtime); - assertEqualInt(12000, st.st_birthtimespec.tv_nsec); - assertEqualInt(12345678, st.st_mtime); - assertEqualInt(4000, st.st_mtimespec.tv_nsec); + assertFileAtime("file11", 1234567, 23456); + assertFileBirthtime("file11", 3456789, 12345); + assertFileMtime("file11", 12345678, 4567); /* * Birthtime only on FreeBSD. @@ -161,14 +141,9 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify */ - /* FreeBSD can only store usec resolution, hence rounding here. */ - assertEqualInt(0, stat("file12", &st)); - assertEqualInt(3456789, st.st_birthtime); - assertEqualInt(12000, st.st_birthtimespec.tv_nsec); - failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime); - assert(st.st_atime >= now && st.st_atime < now + 3); - failure("now: %ld st.st_mtime: %ld", (long)now, (long)st.st_mtime); - assert(st.st_mtime >= now && st.st_mtime < now + 3); + assertFileAtimeRecent("file12"); + assertFileBirthtime("file12", 3456789, 12345); + assertFileMtimeRecent("file12"); /* * mtime only on FreeBSD. @@ -181,14 +156,9 @@ DEFINE_TEST(test_write_disk_times) assertEqualInt(ARCHIVE_OK, archive_write_finish_entry(a)); archive_entry_free(ae); /* Verify */ - /* FreeBSD can only store usec resolution, hence rounding here. */ - assertEqualInt(0, stat("file13", &st)); - assertEqualInt(4567890, st.st_birthtime); - assertEqualInt(23000, st.st_birthtimespec.tv_nsec); - assertEqualInt(4567890, st.st_mtime); - assertEqualInt(23000, st.st_mtimespec.tv_nsec); - failure("now: %ld st.st_atime: %ld", (long)now, (long)st.st_atime); - assert(st.st_atime >= now && st.st_atime < now + 3); + assertFileAtimeRecent("file13"); + assertFileBirthtime("file13", 4567890, 23456); + assertFileMtime("file13", 4567890, 23456); #else skipping("Platform-specific time restore tests"); #endif diff --git a/lib/libarchive/test/test_write_format_cpio_empty.c b/lib/libarchive/test/test_write_format_cpio_empty.c index 81f17a4..fed26ec0 100644 --- a/lib/libarchive/test/test_write_format_cpio_empty.c +++ b/lib/libarchive/test/test_write_format_cpio_empty.c @@ -71,5 +71,5 @@ DEFINE_TEST(test_write_format_cpio_empty) failure("Empty cpio archive should be exactly 87 bytes, was %d.", used); assert(used == 87); failure("Empty cpio archive is incorrectly formatted."); - assert(memcmp(buff, ref, 87) == 0); + assertEqualMem(buff, ref, 87); } diff --git a/lib/libarchive/test/test_write_format_cpio_newc.c b/lib/libarchive/test/test_write_format_cpio_newc.c index 512df74..447d111 100644 --- a/lib/libarchive/test/test_write_format_cpio_newc.c +++ b/lib/libarchive/test/test_write_format_cpio_newc.c @@ -52,7 +52,7 @@ DEFINE_TEST(test_write_format_cpio_newc) { struct archive *a; struct archive_entry *entry; - char *buff, *e; + char *buff, *e, *file; size_t buffsize = 100000; size_t used; @@ -99,7 +99,8 @@ DEFINE_TEST(test_write_format_cpio_newc) assert((entry = archive_entry_new()) != NULL); archive_entry_set_mtime(entry, 3, 30); archive_entry_set_pathname(entry, "lnk"); - archive_entry_set_mode(entry, S_IFLNK | 0664); + archive_entry_set_mode(entry, 0664); + archive_entry_set_filetype(entry, AE_IFLNK); archive_entry_set_size(entry, 0); archive_entry_set_uid(entry, 83); archive_entry_set_gid(entry, 93); @@ -123,9 +124,10 @@ DEFINE_TEST(test_write_format_cpio_newc) e = buff; /* First entry is "file" */ + file = e; assert(is_hex(e, 110)); /* Entire header is hex digits. */ assertEqualMem(e + 0, "070701", 6); /* Magic */ - assertEqualMem(e + 6, "00000059", 8); /* ino */ + assert(memcmp(e + 6, "00000000", 8) != 0); /* ino != 0 */ assertEqualMem(e + 14, "000081b4", 8); /* Mode */ assertEqualMem(e + 22, "00000050", 8); /* uid */ assertEqualMem(e + 30, "0000005a", 8); /* gid */ @@ -166,7 +168,8 @@ DEFINE_TEST(test_write_format_cpio_newc) /* Third entry is "lnk" */ assert(is_hex(e, 110)); /* Entire header is hex digits. */ assertEqualMem(e + 0, "070701", 6); /* Magic */ - assertEqualMem(e + 6, "00000058", 8); /* ino */ + assert(memcmp(e + 6, file + 6, 8) != 0); /* ino != file ino */ + assert(memcmp(e + 6, "00000000", 8) != 0); /* ino != 0 */ assertEqualMem(e + 14, "0000a1b4", 8); /* Mode */ assertEqualMem(e + 22, "00000053", 8); /* uid */ assertEqualMem(e + 30, "0000005d", 8); /* gid */ diff --git a/lib/libarchive/test/test_write_format_cpio_odc.c b/lib/libarchive/test/test_write_format_cpio_odc.c index 73cc3e6..309e003 100644 --- a/lib/libarchive/test/test_write_format_cpio_odc.c +++ b/lib/libarchive/test/test_write_format_cpio_odc.c @@ -46,7 +46,7 @@ DEFINE_TEST(test_write_format_cpio_odc) { struct archive *a; struct archive_entry *entry; - char *buff, *e; + char *buff, *e, *file; size_t buffsize = 100000; size_t used; @@ -109,7 +109,8 @@ DEFINE_TEST(test_write_format_cpio_odc) assert((entry = archive_entry_new()) != NULL); archive_entry_set_mtime(entry, 3, 30); archive_entry_set_pathname(entry, "symlink"); - archive_entry_set_mode(entry, S_IFLNK | 0664); + archive_entry_set_mode(entry, 0664); + archive_entry_set_filetype(entry, AE_IFLNK); archive_entry_set_symlink(entry,"file"); archive_entry_set_size(entry, 0); archive_entry_set_uid(entry, 88); @@ -130,14 +131,29 @@ DEFINE_TEST(test_write_format_cpio_odc) /* * Verify the archive format. + * + * Notes on the ino validation: cpio does not actually require + * that the ino values written to the archive match those read + * from disk. It really requires that: + * * matching non-zero ino values be written as matching + * non-zero values + * * non-matching non-zero ino values be written as non-matching + * non-zero values + * Libarchive further ensures that zero ino values get written + * as zeroes. This allows the cpio writer to generate + * synthetic ino values for the archive that may be different + * than those on disk in order to avoid problems due to truncation. + * This is especially needed for odc (POSIX format) that + * only supports 18-bit ino values. */ e = buff; /* "file" */ + file = e; /* Remember where this starts... */ assert(is_octal(e, 76)); /* Entire header is octal digits. */ assertEqualMem(e + 0, "070707", 6); /* Magic */ assertEqualMem(e + 6, "000014", 6); /* dev */ - assertEqualMem(e + 12, "000131", 6); /* ino */ + assert(memcmp(e + 12, "000000", 6) != 0); /* ino must be != 0 */ assertEqualMem(e + 18, "100664", 6); /* Mode */ assertEqualMem(e + 24, "000120", 6); /* uid */ assertEqualMem(e + 30, "000132", 6); /* gid */ @@ -154,7 +170,7 @@ DEFINE_TEST(test_write_format_cpio_odc) assert(is_octal(e, 76)); /* Entire header is octal digits. */ assertEqualMem(e + 0, "070707", 6); /* Magic */ assertEqualMem(e + 6, "000014", 6); /* dev */ - assertEqualMem(e + 12, "000131", 6); /* ino */ + assertEqualMem(e + 12, file + 12, 6); /* ino must match above */ assertEqualMem(e + 18, "100664", 6); /* Mode */ assertEqualMem(e + 24, "000120", 6); /* uid */ assertEqualMem(e + 30, "000132", 6); /* gid */ @@ -187,7 +203,8 @@ DEFINE_TEST(test_write_format_cpio_odc) assert(is_octal(e, 76)); /* Entire header is octal digits. */ assertEqualMem(e + 0, "070707", 6); /* Magic */ assertEqualMem(e + 6, "000014", 6); /* dev */ - assertEqualMem(e + 12, "000132", 6); /* ino */ + assert(memcmp(e + 12, file + 12, 6) != 0); /* ino must != file ino */ + assert(memcmp(e + 12, "000000", 6) != 0); /* ino must != 0 */ assertEqualMem(e + 18, "120664", 6); /* Mode */ assertEqualMem(e + 24, "000130", 6); /* uid */ assertEqualMem(e + 30, "000142", 6); /* gid */ diff --git a/lib/libarchive/test/test_write_format_tar_ustar.c b/lib/libarchive/test/test_write_format_tar_ustar.c index 3adacb4..f66fd7a 100644 --- a/lib/libarchive/test/test_write_format_tar_ustar.c +++ b/lib/libarchive/test/test_write_format_tar_ustar.c @@ -133,7 +133,8 @@ DEFINE_TEST(test_write_format_tar_ustar) assert((entry = archive_entry_new()) != NULL); archive_entry_set_mtime(entry, 3, 30); archive_entry_set_pathname(entry, "symlink"); - archive_entry_set_mode(entry, S_IFLNK | 0664); + archive_entry_set_mode(entry, 0664); + archive_entry_set_filetype(entry, AE_IFLNK); archive_entry_set_symlink(entry,"file"); archive_entry_set_size(entry, 0); archive_entry_set_uid(entry, 88); diff --git a/lib/libarchive/test/test_write_format_zip.c b/lib/libarchive/test/test_write_format_zip.c new file mode 100644 index 0000000..f4c51f3 --- /dev/null +++ b/lib/libarchive/test/test_write_format_zip.c @@ -0,0 +1,180 @@ +/*- + * Copyright (c) 2003-2008 Tim Kientzle + * Copyright (c) 2008 Anselm Strauss + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Development supported by Google Summer of Code 2008. + */ + +/* TODO: reader does not yet restore permissions. */ + +#include "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_write_format_zip) +{ + char filedata[64]; + struct archive_entry *ae; + struct archive *a; + size_t used; + size_t buffsize = 1000000; + char *buff; + const char *compression_type; + + buff = malloc(buffsize); + + /* Create a new archive in memory. */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_zip(a)); +#ifdef HAVE_ZLIB_H + compression_type = "zip:compression=deflate"; +#else + compression_type = "zip:compression=store"; +#endif + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_format_options(a, compression_type)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_compression_none(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_open_memory(a, buff, buffsize, &used)); + + /* + * Write a file to it. + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_mtime(ae, 1, 10); + assertEqualInt(1, archive_entry_mtime(ae)); + assertEqualInt(10, archive_entry_mtime_nsec(ae)); + archive_entry_copy_pathname(ae, "file"); + assertEqualString("file", archive_entry_pathname(ae)); + archive_entry_set_mode(ae, S_IFREG | 0755); + assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); + archive_entry_set_size(ae, 8); + + assertEqualInt(0, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualInt(8, archive_write_data(a, "12345678", 9)); + assertEqualInt(0, archive_write_data(a, "1", 1)); + + /* + * Write another file to it. + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_mtime(ae, 1, 10); + assertEqualInt(1, archive_entry_mtime(ae)); + assertEqualInt(10, archive_entry_mtime_nsec(ae)); + archive_entry_copy_pathname(ae, "file2"); + assertEqualString("file2", archive_entry_pathname(ae)); + archive_entry_set_mode(ae, S_IFREG | 0755); + assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); + archive_entry_set_size(ae, 4); + + assertEqualInt(ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualInt(4, archive_write_data(a, "1234", 5)); + + /* + * Write a directory to it. + */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_mtime(ae, 11, 110); + archive_entry_copy_pathname(ae, "dir"); + archive_entry_set_mode(ae, S_IFDIR | 0755); + archive_entry_set_size(ae, 512); + + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + failure("size should be zero so that applications know not to write"); + assertEqualInt(0, archive_entry_size(ae)); + archive_entry_free(ae); + assertEqualIntA(a, 0, archive_write_data(a, "12345678", 9)); + + /* Close out the archive. */ + assertEqualInt(ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_finish(a)); + + /* + * Now, read the data back. + */ + ae = NULL; + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_compression_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used)); + + /* + * Read and verify first file. + */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualInt(1, archive_entry_mtime(ae)); + /* Zip doesn't store high-resolution mtime. */ + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + assertEqualInt(0, archive_entry_atime(ae)); + assertEqualInt(0, archive_entry_ctime(ae)); + assertEqualString("file", archive_entry_pathname(ae)); + //assertEqualInt((S_IFREG | 0755), archive_entry_mode(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualIntA(a, 8, + archive_read_data(a, filedata, sizeof(filedata))); + assertEqualMem(filedata, "12345678", 8); + + + /* + * Read the second file back. + */ + if (!assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae))){ + free(buff); + return; + } + assertEqualInt(1, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + assertEqualInt(0, archive_entry_atime(ae)); + assertEqualInt(0, archive_entry_ctime(ae)); + assertEqualString("file2", archive_entry_pathname(ae)); + //assert((S_IFREG | 0755) == archive_entry_mode(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualIntA(a, 4, + archive_read_data(a, filedata, sizeof(filedata))); + assertEqualMem(filedata, "1234", 4); + + /* + * Read the dir entry back. + */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualInt(11, archive_entry_mtime(ae)); + assertEqualInt(0, archive_entry_mtime_nsec(ae)); + assertEqualInt(0, archive_entry_atime(ae)); + assertEqualInt(0, archive_entry_ctime(ae)); + assertEqualString("dir/", archive_entry_pathname(ae)); + //assertEqualInt((S_IFDIR | 0755), archive_entry_mode(ae)); + assertEqualInt(0, archive_entry_size(ae)); + assertEqualIntA(a, 0, archive_read_data(a, filedata, 10)); + + /* Verify the end of the archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_finish(a)); + free(buff); +} diff --git a/lib/libarchive/test/test_write_format_zip_empty.c b/lib/libarchive/test/test_write_format_zip_empty.c new file mode 100644 index 0000000..ef90b8d --- /dev/null +++ b/lib/libarchive/test/test_write_format_zip_empty.c @@ -0,0 +1,56 @@ +/*- + * Copyright (c) 2008 Anselm Strauss + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Development supported by Google Summer of Code 2008. + */ + +#include "test.h" +__FBSDID("$FreeBSD$"); + +DEFINE_TEST(test_write_format_zip_empty) +{ + struct archive *a; + char buff[256]; + size_t used; + + /* Zip format: Create a new archive in memory. */ + assert((a = archive_write_new()) != NULL); + assertA(0 == archive_write_set_format_zip(a)); + assertA(0 == archive_write_set_compression_none(a)); + assertA(0 == archive_write_set_bytes_per_block(a, 1)); + assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); + assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); + + /* Close out the archive without writing anything. */ + assertA(0 == archive_write_close(a)); + assertA(0 == archive_write_finish(a)); + + /* Verify the correct format for an empy Zip archive. */ + assertEqualInt(used, 22); + assertEqualMem(buff, + "PK\005\006\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", + 22); +} diff --git a/lib/libarchive/test/test_write_format_zip_no_compression.c b/lib/libarchive/test/test_write_format_zip_no_compression.c new file mode 100644 index 0000000..63e76b6 --- /dev/null +++ b/lib/libarchive/test/test_write_format_zip_no_compression.c @@ -0,0 +1,304 @@ +/*- + * Copyright (c) 2008 Anselm Strauss + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/* + * Development supported by Google Summer of Code 2008. + */ + +#include "test.h" +__FBSDID("$FreeBSD$"); + +static unsigned long +bitcrc32(unsigned long c, void *_p, size_t s) +{ + /* This is a drop-in replacement for crc32() from zlib. + * Libarchive should be able to correctly generate + * uncompressed zip archives (including correct CRCs) even + * when zlib is unavailable, and this function helps us verify + * that. Yes, this is very, very slow and unsuitable for + * production use, but it's correct, compact, and works well + * enough for this particular usage. Libarchive internally + * uses a much more efficient implementation. */ + const unsigned char *p = _p; + int bitctr; + + if (p == NULL) + return (0); + + for (; s > 0; --s) { + c ^= *p++; + for (bitctr = 8; bitctr > 0; --bitctr) { + if (c & 1) c = (c >> 1); + else c = (c >> 1) ^ 0xedb88320; + c ^= 0x80000000; + } + } + return (c); +} + +/* Quick and dirty: Read 2-byte and 4-byte integers from Zip file. */ +static int i2(const char *p) { return ((p[0] & 0xff) | ((p[1] & 0xff) << 8)); } +static int i4(const char *p) { return (i2(p) | (i2(p + 2) << 16)); } + +DEFINE_TEST(test_write_format_zip_no_compression) +{ + /* Buffer data */ + struct archive *a; + struct archive_entry *entry; + char buff[100000]; + const char *buffend; + /* p is the pointer to walk over the central directory, + * q walks over the local headers, the data and the data descriptors. */ + const char *p, *q; + size_t used; + + /* File data */ + char file_name[] = "file"; + char file_data1[] = {'1', '2', '3', '4', '5'}; + char file_data2[] = {'6', '7', '8', '9', '0'}; + int file_perm = 00644; + short file_uid = 10; + short file_gid = 20; + + /* Folder data */ + char folder_name[] = "folder/"; + int folder_perm = 00755; + short folder_uid = 30; + short folder_gid = 40; + + /* Time data */ + time_t t = time(NULL); + struct tm *tm = localtime(&t); + + /* Misc variables */ + unsigned long crc; + + /* Create new ZIP archive in memory without padding. */ + assert((a = archive_write_new()) != NULL); + assertA(0 == archive_write_set_format_zip(a)); + assertA(0 == archive_write_set_format_options(a, "zip:compression=store")); + assertA(0 == archive_write_set_compression_none(a)); + assertA(0 == archive_write_set_bytes_per_block(a, 1)); + assertA(0 == archive_write_set_bytes_in_last_block(a, 1)); + assertA(0 == archive_write_open_memory(a, buff, sizeof(buff), &used)); + + /* Write entries. */ + + /* Regular file */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, file_name); + archive_entry_set_mode(entry, S_IFREG | 0644); + archive_entry_set_size(entry, sizeof(file_data1) + sizeof(file_data2)); + archive_entry_set_uid(entry, file_uid); + archive_entry_set_gid(entry, file_gid); + archive_entry_set_mtime(entry, t, 0); + archive_entry_set_atime(entry, t, 0); + archive_entry_set_ctime(entry, t, 0); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + assertEqualIntA(a, sizeof(file_data1), archive_write_data(a, file_data1, sizeof(file_data1))); + assertEqualIntA(a, sizeof(file_data2), archive_write_data(a, file_data2, sizeof(file_data2))); + archive_entry_free(entry); + + /* Folder */ + assert((entry = archive_entry_new()) != NULL); + archive_entry_set_pathname(entry, folder_name); + archive_entry_set_mode(entry, S_IFDIR | folder_perm); + archive_entry_set_size(entry, 0); + archive_entry_set_uid(entry, folder_uid); + archive_entry_set_gid(entry, folder_gid); + archive_entry_set_mtime(entry, t, 0); + archive_entry_set_atime(entry, t, 0); + archive_entry_set_ctime(entry, t, 0); + assertEqualIntA(a, 0, archive_write_header(a, entry)); + archive_entry_free(entry); + + /* Close the archive . */ + assertA(0 == archive_write_close(a)); + assertA(0 == archive_write_finish(a)); + + /* Remember the end of the archive in memory. */ + buffend = buff + used; + + /* Verify "End of Central Directory" record. */ + /* Get address of end-of-central-directory record. */ + p = buffend - 22; /* Assumes there is no zip comment field. */ + failure("End-of-central-directory begins with PK\\005\\006 signature"); + assertEqualMem(p, "PK\005\006", 4); + failure("This must be disk 0"); + assertEqualInt(i2(p + 4), 0); + failure("Central dir must start on disk 0"); + assertEqualInt(i2(p + 6), 0); + failure("All central dir entries are on this disk"); + assertEqualInt(i2(p + 8), i2(p + 10)); + failure("CD start (%d) + CD length (%d) should == archive size - 22", + i4(p + 12), i4(p + 16)); + assertEqualInt(i4(p + 12) + i4(p + 16), used - 22); + failure("no zip comment"); + assertEqualInt(i2(p + 20), 0); + + /* Get address of first entry in central directory. */ + p = buff + i4(buffend - 6); + failure("Central file record at offset %d should begin with" + " PK\\001\\002 signature", + i4(buffend - 10)); + + /* Verify file entry in central directory. */ + assertEqualMem(p, "PK\001\002", 4); /* Signature */ + assertEqualInt(i2(p + 4), 3 * 256 + 20); /* Version made by */ + assertEqualInt(i2(p + 6), 20); /* Version needed to extract */ + assertEqualInt(i2(p + 8), 8); /* Flags */ + assertEqualInt(i2(p + 10), 0); /* Compression method */ + assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ + assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ + crc = bitcrc32(0, file_data1, sizeof(file_data1)); + crc = bitcrc32(crc, file_data2, sizeof(file_data2)); + assertEqualInt(i4(p + 16), crc); /* CRC-32 */ + assertEqualInt(i4(p + 20), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */ + assertEqualInt(i4(p + 24), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */ + assertEqualInt(i2(p + 28), strlen(file_name)); /* Pathname length */ + assertEqualInt(i2(p + 30), 13); /* Extra field length */ + assertEqualInt(i2(p + 32), 0); /* File comment length */ + assertEqualInt(i2(p + 34), 0); /* Disk number start */ + assertEqualInt(i2(p + 36), 0); /* Internal file attrs */ + assertEqualInt(i4(p + 38) >> 16 & 01777, file_perm); /* External file attrs */ + assertEqualInt(i4(p + 42), 0); /* Offset of local header */ + assertEqualMem(p + 46, file_name, strlen(file_name)); /* Pathname */ + p = p + 46 + strlen(file_name); + assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ + assertEqualInt(i2(p + 2), 5); /* 'UT' size */ + assertEqualInt(p[4], 7); /* 'UT' flags */ + assertEqualInt(i4(p + 5), t); /* 'UT' mtime */ + p = p + 9; + assertEqualInt(i2(p), 0x7855); /* 'Ux' extension header */ + assertEqualInt(i2(p + 2), 0); /* 'Ux' size */ + p = p + 4; + + /* Verify local header of file entry. */ + q = buff; + assertEqualMem(q, "PK\003\004", 4); /* Signature */ + assertEqualInt(i2(q + 4), 20); /* Version needed to extract */ + assertEqualInt(i2(q + 6), 8); /* Flags */ + assertEqualInt(i2(q + 8), 0); /* Compression method */ + assertEqualInt(i2(q + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ + assertEqualInt(i2(q + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ + assertEqualInt(i4(q + 14), 0); /* CRC-32 */ + assertEqualInt(i4(q + 18), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */ + assertEqualInt(i4(q + 22), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */ + assertEqualInt(i2(q + 26), strlen(file_name)); /* Pathname length */ + assertEqualInt(i2(q + 28), 25); /* Extra field length */ + assertEqualMem(q + 30, file_name, strlen(file_name)); /* Pathname */ + q = q + 30 + strlen(file_name); + assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */ + assertEqualInt(i2(q + 2), 13); /* 'UT' size */ + assertEqualInt(q[4], 7); /* 'UT' flags */ + assertEqualInt(i4(q + 5), t); /* 'UT' mtime */ + assertEqualInt(i4(q + 9), t); /* 'UT' atime */ + assertEqualInt(i4(q + 13), t); /* 'UT' ctime */ + q = q + 17; + assertEqualInt(i2(q), 0x7855); /* 'Ux' extension header */ + assertEqualInt(i2(q + 2), 4); /* 'Ux' size */ + assertEqualInt(i2(q + 4), file_uid); /* 'Ux' UID */ + assertEqualInt(i2(q + 6), file_gid); /* 'Ux' GID */ + q = q + 8; + + /* Verify data of file entry. */ + assertEqualMem(q, file_data1, sizeof(file_data1)); + assertEqualMem(q + sizeof(file_data1), file_data2, sizeof(file_data2)); + q = q + sizeof(file_data1) + sizeof(file_data2); + + /* Verify data descriptor of file entry. */ + assertEqualMem(q, "PK\007\010", 4); /* Signature */ + assertEqualInt(i4(q + 4), crc); /* CRC-32 */ + assertEqualInt(i4(q + 8), sizeof(file_data1) + sizeof(file_data2)); /* Compressed size */ + assertEqualInt(i4(q + 12), sizeof(file_data1) + sizeof(file_data2)); /* Uncompressed size */ + q = q + 16; + + /* Verify folder entry in central directory. */ + assertEqualMem(p, "PK\001\002", 4); /* Signature */ + assertEqualInt(i2(p + 4), 3 * 256 + 20); /* Version made by */ + assertEqualInt(i2(p + 6), 20); /* Version needed to extract */ + assertEqualInt(i2(p + 8), 8); /* Flags */ + assertEqualInt(i2(p + 10), 0); /* Compression method */ + assertEqualInt(i2(p + 12), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ + assertEqualInt(i2(p + 14), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ + crc = 0; + assertEqualInt(i4(p + 16), crc); /* CRC-32 */ + assertEqualInt(i4(p + 20), 0); /* Compressed size */ + assertEqualInt(i4(p + 24), 0); /* Uncompressed size */ + assertEqualInt(i2(p + 28), strlen(folder_name)); /* Pathname length */ + assertEqualInt(i2(p + 30), 13); /* Extra field length */ + assertEqualInt(i2(p + 32), 0); /* File comment length */ + assertEqualInt(i2(p + 34), 0); /* Disk number start */ + assertEqualInt(i2(p + 36), 0); /* Internal file attrs */ + assertEqualInt(i4(p + 38) >> 16 & 01777, folder_perm); /* External file attrs */ + assertEqualInt(i4(p + 42), q - buff); /* Offset of local header */ + assertEqualMem(p + 46, folder_name, strlen(folder_name)); /* Pathname */ + p = p + 46 + strlen(folder_name); + assertEqualInt(i2(p), 0x5455); /* 'UT' extension header */ + assertEqualInt(i2(p + 2), 5); /* 'UT' size */ + assertEqualInt(p[4], 7); /* 'UT' flags */ + assertEqualInt(i4(p + 5), t); /* 'UT' mtime */ + p = p + 9; + assertEqualInt(i2(p), 0x7855); /* 'Ux' extension header */ + assertEqualInt(i2(p + 2), 0); /* 'Ux' size */ + p = p + 4; + + /* Verify local header of folder entry. */ + assertEqualMem(q, "PK\003\004", 4); /* Signature */ + assertEqualInt(i2(q + 4), 20); /* Version needed to extract */ + assertEqualInt(i2(q + 6), 8); /* Flags */ + assertEqualInt(i2(q + 8), 0); /* Compression method */ + assertEqualInt(i2(q + 10), (tm->tm_hour * 2048) + (tm->tm_min * 32) + (tm->tm_sec / 2)); /* File time */ + assertEqualInt(i2(q + 12), ((tm->tm_year - 80) * 512) + ((tm->tm_mon + 1) * 32) + tm->tm_mday); /* File date */ + assertEqualInt(i4(q + 14), 0); /* CRC-32 */ + assertEqualInt(i4(q + 18), 0); /* Compressed size */ + assertEqualInt(i4(q + 22), 0); /* Uncompressed size */ + assertEqualInt(i2(q + 26), strlen(folder_name)); /* Pathname length */ + assertEqualInt(i2(q + 28), 25); /* Extra field length */ + assertEqualMem(q + 30, folder_name, strlen(folder_name)); /* Pathname */ + q = q + 30 + strlen(folder_name); + assertEqualInt(i2(q), 0x5455); /* 'UT' extension header */ + assertEqualInt(i2(q + 2), 13); /* 'UT' size */ + assertEqualInt(q[4], 7); /* 'UT' flags */ + assertEqualInt(i4(q + 5), t); /* 'UT' mtime */ + assertEqualInt(i4(q + 9), t); /* 'UT' atime */ + assertEqualInt(i4(q + 13), t); /* 'UT' ctime */ + q = q + 17; + assertEqualInt(i2(q), 0x7855); /* 'Ux' extension header */ + assertEqualInt(i2(q + 2), 4); /* 'Ux' size */ + assertEqualInt(i2(q + 4), folder_uid); /* 'Ux' UID */ + assertEqualInt(i2(q + 6), folder_gid); /* 'Ux' GID */ + q = q + 8; + + /* There should not be any data in the folder entry, + * meaning next is the data descriptor header. */ + + /* Verify data descriptor of folder entry. */ + assertEqualMem(q, "PK\007\010", 4); /* Signature */ + assertEqualInt(i4(q + 4), crc); /* CRC-32 */ + assertEqualInt(i4(q + 8), 0); /* Compressed size */ + assertEqualInt(i4(q + 12), 0); /* Uncompressed size */ + q = q + 16; +} -- cgit v1.1