diff options
author | mm <mm@FreeBSD.org> | 2012-07-28 06:38:44 +0000 |
---|---|---|
committer | mm <mm@FreeBSD.org> | 2012-07-28 06:38:44 +0000 |
commit | 11bb7fcf7b175da111e710d49b6e1c30153b625b (patch) | |
tree | 1ed0c7ff98605ecfbedcfa8d00cd1a29e2dfebe6 /contrib/libarchive/libarchive/test | |
parent | f694295168072660e04cabb712367c5a73b59885 (diff) | |
parent | e7b24010c4d2190a1465594620e629e469c522f8 (diff) | |
download | FreeBSD-src-11bb7fcf7b175da111e710d49b6e1c30153b625b.zip FreeBSD-src-11bb7fcf7b175da111e710d49b6e1c30153b625b.tar.gz |
Update libarchive to 3.0.4
Diffstat (limited to 'contrib/libarchive/libarchive/test')
22 files changed, 3687 insertions, 288 deletions
diff --git a/contrib/libarchive/libarchive/test/main.c b/contrib/libarchive/libarchive/test/main.c index 35e48a8..9d692d1 100644 --- a/contrib/libarchive/libarchive/test/main.c +++ b/contrib/libarchive/libarchive/test/main.c @@ -24,6 +24,9 @@ */ #include "test.h" +#ifdef HAVE_SYS_IOCTL_H +#include <sys/ioctl.h> +#endif #ifdef HAVE_SYS_TIME_H #include <sys/time.h> #endif @@ -31,6 +34,16 @@ #ifdef HAVE_ICONV_H #include <iconv.h> #endif +/* + * Some Linux distributions have both linux/ext2_fs.h and ext2fs/ext2_fs.h. + * As the include guards don't agree, the order of include is important. + */ +#ifdef HAVE_LINUX_EXT2_FS_H +#include <linux/ext2_fs.h> /* for Linux file flags */ +#endif +#if defined(HAVE_EXT2FS_EXT2_FS_H) && !defined(__CYGWIN__) +#include <ext2fs/ext2_fs.h> /* Linux file flags, broken on Cygwin */ +#endif #include <limits.h> #include <locale.h> #ifdef HAVE_SIGNAL_H @@ -114,7 +127,14 @@ __FBSDID("$FreeBSD$"); #endif #if defined(_WIN32) && !defined(__CYGWIN__) -void *GetFunctionKernel32(const char *name) +static void *GetFunctionKernel32(const char *); +static int my_CreateSymbolicLinkA(const char *, const char *, int); +static int my_CreateHardLinkA(const char *, const char *); +static int my_GetFileInformationByName(const char *, + BY_HANDLE_FILE_INFORMATION *); + +static void * +GetFunctionKernel32(const char *name) { static HINSTANCE lib; static int set; @@ -153,7 +173,7 @@ my_CreateHardLinkA(const char *linkname, const char *target) return f == NULL ? 0 : (*f)(linkname, target, NULL); } -int +static int my_GetFileInformationByName(const char *path, BY_HANDLE_FILE_INFORMATION *bhfi) { HANDLE h; @@ -1505,7 +1525,7 @@ assertion_make_dir(const char *file, int line, const char *dirname, int mode) /* 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) + const char *path, int mode, int csize, const void *contents) { #if defined(_WIN32) && !defined(__CYGWIN__) /* TODO: Rework this to set file mode as well. */ @@ -1519,8 +1539,13 @@ assertion_make_file(const char *file, int line, return (0); } if (contents != NULL) { - if (strlen(contents) - != fwrite(contents, 1, strlen(contents), f)) { + size_t wsize; + + if (csize < 0) + wsize = strlen(contents); + else + wsize = (size_t)csize; + if (wsize != fwrite(contents, 1, wsize, f)) { fclose(f); failure_start(file, line, "Could not write file %s", path); @@ -1540,10 +1565,16 @@ assertion_make_file(const char *file, int line, return (0); } if (contents != NULL) { - if ((ssize_t)strlen(contents) - != write(fd, contents, strlen(contents))) { + ssize_t wsize; + + if (csize < 0) + wsize = (ssize_t)strlen(contents); + else + wsize = (ssize_t)csize; + if (wsize != write(fd, contents, wsize)) { close(fd); - failure_start(file, line, "Could not write to %s", path); + failure_start(file, line, + "Could not write to %s", path); failure_finish(NULL); return (0); } @@ -1714,6 +1745,52 @@ assertion_utimes(const char *file, int line, #endif /* defined(_WIN32) && !defined(__CYGWIN__) */ } +/* Set nodump, report failures. */ +int +assertion_nodump(const char *file, int line, const char *pathname) +{ +#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) + int r; + + assertion_count(file, line); + r = chflags(pathname, UF_NODUMP); + if (r < 0) { + failure_start(file, line, "Can't set nodump %s\n", pathname); + failure_finish(NULL); + return (0); + } +#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\ + && defined(EXT2_NODUMP_FL) + int fd, r, flags; + + assertion_count(file, line); + fd = open(pathname, O_RDONLY | O_NONBLOCK); + if (fd < 0) { + failure_start(file, line, "Can't open %s\n", pathname); + failure_finish(NULL); + return (0); + } + r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags); + if (r < 0) { + failure_start(file, line, "Can't get flags %s\n", pathname); + failure_finish(NULL); + return (0); + } + flags |= EXT2_NODUMP_FL; + r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags); + if (r < 0) { + failure_start(file, line, "Can't set nodump %s\n", pathname); + failure_finish(NULL); + return (0); + } + close(fd); +#else + (void)pathname; /* UNUSED */ + assertion_count(file, line); +#endif + return (1); +} + /* * * UTILITIES for use by tests. @@ -1742,7 +1819,7 @@ canSymlink(void) return (value); ++tested; - assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, "a"); + assertion_make_file(__FILE__, __LINE__, "canSymlink.0", 0644, 1, "a"); /* Note: Cygwin has its own symlink() emulation that does not * use the Win32 CreateSymbolicLink() function. */ #if defined(_WIN32) && !defined(__CYGWIN__) @@ -1792,6 +1869,70 @@ canGunzip(void) } /* + * Can this filesystem handle nodump flags. + */ +#if defined(HAVE_STRUCT_STAT_ST_FLAGS) && defined(UF_NODUMP) + +int +canNodump(void) +{ + const char *path = "cannodumptest"; + struct stat sb; + + assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL); + if (chflags(path, UF_NODUMP) < 0) + return (0); + if (stat(path, &sb) < 0) + return (0); + if (sb.st_flags & UF_NODUMP) + return (1); + return (0); +} + +#elif defined(EXT2_IOC_GETFLAGS) && defined(HAVE_WORKING_EXT2_IOC_GETFLAGS)\ + && defined(EXT2_NODUMP_FL) + +int +canNodump(void) +{ + const char *path = "cannodumptest"; + int fd, r, flags; + + assertion_make_file(__FILE__, __LINE__, path, 0644, 0, NULL); + fd = open(path, O_RDONLY | O_NONBLOCK); + if (fd < 0) + return (0); + r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags); + if (r < 0) + return (0); + flags |= EXT2_NODUMP_FL; + r = ioctl(fd, EXT2_IOC_SETFLAGS, &flags); + if (r < 0) + return (0); + close(fd); + fd = open(path, O_RDONLY | O_NONBLOCK); + if (fd < 0) + return (0); + r = ioctl(fd, EXT2_IOC_GETFLAGS, &flags); + if (r < 0) + return (0); + close(fd); + if (flags & EXT2_NODUMP_FL) + return (1); + return (0); +} + +#else + +int +canNodump() +{ + return (0); +} + +#endif + +/* * 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. @@ -2234,17 +2375,77 @@ success: return strdup(buff); } +static int +get_test_set(int *test_set, int limit, const char *test) +{ + int start, end; + int idx = 0; + + if (test == NULL) { + /* Default: Run all tests. */ + for (;idx < limit; idx++) + test_set[idx] = idx; + return (limit); + } + if (*test >= '0' && *test <= '9') { + const char *vp = test; + start = 0; + while (*vp >= '0' && *vp <= '9') { + start *= 10; + start += *vp - '0'; + ++vp; + } + if (*vp == '\0') { + end = start; + } else if (*vp == '-') { + ++vp; + if (*vp == '\0') { + end = limit - 1; + } else { + end = 0; + while (*vp >= '0' && *vp <= '9') { + end *= 10; + end += *vp - '0'; + ++vp; + } + } + } else + return (-1); + if (start < 0 || end >= limit || start > end) + return (-1); + while (start <= end) + test_set[idx++] = start++; + } else { + size_t len = strlen(test); + for (start = 0; start < limit; ++start) { + const char *name = tests[start].name; + const char *p; + + while ((p = strchr(name, test[0])) != NULL) { + if (strncmp(p, test, len) == 0) { + test_set[idx++] = start; + break; + } else + name = p + 1; + } + + } + } + return ((idx == 0)?-1:idx); +} + int main(int argc, char **argv) { static const int limit = sizeof(tests) / sizeof(tests[0]); - int i = 0, j = 0, start, end, tests_run = 0, tests_failed = 0, option; + int test_set[sizeof(tests) / sizeof(tests[0])]; + int i = 0, j = 0, tests_run = 0, tests_failed = 0, option; time_t now; char *refdir_alloc = NULL; const char *progname; char **saved_argv; const char *tmp, *option_arg, *p; - char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL; + char tmpdir[256], *pwd, *testprogdir, *tmp2 = NULL, *vlevel = NULL; char tmpdir_timestamp[256]; (void)argc; /* UNUSED */ @@ -2330,6 +2531,19 @@ main(int argc, char **argv) if (getenv(ENVBASE "_DEBUG") != NULL) dump_on_failure = 1; + /* Allow -v to be controlled through the environment. */ + if (getenv("_VERBOSITY_LEVEL") != NULL) + { + vlevel = getenv("_VERBOSITY_LEVEL"); + verbosity = atoi(vlevel); + if (verbosity < VERBOSITY_SUMMARY_ONLY || verbosity > VERBOSITY_FULL) + { + /* Unsupported verbosity levels are silently ignored */ + vlevel = NULL; + verbosity = VERBOSITY_PASSFAIL; + } + } + /* Get the directory holding test files from environment. */ refdir = getenv(ENVBASE "_TEST_FILES"); @@ -2377,7 +2591,8 @@ main(int argc, char **argv) #endif break; case 'q': - verbosity--; + if (!vlevel) + verbosity--; break; case 'r': refdir = option_arg; @@ -2386,7 +2601,8 @@ main(int argc, char **argv) until_failure++; break; case 'v': - verbosity++; + if (!vlevel) + verbosity++; break; default: fprintf(stderr, "Unrecognized option '%c'\n", @@ -2499,78 +2715,27 @@ main(int argc, char **argv) saved_argv = argv; do { argv = saved_argv; - if (*argv == NULL) { - /* Default: Run all tests. */ - for (i = 0; i < limit; i++) { + do { + int test_num; + + test_num = get_test_set(test_set, limit, *argv); + if (test_num < 0) { + printf("*** INVALID Test %s\n", *argv); + free(refdir_alloc); + usage(progname); + return (1); + } + for (i = 0; i < test_num; i++) { tests_run++; - if (test_run(i, tmpdir)) { + if (test_run(test_set[i], tmpdir)) { tests_failed++; if (until_failure) goto finish; } } - } else { - while (*(argv) != NULL) { - if (**argv >= '0' && **argv <= '9') { - char *vp = *argv; - start = 0; - while (*vp >= '0' && *vp <= '9') { - start *= 10; - start += *vp - '0'; - ++vp; - } - if (*vp == '\0') { - end = start; - } else if (*vp == '-') { - ++vp; - if (*vp == '\0') { - end = limit - 1; - } else { - end = 0; - while (*vp >= '0' && *vp <= '9') { - end *= 10; - end += *vp - '0'; - ++vp; - } - } - } else { - printf("*** INVALID Test %s\n", *argv); - free(refdir_alloc); - usage(progname); - return (1); - } - if (start < 0 || end >= limit || start > end) { - printf("*** INVALID Test %s\n", *argv); - free(refdir_alloc); - usage(progname); - return (1); - } - } else { - for (start = 0; start < limit; ++start) { - if (strcmp(*argv, tests[start].name) == 0) - break; - } - end = start; - if (start >= limit) { - printf("*** INVALID Test ``%s''\n", - *argv); - free(refdir_alloc); - usage(progname); - /* usage() never returns */ - } - } - while (start <= end) { - tests_run++; - if (test_run(start, tmpdir)) { - tests_failed++; - if (until_failure) - goto finish; - } - ++start; - } + if (*argv != NULL) argv++; - } - } + } while (*argv != NULL); } while (until_failure); finish: diff --git a/contrib/libarchive/libarchive/test/read_open_memory.c b/contrib/libarchive/libarchive/test/read_open_memory.c index 0d88df5..5ee8b30 100644 --- a/contrib/libarchive/libarchive/test/read_open_memory.c +++ b/contrib/libarchive/libarchive/test/read_open_memory.c @@ -68,7 +68,7 @@ read_open_memory(struct archive *a, void *buff, size_t size, size_t read_size) * that internals work correctly with just the minimal entry points. */ int -read_open_memory2(struct archive *a, void *buff, size_t size, size_t read_size) +read_open_memory_minimal(struct archive *a, void *buff, size_t size, size_t read_size) { return read_open_memory_internal(a, buff, size, read_size, 1); } diff --git a/contrib/libarchive/libarchive/test/test.h b/contrib/libarchive/libarchive/test/test.h index eb78f79..01a12fd 100644 --- a/contrib/libarchive/libarchive/test/test.h +++ b/contrib/libarchive/libarchive/test/test.h @@ -194,11 +194,15 @@ #define assertMakeDir(dirname, mode) \ assertion_make_dir(__FILE__, __LINE__, dirname, mode) #define assertMakeFile(path, mode, contents) \ - assertion_make_file(__FILE__, __LINE__, path, mode, contents) + assertion_make_file(__FILE__, __LINE__, path, mode, -1, contents) +#define assertMakeBinFile(path, mode, csize, contents) \ + assertion_make_file(__FILE__, __LINE__, path, mode, csize, contents) #define assertMakeHardlink(newfile, oldfile) \ assertion_make_hardlink(__FILE__, __LINE__, newfile, oldfile) #define assertMakeSymlink(newfile, linkto) \ assertion_make_symlink(__FILE__, __LINE__, newfile, linkto) +#define assertNodump(path) \ + assertion_nodump(__FILE__, __LINE__, path) #define assertUmask(mask) \ assertion_umask(__FILE__, __LINE__, mask) #define assertUtimes(pathname, atime, atime_nsec, mtime, mtime_nsec) \ @@ -241,9 +245,10 @@ 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_file(const char *, int, const char *, int, int, const void *); 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_nodump(const char *, int, const char *); int assertion_non_empty_file(const char *, int, const char *); int assertion_text_file_contents(const char *, int, const char *buff, const char *f); int assertion_umask(const char *, int, int); @@ -267,6 +272,9 @@ int canGzip(void); /* Return true if this platform can run the "gunzip" program. */ int canGunzip(void); +/* Return true if this filesystem can handle nodump flags. */ +int canNodump(void); + /* Return true if the file has large i-node number(>0xffffffff). */ int is_LargeInode(const char *); @@ -289,8 +297,8 @@ const char *testworkdir; /* Special customized read-from-memory interface. */ 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); +/* _minimal version exercises a slightly different set of libarchive APIs. */ +int read_open_memory_minimal(struct archive *, void *, size_t, size_t); /* _seek version produces a seekable file. */ int read_open_memory_seek(struct archive *, void *, size_t, size_t); diff --git a/contrib/libarchive/libarchive/test/test_archive_getdate.c b/contrib/libarchive/libarchive/test/test_archive_getdate.c new file mode 100644 index 0000000..4be359b --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_archive_getdate.c @@ -0,0 +1,81 @@ +/*- + * 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$"); + +#include <time.h> + +/* + * Verify that the getdate() function works. + */ + +time_t __archive_get_date(time_t, const char *); +#define get_date __archive_get_date + +DEFINE_TEST(test_archive_getdate) +{ + time_t now = time(NULL); + + assertEqualInt(get_date(now, "Jan 1, 1970 UTC"), 0); + assertEqualInt(get_date(now, "7:12:18-0530 4 May 1983"), 420900138); + assertEqualInt(get_date(now, "2004/01/29 513 mest"), 1075345980); + assertEqualInt(get_date(now, "99/02/17 7pm utc"), 919278000); + assertEqualInt(get_date(now, "02/17/99 7:11am est"), 919253460); + /* It's important that we handle ctime() format. */ + assertEqualInt(get_date(now, "Sun Feb 22 17:38:26 PST 2009"), + 1235353106); + /* Basic relative offsets. */ + /* If we use the actual current time as the reference, then + * these tests break around DST changes, so it's actually + * important to use a specific reference time here. */ + assertEqualInt(get_date(0, "tomorrow"), 24 * 60 * 60); + assertEqualInt(get_date(0, "yesterday"), - 24 * 60 * 60); + assertEqualInt(get_date(0, "now + 1 hour"), 60 * 60); + assertEqualInt(get_date(0, "now + 1 hour + 1 minute"), 60 * 60 + 60); + /* Repeat the above for a different start time. */ + now = 1231113600; /* Jan 5, 2009 00:00 UTC */ + assertEqualInt(get_date(0, "Jan 5, 2009 00:00 UTC"), now); + assertEqualInt(get_date(now, "tomorrow"), now + 24 * 60 * 60); + assertEqualInt(get_date(now, "yesterday"), now - 24 * 60 * 60); + assertEqualInt(get_date(now, "now + 1 hour"), now + 60 * 60); + assertEqualInt(get_date(now, "now + 1 hour + 1 minute"), + now + 60 * 60 + 60); + assertEqualInt(get_date(now, "tomorrow 5:16am UTC"), + now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60); + assertEqualInt(get_date(now, "UTC 5:16am tomorrow"), + now + 24 * 60 * 60 + 5 * 60 * 60 + 16 * 60); + + /* Jan 5, 2009 was a Monday. */ + assertEqualInt(get_date(now, "monday UTC"), now); + assertEqualInt(get_date(now, "sunday UTC"), now + 6 * 24 * 60 * 60); + assertEqualInt(get_date(now, "tuesday UTC"), now + 24 * 60 * 60); + /* "next tuesday" is one week after "tuesday" */ + assertEqualInt(get_date(now, "UTC next tuesday"), + now + 8 * 24 * 60 * 60); + /* "last tuesday" is one week before "tuesday" */ + assertEqualInt(get_date(now, "last tuesday UTC"), + now - 6 * 24 * 60 * 60); + /* TODO: Lots more tests here. */ +} diff --git a/contrib/libarchive/libarchive/test/test_archive_match_owner.c b/contrib/libarchive/libarchive/test/test_archive_match_owner.c new file mode 100644 index 0000000..6bf9c6f --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_archive_match_owner.c @@ -0,0 +1,289 @@ +/*- + * Copyright (c) 2012 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$"); + +static void +test_uid(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_uid(m, 1000)); + assertEqualIntA(m, 0, archive_match_include_uid(m, 1002)); + + archive_entry_set_uid(ae, 0); + failure("uid 0 should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_uid(ae, 1000); + failure("uid 1000 should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_uid(ae, 1001); + failure("uid 1001 should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_uid(ae, 1002); + failure("uid 1002 should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_uid(ae, 1003); + failure("uid 1003 should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_gid(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_gid(m, 1000)); + assertEqualIntA(m, 0, archive_match_include_gid(m, 1002)); + + archive_entry_set_gid(ae, 0); + failure("uid 0 should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_gid(ae, 1000); + failure("uid 1000 should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_gid(ae, 1001); + failure("uid 1001 should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_gid(ae, 1002); + failure("uid 1002 should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_gid(ae, 1003); + failure("uid 1003 should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_uname_mbs(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_uname(m, "foo")); + assertEqualIntA(m, 0, archive_match_include_uname(m, "bar")); + + archive_entry_copy_uname(ae, "unknown"); + failure("User 'unknown' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_uname(ae, "foo"); + failure("User 'foo' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_uname(ae, "foo1"); + failure("User 'foo1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_uname(ae, "bar"); + failure("User 'bar' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_uname(ae, "bar1"); + failure("User 'bar1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_uname_wcs(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_uname_w(m, L"foo")); + assertEqualIntA(m, 0, archive_match_include_uname_w(m, L"bar")); + + archive_entry_copy_uname_w(ae, L"unknown"); + failure("User 'unknown' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_uname_w(ae, L"foo"); + failure("User 'foo' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_uname_w(ae, L"foo1"); + failure("User 'foo1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_uname_w(ae, L"bar"); + failure("User 'bar' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_uname_w(ae, L"bar1"); + failure("User 'bar1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_gname_mbs(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_gname(m, "foo")); + assertEqualIntA(m, 0, archive_match_include_gname(m, "bar")); + + archive_entry_copy_gname(ae, "unknown"); + failure("Group 'unknown' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_gname(ae, "foo"); + failure("Group 'foo' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_gname(ae, "foo1"); + failure("Group 'foo1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_gname(ae, "bar"); + failure("Group 'bar' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_gname(ae, "bar1"); + failure("Group 'bar1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_gname_wcs(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_gname_w(m, L"foo")); + assertEqualIntA(m, 0, archive_match_include_gname_w(m, L"bar")); + + archive_entry_copy_gname_w(ae, L"unknown"); + failure("Group 'unknown' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_gname_w(ae, L"foo"); + failure("Group 'foo' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_gname_w(ae, L"foo1"); + failure("Group 'foo1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_copy_gname_w(ae, L"bar"); + failure("Group 'bar' should not be excluded"); + assertEqualInt(0, archive_match_owner_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_copy_gname_w(ae, L"bar1"); + failure("Group 'bar1' should be excluded"); + assertEqualInt(1, archive_match_owner_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +DEFINE_TEST(test_archive_match_owner) +{ + test_uid(); + test_gid(); + test_uname_mbs(); + test_uname_wcs(); + test_gname_mbs(); + test_gname_wcs(); +} diff --git a/contrib/libarchive/libarchive/test/test_archive_match_path.c b/contrib/libarchive/libarchive/test/test_archive_match_path.c new file mode 100644 index 0000000..5e9b9a8 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_archive_match_path.c @@ -0,0 +1,450 @@ +/*- + * Copyright (c) 2012 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$"); + +static void +test_exclusion_mbs(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + /* Test for pattern "^aa*" */ + assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aa*")); + + /* Test with 'aa1234', which should be excluded. */ + archive_entry_copy_pathname(ae, "aa1234"); + failure("'aa1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"aa1234"); + failure("'aa1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Test with 'a1234', which should not be excluded. */ + archive_entry_copy_pathname(ae, "a1234"); + failure("'a1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"a1234"); + failure("'a1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_exclusion_wcs(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + /* Test for pattern "^aa*" */ + assertEqualIntA(m, 0, archive_match_exclude_pattern_w(m, L"^aa*")); + + /* Test with 'aa1234', which should be excluded. */ + archive_entry_copy_pathname(ae, "aa1234"); + failure("'aa1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"aa1234"); + failure("'aa1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Test with 'a1234', which should not be excluded. */ + archive_entry_copy_pathname(ae, "a1234"); + failure("'a1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"a1234"); + failure("'a1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +exclusion_from_file(struct archive *m) +{ + struct archive_entry *ae; + + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + /* Test with 'first', which should not be excluded. */ + archive_entry_copy_pathname(ae, "first"); + failure("'first' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"first"); + failure("'first' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Test with 'second', which should be excluded. */ + archive_entry_copy_pathname(ae, "second"); + failure("'second' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"second"); + failure("'second' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Test with 'third', which should not be excluded. */ + archive_entry_copy_pathname(ae, "third"); + failure("'third' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"third"); + failure("'third' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Test with 'four', which should be excluded. */ + archive_entry_copy_pathname(ae, "four"); + failure("'four' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"four"); + failure("'four' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); +} + +static void +test_exclusion_from_file_mbs(void) +{ + struct archive *m; + + /* Test1: read exclusion patterns from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + assertEqualIntA(m, 0, + archive_match_exclude_pattern_from_file(m, "exclusion", 0)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); + + /* Test2: read exclusion patterns in a null separator from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + /* Test for pattern reading from file */ + assertEqualIntA(m, 0, + archive_match_exclude_pattern_from_file(m, "exclusion_null", 1)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); +} + +static void +test_exclusion_from_file_wcs(void) +{ + struct archive *m; + + /* Test1: read exclusion patterns from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + assertEqualIntA(m, 0, + archive_match_exclude_pattern_from_file_w(m, L"exclusion", 0)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); + + /* Test2: read exclusion patterns in a null separator from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + /* Test for pattern reading from file */ + assertEqualIntA(m, 0, + archive_match_exclude_pattern_from_file_w(m, L"exclusion_null", 1)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); +} + +static void +test_inclusion_mbs(void) +{ + struct archive_entry *ae; + struct archive *m; + const char *mp; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + /* Test for pattern "^aa*" */ + assertEqualIntA(m, 0, archive_match_include_pattern(m, "^aa*")); + + /* Test with 'aa1234', which should not be excluded. */ + archive_entry_copy_pathname(ae, "aa1234"); + failure("'aa1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"aa1234"); + failure("'aa1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Test with 'a1234', which should be excluded. */ + archive_entry_copy_pathname(ae, "a1234"); + failure("'a1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"a1234"); + failure("'a1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify unmatched_inclusions. */ + assertEqualInt(0, archive_match_path_unmatched_inclusions(m)); + assertEqualIntA(m, ARCHIVE_EOF, + archive_match_path_unmatched_inclusions_next(m, &mp)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_inclusion_wcs(void) +{ + struct archive_entry *ae; + struct archive *m; + const char *mp; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + /* Test for pattern "^aa*" */ + assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*")); + + /* Test with 'aa1234', which should not be excluded. */ + archive_entry_copy_pathname(ae, "aa1234"); + failure("'aa1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"aa1234"); + failure("'aa1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Test with 'a1234', which should be excluded. */ + archive_entry_copy_pathname(ae, "a1234"); + failure("'a1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"a1234"); + failure("'a1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify unmatched_inclusions. */ + assertEqualInt(0, archive_match_path_unmatched_inclusions(m)); + assertEqualIntA(m, ARCHIVE_EOF, + archive_match_path_unmatched_inclusions_next(m, &mp)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_inclusion_from_file_mbs(void) +{ + struct archive *m; + + /* Test1: read inclusion patterns from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + assertEqualIntA(m, 0, + archive_match_include_pattern_from_file(m, "inclusion", 0)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); + + /* Test2: read inclusion patterns in a null separator from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + assertEqualIntA(m, 0, + archive_match_include_pattern_from_file(m, "inclusion_null", 1)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); +} + +static void +test_inclusion_from_file_wcs(void) +{ + struct archive *m; + + /* Test1: read inclusion patterns from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + /* Test for pattern reading from file */ + assertEqualIntA(m, 0, + archive_match_include_pattern_from_file_w(m, L"inclusion", 0)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); + + /* Test2: read inclusion patterns in a null separator from file */ + if (!assert((m = archive_match_new()) != NULL)) + return; + /* Test for pattern reading from file */ + assertEqualIntA(m, 0, + archive_match_include_pattern_from_file_w(m, L"inclusion_null", 1)); + exclusion_from_file(m); + /* Clean up. */ + archive_match_free(m); +} + +static void +test_exclusion_and_inclusion(void) +{ + struct archive_entry *ae; + struct archive *m; + const char *mp; + const wchar_t *wp; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_exclude_pattern(m, "^aaa*")); + assertEqualIntA(m, 0, archive_match_include_pattern_w(m, L"^aa*")); + assertEqualIntA(m, 0, archive_match_include_pattern(m, "^a1*")); + + /* Test with 'aa1234', which should not be excluded. */ + archive_entry_copy_pathname(ae, "aa1234"); + failure("'aa1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"aa1234"); + failure("'aa1234' should not be excluded"); + assertEqualInt(0, archive_match_path_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Test with 'aaa1234', which should be excluded. */ + archive_entry_copy_pathname(ae, "aaa1234"); + failure("'aaa1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_clear(ae); + archive_entry_copy_pathname_w(ae, L"aaa1234"); + failure("'aaa1234' should be excluded"); + assertEqualInt(1, archive_match_path_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify unmatched_inclusions. */ + assertEqualInt(1, archive_match_path_unmatched_inclusions(m)); + /* Verify unmatched inclusion patterns. */ + assertEqualIntA(m, ARCHIVE_OK, + archive_match_path_unmatched_inclusions_next(m, &mp)); + assertEqualString("^a1*", mp); + assertEqualIntA(m, ARCHIVE_EOF, + archive_match_path_unmatched_inclusions_next(m, &mp)); + /* Verify unmatched inclusion patterns again in Wide-Char. */ + assertEqualIntA(m, ARCHIVE_OK, + archive_match_path_unmatched_inclusions_next_w(m, &wp)); + assertEqualWString(L"^a1*", wp); + assertEqualIntA(m, ARCHIVE_EOF, + archive_match_path_unmatched_inclusions_next_w(m, &wp)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +DEFINE_TEST(test_archive_match_path) +{ + /* Make exclusion sample files which contain exclusion patterns. */ + assertMakeFile("exclusion", 0666, "second\nfour\n"); + assertMakeBinFile("exclusion_null", 0666, 12, "second\0four\0"); + /* Make inclusion sample files which contain inclusion patterns. */ + assertMakeFile("inclusion", 0666, "first\nthird\n"); + assertMakeBinFile("inclusion_null", 0666, 12, "first\0third\0"); + + test_exclusion_mbs(); + test_exclusion_wcs(); + test_exclusion_from_file_mbs(); + test_exclusion_from_file_wcs(); + test_inclusion_mbs(); + test_inclusion_wcs(); + test_inclusion_from_file_mbs(); + test_inclusion_from_file_wcs(); + test_exclusion_and_inclusion(); +} diff --git a/contrib/libarchive/libarchive/test/test_archive_match_time.c b/contrib/libarchive/libarchive/test/test_archive_match_time.c new file mode 100644 index 0000000..c951e0d --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_archive_match_time.c @@ -0,0 +1,1358 @@ +/*- + * Copyright (c) 2012 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$"); + +time_t __archive_get_date(time_t, const char *); + +static void +test_newer_time(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_time(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_NEWER, 7880, 0)); + + archive_entry_copy_pathname(ae, "file1"); + archive_entry_set_mtime(ae, 7880, 0); + archive_entry_set_ctime(ae, 7880, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7879, 999); + archive_entry_set_ctime(ae, 7879, 999); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, 7881, 0); + archive_entry_set_ctime(ae, 7881, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, 7880, 1); + archive_entry_set_ctime(ae, 7880, 0); + failure("Its mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, 7880, 0); + archive_entry_set_ctime(ae, 7880, 1); + failure("Its ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_newer_time_str(void) +{ + struct archive_entry *ae; + struct archive *m; + time_t now, t; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + time(&now); + + assertEqualIntA(m, 0, archive_match_include_date(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_NEWER, "1980/2/1 0:0:0 UTC")); + + /* Test1: Allow newer time. */ + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 1); + archive_entry_set_ctime(ae, t, 0); + failure("Its mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 1); + failure("Its ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + + /* Test2: Allow equal or newer time. */ + assertEqualIntA(m, 0, archive_match_include_date(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL, + "1980/2/1 0:0:0 UTC")); + + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_newer_time_str_w(void) +{ + struct archive_entry *ae; + struct archive *m; + time_t now, t; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + time(&now); + + assertEqualIntA(m, 0, archive_match_include_date_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_NEWER, L"1980/2/1 0:0:0 UTC")); + + /* Test1: Allow newer time. */ + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 1); + archive_entry_set_ctime(ae, t, 0); + failure("Its mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 1); + failure("Its ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + + /* Test2: Allow equal or newer time. */ + assertEqualIntA(m, 0, archive_match_include_date_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_NEWER | ARCHIVE_MATCH_EQUAL, + L"1980/2/1 0:0:0 UTC")); + + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/2/1 0:0:1 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_newer_mtime_than_file_mbs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: newer mtime than a file specified in MBS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "mid_mtime")); + + /* Verify 'old_mtime' file. */ + archive_entry_copy_pathname(ae, "old_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_mtime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_newer_ctime_than_file_mbs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: newer ctime than a file specified in MBS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "mid_ctime")); + + /* Verify 'old_ctime' file. */ + archive_entry_copy_pathname(ae, "old_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_newer_mtime_than_file_wcs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: newer mtime than a file specified in WCS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"mid_mtime")); + + /* Verify 'old_mtime' file. */ + archive_entry_copy_pathname(ae, "old_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_mtime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_newer_ctime_than_file_wcs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: newer ctime than a file specified in WCS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"mid_ctime")); + + /* Verify 'old_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "old_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_time(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + assertEqualIntA(m, 0, archive_match_include_time(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_OLDER, 7880, 0)); + + archive_entry_copy_pathname(ae, "file1"); + archive_entry_set_mtime(ae, 7880, 0); + archive_entry_set_ctime(ae, 7880, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7879, 999); + archive_entry_set_ctime(ae, 7879, 999); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, 7881, 0); + archive_entry_set_ctime(ae, 7881, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, 7880, 1); + archive_entry_set_ctime(ae, 7879, 0); + failure("Its mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + archive_entry_set_mtime(ae, 7879, 0); + archive_entry_set_ctime(ae, 7880, 1); + failure("Its ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_time_str(void) +{ + struct archive_entry *ae; + struct archive *m; + time_t now, t; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + time(&now); + + /* Test1: Allow newer time. */ + assertEqualIntA(m, 0, archive_match_include_date(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_OLDER, "1980/2/1 0:0:0 UTC")); + + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_ctime(ae, t, 0); + failure("Its mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_ctime(ae, t, 0); + failure("Its ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Test2: Allow equal or newer time. */ + assertEqualIntA(m, 0, archive_match_include_date(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL, + "1980/2/1 0:0:0 UTC")); + + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_time_str_w(void) +{ + struct archive_entry *ae; + struct archive *m; + time_t now, t; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + time(&now); + + /* Test1: Allow newer time. */ + assertEqualIntA(m, 0, archive_match_include_date_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_OLDER, L"1980/2/1 0:0:0 UTC")); + + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_ctime(ae, t, 0); + failure("Its mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_ctime(ae, t, 0); + failure("Its ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Test2: Allow equal or newer time. */ + assertEqualIntA(m, 0, archive_match_include_date_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_CTIME | + ARCHIVE_MATCH_OLDER | ARCHIVE_MATCH_EQUAL, + L"1980/2/1 0:0:0 UTC")); + + archive_entry_copy_pathname(ae, "file1"); + t = __archive_get_date(now, "1980/2/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + t = __archive_get_date(now, "1980/1/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + t = __archive_get_date(now, "1980/3/1 0:0:0 UTC"); + archive_entry_set_mtime(ae, t, 0); + archive_entry_set_ctime(ae, t, 0); + failure("Both Its mtime and ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_mtime_than_file_mbs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: older mtime than a file specified in MBS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "mid_mtime")); + + /* Verify 'old_mtime' file. */ + archive_entry_copy_pathname(ae, "old_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_mtime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'mid_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_ctime_than_file_mbs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: older ctime than a file specified in MBS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "mid_ctime")); + + /* Verify 'old_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "old_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'mid_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_mtime_than_file_wcs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: older mtime than a file specified in WCS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"mid_mtime")); + + /* Verify 'old_mtime' file. */ + archive_entry_copy_pathname(ae, "old_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_mtime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'mid_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_older_ctime_than_file_wcs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: older ctime than a file specified in WCS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"mid_ctime")); + + /* Verify 'old_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "old_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'mid_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'new_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_mtime_between_files_mbs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: mtime between file specified in MBS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, "old_mtime")); + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, "new_mtime")); + + /* Verify 'old_mtime' file. */ + archive_entry_copy_pathname(ae, "old_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_mtime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'new_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_mtime_between_files_wcs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: mtime between file specified in WCS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_NEWER, L"old_mtime")); + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER, L"new_mtime")); + + /* Verify 'old_mtime' file. */ + archive_entry_copy_pathname(ae, "old_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_mtime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'new_mtime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_mtime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_mtime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_ctime_between_files_mbs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: ctime between files specified in MBS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, "old_ctime")); + assertEqualIntA(m, 0, archive_match_include_file_time(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, "new_ctime")); + + /* Verify 'old_ctime' file. */ + archive_entry_copy_pathname(ae, "old_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'new_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +test_ctime_between_files_wcs(void) +{ + struct archive *a; + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + if (!assert((a = archive_read_disk_new()) != NULL)) { + archive_match_free(m); + archive_entry_free(ae); + return; + } + + /* + * Test: ctime between files specified in WCS file name. + */ + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_NEWER, L"old_ctime")); + assertEqualIntA(m, 0, archive_match_include_file_time_w(m, + ARCHIVE_MATCH_CTIME | ARCHIVE_MATCH_OLDER, L"new_ctime")); + + /* Verify 'old_ctime' file. */ + archive_entry_copy_pathname(ae, "old_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("old_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Verify 'mid_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "mid_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("mid_ctime should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + /* Verify 'new_ctime' file. */ + archive_entry_clear(ae); + archive_entry_copy_pathname(ae, "new_ctime"); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_entry_from_file(a, ae, -1, NULL)); + failure("new_ctime should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* Clean up. */ + archive_read_free(a); + archive_entry_free(ae); + archive_match_free(m); +} + +static void +excluded(struct archive *m) +{ + struct archive_entry *ae; + + if (!assert((ae = archive_entry_new()) != NULL)) + return; + + archive_entry_copy_pathname(ae, "file1"); + archive_entry_set_mtime(ae, 7879, 999); + failure("It should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 0); + failure("It should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 1); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + archive_entry_copy_pathname(ae, "file2"); + archive_entry_set_mtime(ae, 7879, 999); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 0); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 1); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + archive_entry_copy_pathname(ae, "file3"); + archive_entry_set_mtime(ae, 7879, 999); + failure("It should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 0); + failure("It should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 1); + failure("It should be excluded"); + assertEqualInt(1, archive_match_time_excluded(m, ae)); + assertEqualInt(1, archive_match_excluded(m, ae)); + + /* + * "file4" is not registered, that sort of a file should not be + * excluded with any mtime. + */ + archive_entry_copy_pathname(ae, "file4"); + archive_entry_set_mtime(ae, 7879, 999); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 0); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + archive_entry_set_mtime(ae, 7880, 1); + failure("It should not be excluded"); + assertEqualInt(0, archive_match_time_excluded(m, ae)); + assertEqualInt(0, archive_match_excluded(m, ae)); + + + /* Clean up. */ + archive_entry_free(ae); +} + +static void +test_pathname_newer_mtime(void) +{ + struct archive_entry *ae; + struct archive *m; + + if (!assert((m = archive_match_new()) != NULL)) + return; + if (!assert((ae = archive_entry_new()) != NULL)) { + archive_match_free(m); + return; + } + + archive_entry_copy_pathname(ae, "file1"); + archive_entry_set_mtime(ae, 7880, 0); + assertEqualIntA(m, 0, archive_match_exclude_entry(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | + ARCHIVE_MATCH_EQUAL, ae)); + archive_entry_copy_pathname(ae, "file2"); + archive_entry_set_mtime(ae, 1, 0); + assertEqualIntA(m, 0, archive_match_exclude_entry(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | + ARCHIVE_MATCH_EQUAL, ae)); + archive_entry_copy_pathname(ae, "file3"); + archive_entry_set_mtime(ae, 99999, 0); + assertEqualIntA(m, 0, archive_match_exclude_entry(m, + ARCHIVE_MATCH_MTIME | ARCHIVE_MATCH_OLDER | + ARCHIVE_MATCH_EQUAL, ae)); + + excluded(m); + + /* Clean up. */ + archive_entry_free(ae); + archive_match_free(m); +} + +DEFINE_TEST(test_archive_match_time) +{ + struct stat st; + + /* Test: matching newer times. */ + test_newer_time(); + test_newer_time_str(); + test_newer_time_str_w(); + /* Test: matching older times. */ + test_older_time(); + test_older_time_str(); + test_older_time_str_w(); + + /* + * Create sample files for tests matching mtime. + * ctimes of those files may be all the same or the ctime of + * new_mtime may be older than old_mtime. + */ + assertMakeFile("new_mtime", 0666, "new"); + assertUtimes("new_mtime", 10002, 0, 10002, 0); + assertMakeFile("mid_mtime", 0666, "mid"); + assertUtimes("mid_mtime", 10001, 0, 10001, 0); + assertMakeFile("old_mtime", 0666, "old"); + assertUtimes("old_mtime", 10000, 0, 10000, 0); + + /* + * Create sample files for tests matching ctime. + * the mtime of mid_ctime is older than old_ctime and also the mtime + * of new_ctime is older than both mid_ctime and old_ctime. + */ + assertMakeFile("old_ctime", 0666, "old"); + assertUtimes("old_ctime", 10002, 0, 10002, 0); + assertEqualInt(0, stat("old_ctime", &st)); + sleepUntilAfter(st.st_ctime); + assertMakeFile("mid_ctime", 0666, "mid"); + assertUtimes("mid_ctime", 10001, 0, 10001, 0); + assertEqualInt(0, stat("mid_ctime", &st)); + sleepUntilAfter(st.st_ctime); + assertMakeFile("new_ctime", 0666, "new"); + assertUtimes("new_ctime", 10000, 0, 10000, 0); + + /* + * Test: matching mtime which indicated by files on the disk. + */ + test_newer_mtime_than_file_mbs(); + test_newer_mtime_than_file_wcs(); + test_older_mtime_than_file_mbs(); + test_older_mtime_than_file_wcs(); + test_mtime_between_files_mbs(); + test_mtime_between_files_wcs(); + + /* + * Test: matching ctime which indicated by files on the disk. + */ + test_newer_ctime_than_file_mbs(); + test_newer_ctime_than_file_wcs(); + test_older_ctime_than_file_mbs(); + test_older_ctime_than_file_wcs(); + test_ctime_between_files_mbs(); + test_ctime_between_files_wcs(); + + /* Test: matching both pathname and mtime. */ + test_pathname_newer_mtime(); +} diff --git a/contrib/libarchive/libarchive/test/test_archive_pathmatch.c b/contrib/libarchive/libarchive/test/test_archive_pathmatch.c new file mode 100644 index 0000000..fed6ad7 --- /dev/null +++ b/contrib/libarchive/libarchive/test/test_archive_pathmatch.c @@ -0,0 +1,244 @@ +/*- + * 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$"); + +#define __LIBARCHIVE_TEST +#include "archive_pathmatch.h" + +/* + * Verify that the pattern matcher implements the wildcard logic specified + * in SUSv2 for the cpio command. This is essentially the + * shell glob syntax: + * * - matches any sequence of chars, including '/' + * ? - matches any single char, including '/' + * [...] - matches any of a set of chars, '-' specifies a range, + * initial '!' is undefined + * + * The specification in SUSv2 is a bit incomplete, I assume the following: + * Trailing '-' in [...] is not special. + * + * TODO: Figure out if there's a good way to extend this to handle + * Windows paths that use '\' as a path separator. <sigh> + */ + +DEFINE_TEST(test_archive_pathmatch) +{ + assertEqualInt(1, archive_pathmatch("a/b/c", "a/b/c", 0)); + assertEqualInt(0, archive_pathmatch("a/b/", "a/b/c", 0)); + assertEqualInt(0, archive_pathmatch("a/b", "a/b/c", 0)); + assertEqualInt(0, archive_pathmatch("a/b/c", "a/b/", 0)); + assertEqualInt(0, archive_pathmatch("a/b/c", "a/b", 0)); + + /* Empty pattern only matches empty string. */ + assertEqualInt(1, archive_pathmatch("","", 0)); + assertEqualInt(0, archive_pathmatch("","a", 0)); + assertEqualInt(1, archive_pathmatch("*","", 0)); + assertEqualInt(1, archive_pathmatch("*","a", 0)); + assertEqualInt(1, archive_pathmatch("*","abcd", 0)); + /* SUSv2: * matches / */ + assertEqualInt(1, archive_pathmatch("*","abcd/efgh/ijkl", 0)); + assertEqualInt(1, archive_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0)); + assertEqualInt(1, archive_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0)); + assertEqualInt(1, archive_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0)); + assertEqualInt(0, archive_pathmatch("?", "", 0)); + assertEqualInt(0, archive_pathmatch("?", "\0", 0)); + assertEqualInt(1, archive_pathmatch("?", "a", 0)); + assertEqualInt(0, archive_pathmatch("?", "ab", 0)); + assertEqualInt(1, archive_pathmatch("?", ".", 0)); + assertEqualInt(1, archive_pathmatch("?", "?", 0)); + assertEqualInt(1, archive_pathmatch("a", "a", 0)); + assertEqualInt(0, archive_pathmatch("a", "ab", 0)); + assertEqualInt(0, archive_pathmatch("a", "ab", 0)); + assertEqualInt(1, archive_pathmatch("a?c", "abc", 0)); + /* SUSv2: ? matches / */ + assertEqualInt(1, archive_pathmatch("a?c", "a/c", 0)); + assertEqualInt(1, archive_pathmatch("a?*c*", "a/c", 0)); + assertEqualInt(1, archive_pathmatch("*a*", "a/c", 0)); + assertEqualInt(1, archive_pathmatch("*a*", "/a/c", 0)); + assertEqualInt(1, archive_pathmatch("*a*", "defaaaaaaa", 0)); + assertEqualInt(0, archive_pathmatch("a*", "defghi", 0)); + assertEqualInt(0, archive_pathmatch("*a*", "defghi", 0)); + + /* Character classes */ + assertEqualInt(1, archive_pathmatch("abc[def", "abc[def", 0)); + assertEqualInt(0, archive_pathmatch("abc[def]", "abc[def", 0)); + assertEqualInt(0, archive_pathmatch("abc[def", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[def]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[def]", "abce", 0)); + assertEqualInt(1, archive_pathmatch("abc[def]", "abcf", 0)); + assertEqualInt(0, archive_pathmatch("abc[def]", "abcg", 0)); + assertEqualInt(1, archive_pathmatch("abc[d*f]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[d*f]", "abc*", 0)); + assertEqualInt(0, archive_pathmatch("abc[d*f]", "abcdefghi", 0)); + assertEqualInt(0, archive_pathmatch("abc[d*", "abcdefghi", 0)); + assertEqualInt(1, archive_pathmatch("abc[d*", "abc[defghi", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-f]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-f]", "abce", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-f]", "abcf", 0)); + assertEqualInt(0, archive_pathmatch("abc[d-f]", "abcg", 0)); + assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abca", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abce", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcf", 0)); + assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abcg", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abch", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abci", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abcj", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-k]", "abck", 0)); + assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abcl", 0)); + assertEqualInt(0, archive_pathmatch("abc[d-fh-k]", "abc-", 0)); + + /* [] matches nothing, [!] is the same as ? */ + assertEqualInt(0, archive_pathmatch("abc[]efg", "abcdefg", 0)); + assertEqualInt(0, archive_pathmatch("abc[]efg", "abcqefg", 0)); + assertEqualInt(0, archive_pathmatch("abc[]efg", "abcefg", 0)); + assertEqualInt(1, archive_pathmatch("abc[!]efg", "abcdefg", 0)); + assertEqualInt(1, archive_pathmatch("abc[!]efg", "abcqefg", 0)); + assertEqualInt(0, archive_pathmatch("abc[!]efg", "abcefg", 0)); + + /* I assume: Trailing '-' is non-special. */ + assertEqualInt(0, archive_pathmatch("abc[d-fh-]", "abcl", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abch", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abc-", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-fh-]", "abc-", 0)); + + /* ']' can be backslash-quoted within a character class. */ + assertEqualInt(1, archive_pathmatch("abc[\\]]", "abc]", 0)); + assertEqualInt(1, archive_pathmatch("abc[\\]d]", "abc]", 0)); + assertEqualInt(1, archive_pathmatch("abc[\\]d]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[d\\]]", "abc]", 0)); + assertEqualInt(1, archive_pathmatch("abc[d\\]]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[d]e]", "abcde]", 0)); + assertEqualInt(1, archive_pathmatch("abc[d\\]e]", "abc]", 0)); + assertEqualInt(0, archive_pathmatch("abc[d\\]e]", "abcd]e", 0)); + assertEqualInt(0, archive_pathmatch("abc[d]e]", "abc]", 0)); + + /* backslash-quoted chars can appear as either end of a range. */ + assertEqualInt(1, archive_pathmatch("abc[\\d-f]gh", "abcegh", 0)); + assertEqualInt(0, archive_pathmatch("abc[\\d-f]gh", "abcggh", 0)); + assertEqualInt(0, archive_pathmatch("abc[\\d-f]gh", "abc\\gh", 0)); + assertEqualInt(1, archive_pathmatch("abc[d-\\f]gh", "abcegh", 0)); + assertEqualInt(1, archive_pathmatch("abc[\\d-\\f]gh", "abcegh", 0)); + assertEqualInt(1, archive_pathmatch("abc[\\d-\\f]gh", "abcegh", 0)); + /* backslash-quoted '-' isn't special. */ + assertEqualInt(0, archive_pathmatch("abc[d\\-f]gh", "abcegh", 0)); + assertEqualInt(1, archive_pathmatch("abc[d\\-f]gh", "abc-gh", 0)); + + /* Leading '!' negates a character class. */ + assertEqualInt(0, archive_pathmatch("abc[!d]", "abcd", 0)); + assertEqualInt(1, archive_pathmatch("abc[!d]", "abce", 0)); + assertEqualInt(1, archive_pathmatch("abc[!d]", "abcc", 0)); + assertEqualInt(0, archive_pathmatch("abc[!d-z]", "abcq", 0)); + assertEqualInt(1, archive_pathmatch("abc[!d-gi-z]", "abch", 0)); + assertEqualInt(1, archive_pathmatch("abc[!fgijkl]", "abch", 0)); + assertEqualInt(0, archive_pathmatch("abc[!fghijkl]", "abch", 0)); + + /* Backslash quotes next character. */ + assertEqualInt(0, archive_pathmatch("abc\\[def]", "abc\\d", 0)); + assertEqualInt(1, archive_pathmatch("abc\\[def]", "abc[def]", 0)); + assertEqualInt(0, archive_pathmatch("abc\\\\[def]", "abc[def]", 0)); + assertEqualInt(0, archive_pathmatch("abc\\\\[def]", "abc\\[def]", 0)); + assertEqualInt(1, archive_pathmatch("abc\\\\[def]", "abc\\d", 0)); + assertEqualInt(1, archive_pathmatch("abcd\\", "abcd\\", 0)); + assertEqualInt(0, archive_pathmatch("abcd\\", "abcd\\[", 0)); + assertEqualInt(0, archive_pathmatch("abcd\\", "abcde", 0)); + assertEqualInt(0, archive_pathmatch("abcd\\[", "abcd\\", 0)); + + /* + * Because '.' and '/' have special meanings, we can + * identify many equivalent paths even if they're expressed + * differently. (But quoting a character with '\\' suppresses + * special meanings!) + */ + assertEqualInt(0, archive_pathmatch("a/b/", "a/bc", 0)); + assertEqualInt(1, archive_pathmatch("a/./b", "a/b", 0)); + assertEqualInt(0, archive_pathmatch("a\\/./b", "a/b", 0)); + assertEqualInt(0, archive_pathmatch("a/\\./b", "a/b", 0)); + assertEqualInt(0, archive_pathmatch("a/.\\/b", "a/b", 0)); + assertEqualInt(0, archive_pathmatch("a\\/\\.\\/b", "a/b", 0)); + assertEqualInt(1, archive_pathmatch("./abc/./def/", "abc/def/", 0)); + assertEqualInt(1, archive_pathmatch("abc/def", "./././abc/./def", 0)); + assertEqualInt(1, archive_pathmatch("abc/def/././//", "./././abc/./def/", 0)); + assertEqualInt(1, archive_pathmatch(".////abc/.//def", "./././abc/./def", 0)); + assertEqualInt(1, archive_pathmatch("./abc?def/", "abc/def/", 0)); + failure("\"?./\" is not the same as \"/./\""); + assertEqualInt(0, archive_pathmatch("./abc?./def/", "abc/def/", 0)); + failure("Trailing '/' should match no trailing '/'"); + assertEqualInt(1, archive_pathmatch("./abc/./def/", "abc/def", 0)); + failure("Trailing '/./' is still the same directory."); + assertEqualInt(1, archive_pathmatch("./abc/./def/./", "abc/def", 0)); + failure("Trailing '/.' is still the same directory."); + assertEqualInt(1, archive_pathmatch("./abc/./def/.", "abc/def", 0)); + assertEqualInt(1, archive_pathmatch("./abc/./def", "abc/def/", 0)); + failure("Trailing '/./' is still the same directory."); + assertEqualInt(1, archive_pathmatch("./abc/./def", "abc/def/./", 0)); + failure("Trailing '/.' is still the same directory."); + assertEqualInt(1, archive_pathmatch("./abc*/./def", "abc/def/.", 0)); + + /* Matches not anchored at beginning. */ + assertEqualInt(0, + archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START)); + assertEqualInt(1, + archive_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START)); + assertEqualInt(0, + archive_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START)); + assertEqualInt(1, + archive_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); + assertEqualInt(0, + archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); + assertEqualInt(0, + archive_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START)); + + /* Matches not anchored at end. */ + assertEqualInt(0, + archive_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(0, + archive_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(0, + archive_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(0, + archive_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(1, + archive_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END)); + assertEqualInt(0, + archive_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END)); +} diff --git a/contrib/libarchive/libarchive/test/test_archive_string_conversion.c b/contrib/libarchive/libarchive/test/test_archive_string_conversion.c index 8b833ea..fea141d 100644 --- a/contrib/libarchive/libarchive/test/test_archive_string_conversion.c +++ b/contrib/libarchive/libarchive/test/test_archive_string_conversion.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2011 Michihiro NAKAJIMA + * Copyright (c) 2011-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD$"); Execute the following to rebuild the data for this program: tail -n +36 test_archive_string_conversion.c | /bin/sh # -# This requires http://unicode.org/Public/UNIDATA/NormalizationTest.txt +# This requires http://unicode.org/Public/6.0.0/ucd/NormalizationTest.txt # if="NormalizationTest.txt" if [ ! -f ${if} ]; then @@ -158,7 +158,7 @@ unicode_to_wc(wchar_t *wp, uint32_t uc) */ static int scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le, - const char *pattern, int exclude_mac_nfd) + const char *pattern, int mac_nfd) { unsigned uc = 0; const char *p = pattern; @@ -166,6 +166,7 @@ scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le, wchar_t *owp = wout; char *op16be = u16be; char *op16le = u16le; + int ret = 0; for (;;) { if (*p >= '0' && *p <= '9') @@ -173,14 +174,31 @@ scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le, else if (*p >= 'A' && *p <= 'F') uc = (uc << 4) + (*p - 'A' + 0x0a); else { - if (exclude_mac_nfd) { + if (mac_nfd && op == out) { /* * These are not converted to NFD on Mac OS. + * U+2000 - U+2FFF + * U+F900 - U+FAFF + * U+2F800 - U+2FAFF */ - if ((uc >= 0x2000 && uc <= 0x2FFF) || - (uc >= 0xF900 && uc <= 0xFAFF) || - (uc >= 0x2F800 && uc <= 0x2FAFF)) - return (-1); + switch (uc) { + case 0x2194: case 0x219A: case 0x219B: + case 0x21AE: case 0x21CD: case 0x21CE: + case 0x21CF: case 0x2204: case 0x2209: + case 0x220C: case 0x2224: case 0x2226: + case 0x2241: case 0x2244: case 0x2247: + case 0x2249: case 0x2260: case 0x2262: + case 0x226D: case 0x226E: case 0x226F: + case 0x2270: case 0x2271: case 0x2274: + case 0x2275: case 0x2276: case 0x2278: + case 0x2279: case 0x227A: case 0x227B: + case 0x2280: case 0x2281: case 0x2284: + case 0x2285: case 0x2288: case 0x2289: + case 0x22AC: case 0x22AD: case 0x22AE: + case 0x22AF: case 0x22E0: case 0x22E1: + case 0x22E2: case 0x22E3: case 0x22EA: + case 0x22EB: case 0x22EC: case 0x22ED: + /* * Those code points are not converted to * NFD on Mac OS. I do not know the reason @@ -190,9 +208,10 @@ scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le, * 1109C ==> 1109B 110BA * 110AB ==> 110A5 110BA */ - if (uc == 0x1109A || uc == 0x1109C || - uc == 0x110AB) - return (-1); + case 0x1109A: case 0x1109C: case 0x110AB: + ret = 1; + break; + } } op16be += unicode_to_utf16be(op16be, uc); op16le += unicode_to_utf16le(op16le, uc); @@ -211,7 +230,7 @@ scan_unicode_pattern(char *out, wchar_t *wout, char *u16be, char *u16le, } p++; } - return (0); + return (ret); } static int @@ -230,27 +249,26 @@ is_wc_unicode(void) * On other platforms, the characters to be Form C. */ static void -test_archive_string_normalization(void) +test_archive_string_normalization_nfc(const char *testdata) { struct archive *a, *a2; - struct archive_entry *ae; struct archive_string utf8; struct archive_mstring mstr; struct archive_string_conv *f_sconv8, *t_sconv8; struct archive_string_conv *f_sconv16be, *f_sconv16le; FILE *fp; char buff[512]; - static const char reffile[] = "test_archive_string_conversion.txt.Z"; - ssize_t size; int line = 0; int locale_is_utf8, wc_is_unicode; + int sconv_opt = SCONV_SET_OPT_NORMALIZATION_C; locale_is_utf8 = (NULL != setlocale(LC_ALL, "en_US.UTF-8")); wc_is_unicode = is_wc_unicode(); /* If it doesn't exist, just warn and return. */ if (!locale_is_utf8 && !wc_is_unicode) { - skipping("invalid encoding tests require a suitable locale;" - " en_US.UTF-8 not available on this system"); + skipping("A test of string normalization for NFC requires " + "a suitable locale; en_US.UTF-8 not available on this " + "system"); return; } @@ -258,27 +276,9 @@ test_archive_string_normalization(void) memset(&mstr, 0, sizeof(mstr)); /* - * Extract a test pattern file. - */ - extract_reference_file(reffile); - assert((a = archive_read_new()) != NULL); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); - assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); - assertEqualIntA(a, ARCHIVE_OK, - archive_read_open_filename(a, reffile, 512)); - - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assert((fp = fopen("testdata.txt", "w")) != NULL); - while ((size = archive_read_data(a, buff, 512)) > 0) - fwrite(buff, 1, size, fp); - fclose(fp); - - /* Open a test pattern file. */ - assert((fp = fopen("testdata.txt", "r")) != NULL); - - /* * Create string conversion objects. */ + assert((a = archive_read_new()) != NULL); assertA(NULL != (f_sconv8 = archive_string_conversion_from_charset(a, "UTF-8", 0))); assertA(NULL != (f_sconv16be = @@ -289,13 +289,18 @@ test_archive_string_normalization(void) assertA(NULL != (t_sconv8 = archive_string_conversion_to_charset(a2, "UTF-8", 0))); if (f_sconv8 == NULL || f_sconv16be == NULL || f_sconv16le == NULL || - t_sconv8 == NULL || fp == NULL) { + t_sconv8 == NULL) { /* We cannot continue this test. */ - if (fp != NULL) - fclose(fp); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); return; } + archive_string_conversion_set_opt(f_sconv8, sconv_opt); + archive_string_conversion_set_opt(f_sconv16be, sconv_opt); + archive_string_conversion_set_opt(f_sconv16le, sconv_opt); + archive_string_conversion_set_opt(t_sconv8, sconv_opt); + + /* Open a test pattern file. */ + assert((fp = fopen(testdata, "r")) != NULL); /* * Read test data. @@ -311,6 +316,9 @@ test_archive_string_normalization(void) char utf16le_nfc[80], utf16le_nfd[80]; wchar_t wc_nfc[40], wc_nfd[40]; char *e, *p; + const wchar_t *wp; + const char *mp; + size_t mplen; line++; if (buff[0] == '#') @@ -332,74 +340,22 @@ test_archive_string_normalization(void) nfd[sizeof(nfd)-1] = '\0'; /* - * Convert an NFC pattern to UTF-8 bytes. + * Get an NFC patterns. */ -#if defined(__APPLE__) - if (scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc, - nfc, 1) != 0) - continue; -#else scan_unicode_pattern(utf8_nfc, wc_nfc, utf16be_nfc, utf16le_nfc, nfc, 0); -#endif /* - * Convert an NFD pattern to UTF-8 bytes. + * Get an NFD patterns. */ scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd, nfd, 0); if (locale_is_utf8) { -#if defined(__APPLE__) - /* - * Normalize an NFC string for import. - */ - assertEqualInt(0, archive_strcpy_in_locale( - &utf8, utf8_nfc, f_sconv8)); - failure("NFC(%s) should be converted to NFD(%s):%d", - nfc, nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - - /* - * Normalize an NFD string for import. - */ - assertEqualInt(0, archive_strcpy_in_locale( - &utf8, utf8_nfd, f_sconv8)); - failure("NFD(%s) should not be any changed:%d", - nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - - /* - * Copy an NFD string for export. - */ - assertEqualInt(0, archive_strcpy_in_locale( - &utf8, utf8_nfd, t_sconv8)); - failure("NFD(%s) should not be any changed:%d", - nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - - /* - * Normalize an NFC string in UTF-16BE for import. - */ - assertEqualInt(0, archive_strncpy_in_locale( - &utf8, utf16be_nfc, 100000, f_sconv16be)); - failure("NFC(%s) should be converted to NFD(%s):%d", - nfc, nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); - - /* - * Normalize an NFC string in UTF-16LE for import. - */ - assertEqualInt(0, archive_strncpy_in_locale( - &utf8, utf16le_nfc, 100000, f_sconv16le)); - failure("NFC(%s) should be converted to NFD(%s):%d", - nfc, nfd, line); - assertEqualUTF8String(utf8_nfd, utf8.s); -#else /* * Normalize an NFD string for import. */ - assertEqualInt(0, archive_strcpy_in_locale( + assertEqualInt(0, archive_strcpy_l( &utf8, utf8_nfd, f_sconv8)); failure("NFD(%s) should be converted to NFC(%s):%d", nfd, nfc, line); @@ -408,7 +364,7 @@ test_archive_string_normalization(void) /* * Normalize an NFC string for import. */ - assertEqualInt(0, archive_strcpy_in_locale( + assertEqualInt(0, archive_strcpy_l( &utf8, utf8_nfc, f_sconv8)); failure("NFC(%s) should not be any changed:%d", nfc, line); @@ -417,7 +373,7 @@ test_archive_string_normalization(void) /* * Copy an NFC string for export. */ - assertEqualInt(0, archive_strcpy_in_locale( + assertEqualInt(0, archive_strcpy_l( &utf8, utf8_nfc, t_sconv8)); failure("NFC(%s) should not be any changed:%d", nfc, line); @@ -426,7 +382,7 @@ test_archive_string_normalization(void) /* * Normalize an NFD string in UTF-16BE for import. */ - assertEqualInt(0, archive_strncpy_in_locale( + assertEqualInt(0, archive_strncpy_l( &utf8, utf16be_nfd, 100000, f_sconv16be)); failure("NFD(%s) should be converted to NFC(%s):%d", nfd, nfc, line); @@ -435,12 +391,11 @@ test_archive_string_normalization(void) /* * Normalize an NFD string in UTF-16LE for import. */ - assertEqualInt(0, archive_strncpy_in_locale( + assertEqualInt(0, archive_strncpy_l( &utf8, utf16le_nfd, 100000, f_sconv16le)); failure("NFD(%s) should be converted to NFC(%s):%d", nfd, nfc, line); assertEqualUTF8String(utf8_nfc, utf8.s); -#endif } /* @@ -451,99 +406,299 @@ test_archive_string_normalization(void) * locale UTF-8. */ if (locale_is_utf8 || wc_is_unicode) { - const wchar_t *wp; - const char *mp; - size_t mplen; - -#if defined(__APPLE__) /* * Normalize an NFD string in UTF-8 for import. */ assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf8_nfc, 100000, f_sconv8)); + &mstr, utf8_nfd, 100000, f_sconv8)); assertEqualInt(0, archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFC(%s) should be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfd, wp); + failure("UTF-8 NFD(%s) should be converted " + "to WCS NFC(%s):%d", nfd, nfc, line); + assertEqualWString(wc_nfc, wp); /* * Normalize an NFD string in UTF-16BE for import. */ assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16be_nfc, 100000, f_sconv16be)); + &mstr, utf16be_nfd, 100000, f_sconv16be)); assertEqualInt(0, archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-16BE NFC(%s) should be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfd, wp); + failure("UTF-8 NFD(%s) should be converted " + "to WCS NFC(%s):%d", nfd, nfc, line); + assertEqualWString(wc_nfc, wp); /* * Normalize an NFD string in UTF-16LE for import. */ assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16le_nfc, 100000, f_sconv16le)); + &mstr, utf16le_nfd, 100000, f_sconv16le)); assertEqualInt(0, archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-16LE NFC(%s) should be converted " - "to WCS NFD(%s):%d", nfc, nfd, line); - assertEqualWString(wc_nfd, wp); + failure("UTF-8 NFD(%s) should be converted " + "to WCS NFC(%s):%d", nfd, nfc, line); + assertEqualWString(wc_nfc, wp); /* - * Copy an NFD wide-string for export. + * Copy an NFC wide-string for export. */ - assertEqualInt(0, archive_mstring_copy_wcs( - &mstr, wc_nfd)); + assertEqualInt(0, + archive_mstring_copy_wcs(&mstr, wc_nfc)); assertEqualInt(0, archive_mstring_get_mbs_l( &mstr, &mp, &mplen, t_sconv8)); - failure("WCS NFD(%s) should be UTF-8 NFD:%d" - ,nfd, line); - assertEqualUTF8String(utf8_nfd, mp); -#else + failure("WCS NFC(%s) should be UTF-8 NFC:%d" + ,nfc, line); + assertEqualUTF8String(utf8_nfc, mp); + } + } + + archive_string_free(&utf8); + archive_mstring_clean(&mstr); + fclose(fp); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a2)); +} + +static void +test_archive_string_normalization_mac_nfd(const char *testdata) +{ + struct archive *a, *a2; + struct archive_string utf8; + struct archive_mstring mstr; + struct archive_string_conv *f_sconv8, *t_sconv8; + struct archive_string_conv *f_sconv16be, *f_sconv16le; + FILE *fp; + char buff[512]; + int line = 0; + int locale_is_utf8, wc_is_unicode; + int sconv_opt = SCONV_SET_OPT_NORMALIZATION_D; + + locale_is_utf8 = (NULL != setlocale(LC_ALL, "en_US.UTF-8")); + wc_is_unicode = is_wc_unicode(); + /* If it doesn't exist, just warn and return. */ + if (!locale_is_utf8 && !wc_is_unicode) { + skipping("A test of string normalization for NFD requires " + "a suitable locale; en_US.UTF-8 not available on this " + "system"); + return; + } + + archive_string_init(&utf8); + memset(&mstr, 0, sizeof(mstr)); + + /* + * Create string conversion objects. + */ + assert((a = archive_read_new()) != NULL); + assertA(NULL != (f_sconv8 = + archive_string_conversion_from_charset(a, "UTF-8", 0))); + assertA(NULL != (f_sconv16be = + archive_string_conversion_from_charset(a, "UTF-16BE", 0))); + assertA(NULL != (f_sconv16le = + archive_string_conversion_from_charset(a, "UTF-16LE", 0))); + assert((a2 = archive_write_new()) != NULL); + assertA(NULL != (t_sconv8 = + archive_string_conversion_to_charset(a2, "UTF-8", 0))); + if (f_sconv8 == NULL || f_sconv16be == NULL || f_sconv16le == NULL || + t_sconv8 == NULL) { + /* We cannot continue this test. */ + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + archive_string_conversion_set_opt(f_sconv8, sconv_opt); + archive_string_conversion_set_opt(f_sconv16be, sconv_opt); + archive_string_conversion_set_opt(f_sconv16le, sconv_opt); + archive_string_conversion_set_opt(t_sconv8, sconv_opt); + + /* Open a test pattern file. */ + assert((fp = fopen(testdata, "r")) != NULL); + + /* + * Read test data. + * Test data format: + * <NFC Unicode pattern> ';' <NFD Unicode pattern> '\n' + * Unicode pattern format: + * [0-9A-F]{4,5}([ ][0-9A-F]{4,5}){0,} + */ + while (fgets(buff, sizeof(buff), fp) != NULL) { + char nfc[80], nfd[80]; + char utf8_nfc[80], utf8_nfd[80]; + char utf16be_nfc[80], utf16be_nfd[80]; + char utf16le_nfc[80], utf16le_nfd[80]; + wchar_t wc_nfc[40], wc_nfd[40]; + char *e, *p; + const wchar_t *wp; + const char *mp; + size_t mplen; + int should_be_nfc; + + line++; + if (buff[0] == '#') + continue; + p = strchr(buff, ';'); + if (p == NULL) + continue; + *p++ = '\0'; + /* Copy an NFC pattern */ + strncpy(nfc, buff, sizeof(nfc)-1); + nfc[sizeof(nfc)-1] = '\0'; + e = p; + p = strchr(p, '\n'); + if (p == NULL) + continue; + *p = '\0'; + /* Copy an NFD pattern */ + strncpy(nfd, e, sizeof(nfd)-1); + nfd[sizeof(nfd)-1] = '\0'; + + /* + * Get an NFC patterns. + */ + should_be_nfc = scan_unicode_pattern(utf8_nfc, wc_nfc, + utf16be_nfc, utf16le_nfc, nfc, 1); + + /* + * Get an NFD patterns. + */ + scan_unicode_pattern(utf8_nfd, wc_nfd, utf16be_nfd, utf16le_nfd, + nfd, 0); + + if (locale_is_utf8) { + /* + * Normalize an NFC string for import. + */ + assertEqualInt(0, archive_strcpy_l( + &utf8, utf8_nfc, f_sconv8)); + if (should_be_nfc) { + failure("NFC(%s) should not be converted to" + " NFD(%s):%d", nfc, nfd, line); + assertEqualUTF8String(utf8_nfc, utf8.s); + } else { + failure("NFC(%s) should be converted to" + " NFD(%s):%d", nfc, nfd, line); + assertEqualUTF8String(utf8_nfd, utf8.s); + } + + /* + * Normalize an NFD string for import. + */ + assertEqualInt(0, archive_strcpy_l( + &utf8, utf8_nfd, f_sconv8)); + failure("NFD(%s) should not be any changed:%d", + nfd, line); + assertEqualUTF8String(utf8_nfd, utf8.s); + + /* + * Copy an NFD string for export. + */ + assertEqualInt(0, archive_strcpy_l( + &utf8, utf8_nfd, t_sconv8)); + failure("NFD(%s) should not be any changed:%d", + nfd, line); + assertEqualUTF8String(utf8_nfd, utf8.s); + + /* + * Normalize an NFC string in UTF-16BE for import. + */ + assertEqualInt(0, archive_strncpy_l( + &utf8, utf16be_nfc, 100000, f_sconv16be)); + if (should_be_nfc) { + failure("NFC(%s) should not be converted to" + " NFD(%s):%d", nfc, nfd, line); + assertEqualUTF8String(utf8_nfc, utf8.s); + } else { + failure("NFC(%s) should be converted to" + " NFD(%s):%d", nfc, nfd, line); + assertEqualUTF8String(utf8_nfd, utf8.s); + } + + /* + * Normalize an NFC string in UTF-16LE for import. + */ + assertEqualInt(0, archive_strncpy_l( + &utf8, utf16le_nfc, 100000, f_sconv16le)); + if (should_be_nfc) { + failure("NFC(%s) should not be converted to" + " NFD(%s):%d", nfc, nfd, line); + assertEqualUTF8String(utf8_nfc, utf8.s); + } else { + failure("NFC(%s) should be converted to" + " NFD(%s):%d", nfc, nfd, line); + assertEqualUTF8String(utf8_nfd, utf8.s); + } + } + + /* + * Test for archive_mstring interface. + * In specific, Windows platform UTF-16BE is directly + * converted to/from wide-character to avoid the effect of + * current locale since windows platform cannot make + * locale UTF-8. + */ + if (locale_is_utf8 || wc_is_unicode) { /* * Normalize an NFD string in UTF-8 for import. */ assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf8_nfd, 100000, f_sconv8)); + &mstr, utf8_nfc, 100000, f_sconv8)); assertEqualInt(0, archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFD(%s) should be converted " - "to WCS NFC(%s):%d", nfd, nfc, line); - assertEqualWString(wc_nfc, wp); + if (should_be_nfc) { + failure("UTF-8 NFC(%s) should not be converted " + "to WCS NFD(%s):%d", nfc, nfd, line); + assertEqualWString(wc_nfc, wp); + } else { + failure("UTF-8 NFC(%s) should be converted " + "to WCS NFD(%s):%d", nfc, nfd, line); + assertEqualWString(wc_nfd, wp); + } /* * Normalize an NFD string in UTF-16BE for import. */ assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16be_nfd, 100000, f_sconv16be)); + &mstr, utf16be_nfc, 100000, f_sconv16be)); assertEqualInt(0, archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFD(%s) should be converted " - "to WCS NFC(%s):%d", nfd, nfc, line); - assertEqualWString(wc_nfc, wp); + if (should_be_nfc) { + failure("UTF-16BE NFC(%s) should not be " + "converted to WCS NFD(%s):%d", + nfc, nfd, line); + assertEqualWString(wc_nfc, wp); + } else { + failure("UTF-16BE NFC(%s) should be converted " + "to WCS NFD(%s):%d", nfc, nfd, line); + assertEqualWString(wc_nfd, wp); + } /* * Normalize an NFD string in UTF-16LE for import. */ assertEqualInt(0, archive_mstring_copy_mbs_len_l( - &mstr, utf16le_nfd, 100000, f_sconv16le)); + &mstr, utf16le_nfc, 100000, f_sconv16le)); assertEqualInt(0, archive_mstring_get_wcs(a, &mstr, &wp)); - failure("UTF-8 NFD(%s) should be converted " - "to WCS NFC(%s):%d", nfd, nfc, line); - assertEqualWString(wc_nfc, wp); + if (should_be_nfc) { + failure("UTF-16LE NFC(%s) should not be " + "converted to WCS NFD(%s):%d", + nfc, nfd, line); + assertEqualWString(wc_nfc, wp); + } else { + failure("UTF-16LE NFC(%s) should be converted " + "to WCS NFD(%s):%d", nfc, nfd, line); + assertEqualWString(wc_nfd, wp); + } /* - * Copy an NFC wide-string for export. + * Copy an NFD wide-string for export. */ assertEqualInt(0, archive_mstring_copy_wcs( - &mstr, wc_nfc)); + &mstr, wc_nfd)); assertEqualInt(0, archive_mstring_get_mbs_l( &mstr, &mp, &mplen, t_sconv8)); - failure("WCS NFC(%s) should be UTF-8 NFC:%d" - ,nfc, line); - assertEqualUTF8String(utf8_nfc, mp); -#endif + failure("WCS NFD(%s) should be UTF-8 NFD:%d" + ,nfd, line); + assertEqualUTF8String(utf8_nfd, mp); } } @@ -624,6 +779,32 @@ test_archive_string_canonicalization(void) DEFINE_TEST(test_archive_string_conversion) { - test_archive_string_normalization(); + static const char reffile[] = "test_archive_string_conversion.txt.Z"; + static const char testdata[] = "testdata.txt"; + struct archive *a; + struct archive_entry *ae; + char buff[512]; + ssize_t size; + FILE *fp; + + /* + * Extract a test pattern file. + */ + extract_reference_file(reffile); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_filename(a, reffile, 512)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assert((fp = fopen(testdata, "w")) != NULL); + while ((size = archive_read_data(a, buff, 512)) > 0) + fwrite(buff, 1, size, fp); + fclose(fp); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + + test_archive_string_normalization_nfc(testdata); + test_archive_string_normalization_mac_nfd(testdata); test_archive_string_canonicalization(); } diff --git a/contrib/libarchive/libarchive/test/test_compat_zip.c b/contrib/libarchive/libarchive/test/test_compat_zip.c index 9785d42..3ebf28c 100644 --- a/contrib/libarchive/libarchive/test/test_compat_zip.c +++ b/contrib/libarchive/libarchive/test/test_compat_zip.c @@ -238,19 +238,19 @@ test_compat_zip_5(void) assertEqualString("Metadata/Job_PT.xml", archive_entry_pathname(ae)); assertEqualInt(3559, archive_entry_size(ae)); assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0777, archive_entry_perm(ae)); + assertEqualInt(0666, archive_entry_perm(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae)); assertEqualInt(456, archive_entry_size(ae)); assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0777, archive_entry_perm(ae)); + assertEqualInt(0666, archive_entry_perm(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae)); assertEqualInt(1495, archive_entry_size(ae)); assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0777, archive_entry_perm(ae)); + assertEqualInt(0666, archive_entry_perm(ae)); /* TODO: Read some of the file data and verify it. The code to read uncompressed Zip entries with "file at end" semantics is tricky and should be verified more carefully. */ @@ -298,21 +298,21 @@ test_compat_zip_5(void) assertEqualInt(0, archive_entry_size(ae)); assert(!archive_entry_size_is_set(ae)); assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0777, archive_entry_perm(ae)); + assertEqualInt(0666, archive_entry_perm(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("Metadata/MXDC_Empty_PT.xml", archive_entry_pathname(ae)); assertEqualInt(0, archive_entry_size(ae)); assert(!archive_entry_size_is_set(ae)); assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0777, archive_entry_perm(ae)); + assertEqualInt(0666, archive_entry_perm(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("Documents/1/Metadata/Page1_Thumbnail.JPG", archive_entry_pathname(ae)); assertEqualInt(0, archive_entry_size(ae)); assert(!archive_entry_size_is_set(ae)); assertEqualInt(AE_IFREG, archive_entry_filetype(ae)); - assertEqualInt(0777, archive_entry_perm(ae)); + assertEqualInt(0666, archive_entry_perm(ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualString("Documents/1/Pages/_rels/1.fpage.rels", archive_entry_pathname(ae)); @@ -420,7 +420,7 @@ test_compat_zip_7(void) for (i = 1; i < 1000; ++i) { assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); - assertEqualIntA(a, ARCHIVE_OK, read_open_memory2(a, p, s, i)); + assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, i)); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_skip(a)); diff --git a/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c b/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c index 6741ee1..3ecfbc2 100644 --- a/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c +++ b/contrib/libarchive/libarchive/test/test_read_disk_directory_traversals.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010 Michihiro NAKAJIMA + * Copyright (c) 2010-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -66,6 +66,9 @@ test_basic(void) size_t size; int64_t offset; int file_count; +#if defined(_WIN32) && !defined(__CYGWIN__) + wchar_t *wcwd, *wp, *fullpath; +#endif assertMakeDir("dir1", 0755); assertMakeFile("dir1/file1", 0644, "0123456789"); @@ -89,6 +92,7 @@ test_basic(void) assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "dir1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -102,6 +106,7 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -115,9 +120,11 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -131,9 +138,11 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -147,6 +156,7 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -160,15 +170,19 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub3") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub3/file") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -182,6 +196,7 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 3); + assertEqualInt(0, archive_read_disk_can_descend(a)); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ @@ -205,6 +220,7 @@ test_basic(void) assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -218,6 +234,7 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -231,9 +248,11 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -247,9 +266,11 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -263,6 +284,7 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -276,15 +298,19 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); + assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub3") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub3/file") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); @@ -298,6 +324,7 @@ test_basic(void) archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 3); + assertEqualInt(0, archive_read_disk_can_descend(a)); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ @@ -318,6 +345,7 @@ test_basic(void) /* dir1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/file1"); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); @@ -342,6 +370,7 @@ test_basic(void) /* dir1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/file1"); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); @@ -353,6 +382,7 @@ test_basic(void) /* dir1/sub1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(1, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/sub1"); assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); @@ -361,6 +391,7 @@ test_basic(void) /* dir1/sub1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1"); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); @@ -375,6 +406,96 @@ test_basic(void) /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + + /* + * Test for a full-path beginning with "//?/" + */ + wcwd = _wgetcwd(NULL, 0); + fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); + wcscpy(fullpath, L"//?/"); + wcscat(fullpath, wcwd); + wcscat(fullpath, L"/dir1/file1"); + free(wcwd); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); + while ((wcwd = wcschr(fullpath, L'\\')) != NULL) + *wcwd = L'/'; + + /* dir1/file1 */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(0, archive_read_disk_can_descend(a)); + assertEqualWString(archive_entry_pathname_w(ae), fullpath); + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 10); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "0123456789", 10); + + /* There is no entry. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + free(fullpath); + + /* + * Test for wild card '*' or '?' with "//?/" prefix. + */ + wcwd = _wgetcwd(NULL, 0); + fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); + wcscpy(fullpath, L"//?/"); + wcscat(fullpath, wcwd); + wcscat(fullpath, L"/dir1/*1"); + free(wcwd); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); + while ((wcwd = wcschr(fullpath, L'\\')) != NULL) + *wcwd = L'/'; + + /* dir1/file1 */ + wp = wcsrchr(fullpath, L'/'); + wcscpy(wp+1, L"file1"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(0, archive_read_disk_can_descend(a)); + assertEqualWString(archive_entry_pathname_w(ae), fullpath); + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 10); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "0123456789", 10); + + /* dir1/sub1 */ + wcscpy(wp+1, L"sub1"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(1, archive_read_disk_can_descend(a)); + assertEqualWString(archive_entry_pathname_w(ae), fullpath); + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); + + /* dir1/sub1/file1 */ + wcscpy(wp+1, L"sub1/file1"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + assertEqualInt(0, archive_read_disk_can_descend(a)); + assertEqualWString(archive_entry_pathname_w(ae), fullpath); + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 10); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "0123456789", 10); + + /* There is no entry. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + free(fullpath); + #endif /* @@ -969,11 +1090,13 @@ test_restore_atime(void) failure("There must be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - failure("Atime must not be restored"); + failure("Atime should be restored"); assertFileAtimeRecent("at"); + failure("Atime should be restored"); assertFileAtimeRecent("at/f1"); + failure("Atime should be restored"); assertFileAtimeRecent("at/f2"); - failure("The atime of a empty file must not be changed"); + failure("The atime of a empty file should not be changed"); assertFileAtime("at/fe", 886611, 0); /* Close the disk object. */ @@ -1033,13 +1156,403 @@ test_restore_atime(void) failure("There must be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); - failure("Atime must be restored"); + failure("Atime should be restored"); assertFileAtime("at", 886622, 0); + failure("Atime should be restored"); assertFileAtime("at/f1", 886600, 0); + failure("Atime should be restored"); assertFileAtime("at/f2", 886611, 0); - failure("The atime of a empty file must not be changed"); + failure("The atime of a empty file should not be changed"); assertFileAtime("at/fe", 886611, 0); + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + + /* + * Test3: Traversals with archive_read_disk_set_atime_restored() but + * no data read as a listing. + */ + assertUtimes("at/f1", 886600, 0, 886600, 0); + assertUtimes("at/f2", 886611, 0, 886611, 0); + assertUtimes("at/fe", 886611, 0, 886611, 0); + assertUtimes("at", 886622, 0, 886622, 0); + file_count = 4; + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); + + failure("Directory traversals should work as well"); + while (file_count--) { + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + if (strcmp(archive_entry_pathname(ae), "at") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 11); + } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 0); + } + if (archive_entry_filetype(ae) == AE_IFDIR) { + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_descend(a)); + } + } + /* There is no entry. */ + failure("There must be no entry"); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + failure("Atime should be restored"); + assertFileAtime("at", 886622, 0); + failure("Atime should be restored"); + assertFileAtime("at/f1", 886600, 0); + failure("Atime should be restored"); + assertFileAtime("at/f2", 886611, 0); + failure("The atime of a empty file should not be changed"); + assertFileAtime("at/fe", 886611, 0); + + if (!canNodump()) { + /* Destroy the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + archive_entry_free(ae); + skipping("Can't test atime with nodump on this filesystem"); + return; + } + + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + + /* + * Test4: Traversals with archive_read_disk_set_atime_restored() and + * archive_read_disk_honor_nodump(). + */ + assertNodump("at/f1"); + assertNodump("at/f2"); + assertUtimes("at/f1", 886600, 0, 886600, 0); + assertUtimes("at/f2", 886611, 0, 886611, 0); + assertUtimes("at/fe", 886611, 0, 886611, 0); + assertUtimes("at", 886622, 0, 886622, 0); + file_count = 2; + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, + ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); + + failure("Directory traversals should work as well"); + while (file_count--) { + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + if (strcmp(archive_entry_pathname(ae), "at") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 0); + } + if (archive_entry_filetype(ae) == AE_IFDIR) { + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_descend(a)); + } + } + /* There is no entry. */ + failure("There must be no entry"); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + failure("Atime should be restored"); + assertFileAtime("at", 886622, 0); + failure("Atime should be restored"); + assertFileAtime("at/f1", 886600, 0); + failure("Atime should be restored"); + assertFileAtime("at/f2", 886611, 0); + failure("The atime of a empty file should not be changed"); + assertFileAtime("at/fe", 886611, 0); + + /* Destroy the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + archive_entry_free(ae); +} + +static int +metadata_filter(struct archive *a, void *data, struct archive_entry *ae) +{ + (void)data; /* UNUSED */ + + failure("CTime should be set"); + assertEqualInt(8, archive_entry_ctime_is_set(ae)); + failure("MTime should be set"); + assertEqualInt(16, archive_entry_mtime_is_set(ae)); + + if (archive_entry_mtime(ae) < 886611) + return (0); + if (archive_read_disk_can_descend(a)) { + /* Descend into the current object */ + failure("archive_read_disk_can_descend should work" + " in metadata filter"); + assertEqualIntA(a, 1, archive_read_disk_can_descend(a)); + failure("archive_read_disk_descend should work" + " in metadata filter"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); + } + return (1); +} + +static void +test_callbacks(void) +{ + struct archive *a; + struct archive *m; + struct archive_entry *ae; + const void *p; + size_t size; + int64_t offset; + int file_count; + + assertMakeDir("cb", 0755); + assertMakeFile("cb/f1", 0644, "0123456789"); + assertMakeFile("cb/f2", 0644, "hello world"); + assertMakeFile("cb/fe", 0644, NULL); + assertUtimes("cb/f1", 886600, 0, 886600, 0); + assertUtimes("cb/f2", 886611, 0, 886611, 0); + assertUtimes("cb/fe", 886611, 0, 886611, 0); + assertUtimes("cb", 886622, 0, 886622, 0); + + assert((ae = archive_entry_new()) != NULL); + if (assert((a = archive_read_disk_new()) != NULL)) { + archive_entry_free(ae); + return; + } + if (assert((m = archive_match_new()) != NULL)) { + archive_entry_free(ae); + archive_read_free(a); + return; + } + + /* + * Test1: Traversals with a name filter. + */ + file_count = 3; + assertEqualIntA(m, ARCHIVE_OK, + archive_match_exclude_pattern(m, "cb/f2")); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_set_matching(a, m, NULL, NULL)); + failure("Directory traversals should work as well"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); + while (file_count--) { + archive_entry_clear(ae); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + failure("File 'cb/f2' should be exclueded"); + assert(strcmp(archive_entry_pathname(ae), "cb/f2") != 0); + if (strcmp(archive_entry_pathname(ae), "cb") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + } else if (strcmp(archive_entry_pathname(ae), "cb/f1") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 10); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "0123456789", 10); + assertEqualInt(ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + assertEqualInt((int)offset, 10); + } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 0); + } + if (archive_read_disk_can_descend(a)) { + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_descend(a)); + } + } + /* There is no entry. */ + failure("There should be no entry"); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + + /* + * Test2: Traversals with a metadata filter. + */ + assertUtimes("cb/f1", 886600, 0, 886600, 0); + assertUtimes("cb/f2", 886611, 0, 886611, 0); + assertUtimes("cb/fe", 886611, 0, 886611, 0); + assertUtimes("cb", 886622, 0, 886622, 0); + file_count = 3; + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_set_metadata_filter_callback(a, metadata_filter, + NULL)); + failure("Directory traversals should work as well"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); + + while (file_count--) { + archive_entry_clear(ae); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + failure("File 'cb/f1' should be exclueded"); + assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0); + if (strcmp(archive_entry_pathname(ae), "cb") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + } else if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 11); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 11); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "hello world", 11); + assertEqualInt(ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + assertEqualInt((int)offset, 11); + } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 0); + } + } + /* There is no entry. */ + failure("There should be no entry"); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + /* Destroy the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + assertEqualInt(ARCHIVE_OK, archive_match_free(m)); + archive_entry_free(ae); +} + +static void +test_nodump(void) +{ + struct archive *a; + struct archive_entry *ae; + const void *p; + size_t size; + int64_t offset; + int file_count; + + if (!canNodump()) { + skipping("Can't test nodump on this filesystem"); + return; + } + + assertMakeDir("nd", 0755); + assertMakeFile("nd/f1", 0644, "0123456789"); + assertMakeFile("nd/f2", 0644, "hello world"); + assertMakeFile("nd/fe", 0644, NULL); + assertNodump("nd/f2"); + assertUtimes("nd/f1", 886600, 0, 886600, 0); + assertUtimes("nd/f2", 886611, 0, 886611, 0); + assertUtimes("nd/fe", 886611, 0, 886611, 0); + assertUtimes("nd", 886622, 0, 886622, 0); + + assert((ae = archive_entry_new()) != NULL); + assert((a = archive_read_disk_new()) != NULL); + + /* + * Test1: Traversals without archive_read_disk_honor_nodump(). + */ + failure("Directory traversals should work as well"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); + + file_count = 4; + while (file_count--) { + archive_entry_clear(ae); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + if (strcmp(archive_entry_pathname(ae), "nd") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 10); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "0123456789", 10); + assertEqualInt(ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + assertEqualInt((int)offset, 10); + } else if (strcmp(archive_entry_pathname(ae), "nd/f2") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 11); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 11); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "hello world", 11); + assertEqualInt(ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + assertEqualInt((int)offset, 11); + } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 0); + } + if (archive_read_disk_can_descend(a)) { + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_descend(a)); + } + } + /* There is no entry. */ + failure("There should be no entry"); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + + /* + * Test2: Traversals with archive_read_disk_honor_nodump(). + */ + assertUtimes("nd/f1", 886600, 0, 886600, 0); + assertUtimes("nd/f2", 886611, 0, 886611, 0); + assertUtimes("nd/fe", 886611, 0, 886611, 0); + assertUtimes("nd", 886622, 0, 886622, 0); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, + ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); + failure("Directory traversals should work as well"); + assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); + + file_count = 3; + while (file_count--) { + archive_entry_clear(ae); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); + failure("File 'nd/f2' should be exclueded"); + assert(strcmp(archive_entry_pathname(ae), "nd/f2") != 0); + if (strcmp(archive_entry_pathname(ae), "nd") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); + } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 10); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 10); + assertEqualInt((int)offset, 0); + assertEqualMem(p, "0123456789", 10); + assertEqualInt(ARCHIVE_EOF, + archive_read_data_block(a, &p, &size, &offset)); + assertEqualInt((int)size, 0); + assertEqualInt((int)offset, 10); + } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { + assertEqualInt(archive_entry_filetype(ae), AE_IFREG); + assertEqualInt(archive_entry_size(ae), 0); + } + if (archive_read_disk_can_descend(a)) { + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_descend(a)); + } + } + /* There is no entry. */ + failure("There should be no entry"); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + + failure("Atime should be restored"); + assertFileAtime("nd/f2", 886611, 0); + /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); archive_entry_free(ae); @@ -1057,4 +1570,8 @@ DEFINE_TEST(test_read_disk_directory_traversals) test_symlink_logical_loop(); /* Test to restore atime. */ test_restore_atime(); + /* Test callbacks. */ + test_callbacks(); + /* Test nodump. */ + test_nodump(); } diff --git a/contrib/libarchive/libarchive/test/test_read_format_7zip.c b/contrib/libarchive/libarchive/test/test_read_format_7zip.c index a4cc555..043ef9f 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_7zip.c +++ b/contrib/libarchive/libarchive/test/test_read_format_7zip.c @@ -26,8 +26,8 @@ __FBSDID("$FreeBSD"); /* - * Extract a non-encorded file. - * The header of the 7z archive files is not encdoed. + * Extract a non-encoded file. + * The header of the 7z archive files is not encoded. */ static void test_copy() @@ -46,7 +46,7 @@ test_copy() /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); assertEqualString("file1", archive_entry_pathname(ae)); assertEqualInt(86401, archive_entry_mtime(ae)); assertEqualInt(60, archive_entry_size(ae)); @@ -139,7 +139,7 @@ test_empty_file() /* * Extract an encoded file. - * The header of the 7z archive files is not encdoed. + * The header of the 7z archive files is not encoded. */ static void test_plain_header(const char *refname) @@ -180,7 +180,7 @@ test_plain_header(const char *refname) /* * Extract multi files. - * The header of the 7z archive files is encdoed with LZMA. + * The header of the 7z archive files is encoded with LZMA. */ static void test_extract_all_files(const char *refname) @@ -255,7 +255,7 @@ test_extract_all_files(const char *refname) /* * Extract last file. - * The header of the 7z archive files is encdoed with LZMA. + * The header of the 7z archive files is encoded with LZMA. */ static void test_extract_last_file(const char *refname) @@ -323,7 +323,7 @@ test_extract_last_file(const char *refname) } /* - * Extract a mixed archive file which has both LZMA and LZMA2 encoded files. + * Extract a mixed archive file which has both LZMA and LZMA2 encoded files. * LZMA: file1, file2, file3, file4 * LZMA2: zfile1, zfile2, zfile3, zfile4 */ @@ -510,7 +510,7 @@ test_bcj(const char *refname) /* Verify regular x86exe. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0555), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae) & ~0111); assertEqualString("x86exe", archive_entry_pathname(ae)); assertEqualInt(172802, archive_entry_mtime(ae)); assertEqualInt(27328, archive_entry_size(ae)); @@ -565,7 +565,7 @@ test_ppmd() /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); assertEqualString("ppmd_test.txt", archive_entry_pathname(ae)); assertEqualInt(1322464589, archive_entry_mtime(ae)); assertEqualInt(102400, archive_entry_size(ae)); diff --git a/contrib/libarchive/libarchive/test/test_read_format_cab.c b/contrib/libarchive/libarchive/test/test_read_format_cab.c index 4e8607e..004d6e8 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_cab.c +++ b/contrib/libarchive/libarchive/test/test_read_format_cab.c @@ -199,7 +199,7 @@ verify(const char *refname, enum comp_type comp) /* Verify regular empty. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); assertEqualString("empty", archive_entry_pathname(ae)); assertEqualInt(0, archive_entry_uid(ae)); assertEqualInt(0, archive_entry_gid(ae)); @@ -211,7 +211,7 @@ verify(const char *refname, enum comp_type comp) * file to check if we properly handle multiple CFDATA. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); assertEqualString("zero", archive_entry_pathname(ae)); assertEqualInt(0, archive_entry_uid(ae)); assertEqualInt(0, archive_entry_gid(ae)); @@ -232,7 +232,7 @@ verify(const char *refname, enum comp_type comp) /* Verify regular file1. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); assertEqualString("dir1/file1", archive_entry_pathname(ae)); assertEqualInt(0, archive_entry_uid(ae)); assertEqualInt(0, archive_entry_gid(ae)); @@ -242,7 +242,7 @@ verify(const char *refname, enum comp_type comp) /* Verify regular file2. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); - assertEqualInt((AE_IFREG | 0777), archive_entry_mode(ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); assertEqualString("dir2/file2", archive_entry_pathname(ae)); assertEqualInt(0, archive_entry_uid(ae)); assertEqualInt(0, archive_entry_gid(ae)); @@ -269,13 +269,121 @@ finish: assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } +/* + * Skip beginning files and Read the last file. + */ +static void +verify2(const char *refname, enum comp_type comp) +{ + struct archive_entry *ae; + struct archive *a; + char buff[128]; + char zero[128]; + + memset(zero, 0, sizeof(zero)); + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Verify regular empty. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + if (comp != STORE) { + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + } + /* Verify regular file1. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* Verify regular file2. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae)); + assertEqualString("dir2/file2", archive_entry_pathname(ae)); + assertEqualInt(0, archive_entry_uid(ae)); + assertEqualInt(0, archive_entry_gid(ae)); + assertEqualInt(file2_size, archive_entry_size(ae)); + assertEqualInt(file2_size, archive_read_data(a, buff, file2_size)); + assertEqualMem(buff, file2, file2_size); + + /* End of archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + if (comp != STORE) { + assertEqualInt(4, archive_file_count(a)); + } else { + assertEqualInt(3, archive_file_count(a)); + } + + /* Verify archive format. */ + assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); + assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); + + /* Close the archive. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + +/* + * Skip all file like 'bsdtar tvf foo.cab'. + */ +static void +verify3(const char *refname, enum comp_type comp) +{ + struct archive_entry *ae; + struct archive *a; + char zero[128]; + + memset(zero, 0, sizeof(zero)); + extract_reference_file(refname); + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_filename(a, refname, 10240)); + + /* Verify regular empty. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + if (comp != STORE) { + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + } + /* Verify regular file1. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* Verify regular file2. */ + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* End of archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + if (comp != STORE) { + assertEqualInt(4, archive_file_count(a)); + } else { + assertEqualInt(3, archive_file_count(a)); + } + + /* Verify archive format. */ + assertEqualIntA(a, ARCHIVE_COMPRESSION_NONE, archive_compression(a)); + assertEqualIntA(a, ARCHIVE_FORMAT_CAB, archive_format(a)); + + /* Close the archive. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); +} + DEFINE_TEST(test_read_format_cab) { /* Verify Cabinet file in no compression. */ verify("test_read_format_cab_1.cab", STORE); + verify2("test_read_format_cab_1.cab", STORE); + verify3("test_read_format_cab_1.cab", STORE); /* Verify Cabinet file in MSZIP. */ verify("test_read_format_cab_2.cab", MSZIP); + verify2("test_read_format_cab_2.cab", MSZIP); + verify3("test_read_format_cab_2.cab", MSZIP); /* Verify Cabinet file in LZX. */ verify("test_read_format_cab_3.cab", LZX); + verify2("test_read_format_cab_3.cab", LZX); + verify3("test_read_format_cab_3.cab", LZX); } diff --git a/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c b/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c index f0d27a3..b354b8c 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c +++ b/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_bzip2_rpm.c @@ -51,7 +51,7 @@ Name: ${NAME} Version: 1.0.0 Release: 1 License: BSD -URL: http://code.google.com/p/libarchive +URL: http://libarchive.github.com/ BuildArch: noarch BuildRoot: %{_tmppath}/%{name}-%{version}-root diff --git a/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c b/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c index 338a088..582096b 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c +++ b/contrib/libarchive/libarchive/test/test_read_format_cpio_svr4_gzip_rpm.c @@ -51,7 +51,7 @@ Name: ${NAME} Version: 1.0.0 Release: 1 License: BSD -URL: http://code.google.com/p/libarchive +URL: http://libarchive.github.com/ BuildArch: noarch BuildRoot: %{_tmppath}/%{name}-%{version}-root diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar.c b/contrib/libarchive/libarchive/test/test_read_format_rar.c index 8a73a78..a7c61f9 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_rar.c +++ b/contrib/libarchive/libarchive/test/test_read_format_rar.c @@ -1,6 +1,7 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle * Copyright (c) 2011 Andres Mejia + * Copyright (c) 2011-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -278,9 +279,19 @@ test_unicode_UTF8(void) assertEqualInt(41453, archive_entry_mode(ae)); assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); + /* Sixth header */ + assertA(0 == archive_read_next_header(a, &ae)); + assertEqualUTF8String( + "abcdefghijklmnopqrs\xE3\x83\x86\xE3\x82\xB9\xE3\x83\x88.txt", + archive_entry_pathname(ae)); + assertA((int)archive_entry_mtime(ae)); + assertEqualInt(16, archive_entry_size(ae)); + assertEqualInt(33204, archive_entry_mode(ae)); + assertEqualIntA(a, 16, archive_read_data(a, buff, sizeof(buff))); + /* Test EOF */ assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); + assertEqualInt(6, archive_file_count(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } @@ -364,9 +375,19 @@ test_unicode_CP932(void) assertEqualInt(41453, archive_entry_mode(ae)); assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); + /* Sixth header */ + assertA(0 == archive_read_next_header(a, &ae)); + assertEqualUTF8String( + "abcdefghijklmnopqrs\x83\x65\x83\x58\x83\x67.txt", + archive_entry_pathname(ae)); + assertA((int)archive_entry_mtime(ae)); + assertEqualInt(16, archive_entry_size(ae)); + assertEqualInt(33204, archive_entry_mode(ae)); + assertEqualIntA(a, 16, archive_read_data(a, buff, sizeof(buff))); + /* Test EOF */ assertA(1 == archive_read_next_header(a, &ae)); - assertEqualInt(5, archive_file_count(a)); + assertEqualInt(6, archive_file_count(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } diff --git a/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.rar.uu b/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.rar.uu index cfe6e40..8469e99 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.rar.uu +++ b/contrib/libarchive/libarchive/test/test_read_format_rar_unicode.rar.uu @@ -11,7 +11,8 @@ M5H*U@J*#=(-(@XN#7P"(:&A@,(@P7*JP95<P1##5,*BI,.LPP#``\"8YA&UX M=."2,P````````````(`````#VGA/A0P#@`0````E5R"OH+F`(AH:&`PB#`` M\.H)?ED.="""2``V````-@````,E@OM=6%0+/Q0P*`#MH0``Z*&HXX&@XX*( M7..#E>."H>."I..#JP"(:&A@,(@P7*K5,*$PI##K,.:\HN6ME^F5M^.!A..# -ME>."H>."I..#J^60C6QO;F<M9FEL96YA;64M:6XMYKRBY:V7+G1X=,0]>P!` -"!P`` +ME>."H>."I..#J^60C6QO;F<M9FEL96YA;64M:6XMYKRBY:V7+G1X=)MJ=""` +M0``/````$`````,%T+85W81G0!TS(`"T@0``86)C9&5F9VAI:FML;6YO<'%R +D<^.#AN."N>.#B"YT>'0`D/\0?^2Y_">#,#TN'-+$/7L`0`<` ` end diff --git a/contrib/libarchive/libarchive/test/test_read_format_tar_filename.c b/contrib/libarchive/libarchive/test/test_read_format_tar_filename.c index abec4ec..ee2bf81 100644 --- a/contrib/libarchive/libarchive/test/test_read_format_tar_filename.c +++ b/contrib/libarchive/libarchive/test/test_read_format_tar_filename.c @@ -34,7 +34,7 @@ __FBSDID("$FreeBSD"); * - the filename of second file is stored in UTF-8. * * Whenever hdrcharset option is specified, we will correctly read the - * filename of sencod file, which is stored in UTF-8 by default. + * filename of second file, which is stored in UTF-8 by default. */ static void diff --git a/contrib/libarchive/libarchive/test/test_read_pax_truncated.c b/contrib/libarchive/libarchive/test/test_read_pax_truncated.c index 0c36bb4..8c61f26 100644 --- a/contrib/libarchive/libarchive/test/test_read_pax_truncated.c +++ b/contrib/libarchive/libarchive/test/test_read_pax_truncated.c @@ -71,10 +71,10 @@ DEFINE_TEST(test_read_pax_truncated) assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); /* If it's truncated very early, the file type detection should fail. */ if (i < 512) { - assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory2(a, buff, i, 13)); + assertEqualIntA(a, ARCHIVE_FATAL, read_open_memory_minimal(a, buff, i, 13)); goto wrap_up; } else { - assertEqualIntA(a, ARCHIVE_OK, read_open_memory2(a, buff, i, 13)); + assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, buff, i, 13)); } /* If it's truncated in a header, the header read should fail. */ diff --git a/contrib/libarchive/libarchive/test/test_read_position.c b/contrib/libarchive/libarchive/test/test_read_position.c index 69e4796..5e7f05f 100644 --- a/contrib/libarchive/libarchive/test/test_read_position.c +++ b/contrib/libarchive/libarchive/test/test_read_position.c @@ -105,7 +105,7 @@ DEFINE_TEST(test_read_position) /* Read the archive back without a skip function. */ assert(NULL != (a = archive_read_new())); assertA(0 == archive_read_support_format_tar(a)); - assertA(0 == read_open_memory2(a, buff, sizeof(buff), 512)); + assertA(0 == read_open_memory_minimal(a, buff, sizeof(buff), 512)); verify_read_positions(a); archive_read_free(a); diff --git a/contrib/libarchive/libarchive/test/test_sparse_basic.c b/contrib/libarchive/libarchive/test/test_sparse_basic.c index 1d62e7c..d564f0c 100644 --- a/contrib/libarchive/libarchive/test/test_sparse_basic.c +++ b/contrib/libarchive/libarchive/test/test_sparse_basic.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2010 Michihiro NAKAJIMA + * Copyright (c) 2010-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,9 +31,6 @@ __FBSDID("$FreeBSD$"); #ifdef HAVE_SYS_PARAM_H #include <sys/param.h> #endif -#ifdef HAVE_SYS_UTSNAME_H -#include <sys/utsname.h> -#endif #ifdef HAVE_FCNTL_H #include <fcntl.h> #endif @@ -169,31 +166,12 @@ is_sparse_supported(const char *path) { HOLE, 1024 }, { DATA, 10240 }, { END, 0 } }; - struct utsname ut; - char *p, *e; - long d; int fd, r; struct fiemap *fm; char buff[1024]; const char *testfile = "can_sparse"; (void)path; /* UNUSED */ - memset(&ut, 0, sizeof(ut)); - assertEqualInt(uname(&ut), 0); - p = ut.release; - d = strtol(p, &e, 10); - if (d < 2 || *e != '.') - return (0); - if (d == 2) { - p = e + 1; - d = strtol(p, &e, 10); - if (d < 6 || *e != '.') - return (0); - p = e + 1; - d = strtol(p, NULL, 10); - if (d < 28) - return (0); - } create_sparse_file(testfile, sparse_file); fd = open(testfile, O_RDWR); if (fd < 0) @@ -205,11 +183,9 @@ is_sparse_supported(const char *path) fm->fm_extent_count = (sizeof(buff) - sizeof(*fm))/ sizeof(struct fiemap_extent); r = ioctl(fd, FS_IOC_FIEMAP, fm); - if (r < 0 && (errno == ENOTTY || errno == EOPNOTSUPP)) - return (0);/* Not supported. */ close(fd); unlink(testfile); - return (1); + return (r >= 0); } #else diff --git a/contrib/libarchive/libarchive/test/test_write_format_zip.c b/contrib/libarchive/libarchive/test/test_write_format_zip.c index d9bfe5d..76f88f7 100644 --- a/contrib/libarchive/libarchive/test/test_write_format_zip.c +++ b/contrib/libarchive/libarchive/test/test_write_format_zip.c @@ -91,7 +91,7 @@ verify_contents(struct archive *a, int expect_details) assertEqualInt(0, archive_entry_size(ae)); assertEqualString("file1", archive_entry_symlink(ae)); } else { - assertEqualInt(AE_IFREG | 0777, archive_entry_mode(ae)); + assertEqualInt(AE_IFREG | 0666, archive_entry_mode(ae)); assertEqualInt(0, archive_entry_size(ae)); } |