summaryrefslogtreecommitdiffstats
path: root/contrib/libarchive/cpio
diff options
context:
space:
mode:
authormm <mm@FreeBSD.org>2012-07-28 06:38:44 +0000
committermm <mm@FreeBSD.org>2012-07-28 06:38:44 +0000
commit11bb7fcf7b175da111e710d49b6e1c30153b625b (patch)
tree1ed0c7ff98605ecfbedcfa8d00cd1a29e2dfebe6 /contrib/libarchive/cpio
parentf694295168072660e04cabb712367c5a73b59885 (diff)
parente7b24010c4d2190a1465594620e629e469c522f8 (diff)
downloadFreeBSD-src-11bb7fcf7b175da111e710d49b6e1c30153b625b.zip
FreeBSD-src-11bb7fcf7b175da111e710d49b6e1c30153b625b.tar.gz
Update libarchive to 3.0.4
Diffstat (limited to 'contrib/libarchive/cpio')
-rw-r--r--contrib/libarchive/cpio/bsdcpio.12
-rw-r--r--contrib/libarchive/cpio/cmdline.c1
-rw-r--r--contrib/libarchive/cpio/cpio.c36
-rw-r--r--contrib/libarchive/cpio/cpio.h4
-rw-r--r--contrib/libarchive/cpio/test/main.c321
-rw-r--r--contrib/libarchive/cpio/test/test.h12
-rw-r--r--contrib/libarchive/cpio/test/test_pathmatch.c243
7 files changed, 280 insertions, 339 deletions
diff --git a/contrib/libarchive/cpio/bsdcpio.1 b/contrib/libarchive/cpio/bsdcpio.1
index 1355130..5611b20 100644
--- a/contrib/libarchive/cpio/bsdcpio.1
+++ b/contrib/libarchive/cpio/bsdcpio.1
@@ -24,7 +24,7 @@
.\"
.\" $FreeBSD$
.\"
-.Dd December 21, 2007
+.Dd December 24, 2011
.Dt CPIO 1
.Os
.Sh NAME
diff --git a/contrib/libarchive/cpio/cmdline.c b/contrib/libarchive/cpio/cmdline.c
index a9cb33c..7f12896 100644
--- a/contrib/libarchive/cpio/cmdline.c
+++ b/contrib/libarchive/cpio/cmdline.c
@@ -346,6 +346,7 @@ owner_parse(const char *spec, int *uid, int *gid)
snprintf(errbuff, sizeof(errbuff),
"Couldn't lookup user ``%s''", user);
errbuff[sizeof(errbuff) - 1] = '\0';
+ free(user);
return (errbuff);
}
}
diff --git a/contrib/libarchive/cpio/cpio.c b/contrib/libarchive/cpio/cpio.c
index 3e74461..fb814a2 100644
--- a/contrib/libarchive/cpio/cpio.c
+++ b/contrib/libarchive/cpio/cpio.c
@@ -82,7 +82,6 @@ __FBSDID("$FreeBSD$");
#include "cpio.h"
#include "err.h"
#include "line_reader.h"
-#include "matching.h"
/* Fixed size of uname/gname caches. */
#define name_cache_size 101
@@ -190,6 +189,10 @@ main(int argc, char *argv[])
cpio->bytes_per_block = 512;
cpio->filename = NULL;
+ cpio->matching = archive_match_new();
+ if (cpio->matching == NULL)
+ lafe_errc(1, 0, "Out of memory");
+
while ((opt = cpio_getopt(cpio)) != -1) {
switch (opt) {
case '0': /* GNU convention: --null, -0 */
@@ -216,14 +219,20 @@ main(int argc, char *argv[])
cpio->extract_flags &= ~ARCHIVE_EXTRACT_NO_AUTODIR;
break;
case 'E': /* NetBSD/OpenBSD */
- lafe_include_from_file(&cpio->matching,
- cpio->argument, cpio->option_null);
+ if (archive_match_include_pattern_from_file(
+ cpio->matching, cpio->argument,
+ cpio->option_null) != ARCHIVE_OK)
+ lafe_errc(1, 0, "Error : %s",
+ archive_error_string(cpio->matching));
break;
case 'F': /* NetBSD/OpenBSD/GNU cpio */
cpio->filename = cpio->argument;
break;
case 'f': /* POSIX 1997 */
- lafe_exclude(&cpio->matching, cpio->argument);
+ if (archive_match_exclude_pattern(cpio->matching,
+ cpio->argument) != ARCHIVE_OK)
+ lafe_errc(1, 0, "Error : %s",
+ archive_error_string(cpio->matching));
break;
case 'H': /* GNU cpio (also --format) */
cpio->format = cpio->argument;
@@ -369,9 +378,6 @@ main(int argc, char *argv[])
/* -v overrides -V */
if (cpio->dot && cpio->verbose)
cpio->dot = 0;
- /* -v overrides -V */
- if (cpio->dot && cpio->verbose)
- cpio->dot = 0;
/* TODO: Flag other nonsensical combinations. */
switch (cpio->mode) {
@@ -385,7 +391,10 @@ main(int argc, char *argv[])
break;
case 'i':
while (*cpio->argv != NULL) {
- lafe_include(&cpio->matching, *cpio->argv);
+ if (archive_match_include_pattern(cpio->matching,
+ *cpio->argv) != ARCHIVE_OK)
+ lafe_errc(1, 0, "Error : %s",
+ archive_error_string(cpio->matching));
--cpio->argc;
++cpio->argv;
}
@@ -405,6 +414,7 @@ main(int argc, char *argv[])
"Must specify at least one of -i, -o, or -p");
}
+ archive_match_free(cpio->matching);
free_cache(cpio->gname_cache);
free_cache(cpio->uname_cache);
return (cpio->return_value);
@@ -909,7 +919,7 @@ mode_in(struct cpio *cpio)
lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
}
- if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
+ if (archive_match_path_excluded(cpio->matching, entry))
continue;
if (cpio->option_rename) {
destpath = cpio_rename(archive_entry_pathname(entry));
@@ -1011,7 +1021,7 @@ mode_list(struct cpio *cpio)
lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
}
- if (lafe_excluded(cpio->matching, archive_entry_pathname(entry)))
+ if (archive_match_path_excluded(cpio->matching, entry))
continue;
if (cpio->verbose)
list_item_verbose(cpio, entry);
@@ -1306,7 +1316,8 @@ lookup_uname_helper(struct cpio *cpio, const char **name, id_t id)
if (pwent == NULL) {
*name = NULL;
if (errno != 0 && errno != ENOENT)
- lafe_warnc(errno, "getpwuid(%d) failed", id);
+ lafe_warnc(errno, "getpwuid(%s) failed",
+ cpio_i64toa((int64_t)id));
return (errno);
}
@@ -1333,7 +1344,8 @@ lookup_gname_helper(struct cpio *cpio, const char **name, id_t id)
if (grent == NULL) {
*name = NULL;
if (errno != 0)
- lafe_warnc(errno, "getgrgid(%d) failed", id);
+ lafe_warnc(errno, "getgrgid(%s) failed",
+ cpio_i64toa((int64_t)id));
return (errno);
}
diff --git a/contrib/libarchive/cpio/cpio.h b/contrib/libarchive/cpio/cpio.h
index 7c56d3c..0859100 100644
--- a/contrib/libarchive/cpio/cpio.h
+++ b/contrib/libarchive/cpio/cpio.h
@@ -31,8 +31,6 @@
#include "cpio_platform.h"
#include <stdio.h>
-#include "matching.h"
-
/*
* The internal state for the "cpio" program.
*
@@ -88,7 +86,7 @@ struct cpio {
struct name_cache *gname_cache;
/* Work data. */
- struct lafe_matching *matching;
+ struct archive *matching;
char *buff;
size_t buff_size;
};
diff --git a/contrib/libarchive/cpio/test/main.c b/contrib/libarchive/cpio/test/main.c
index d4ed99c..1e4997c 100644
--- a/contrib/libarchive/cpio/test/main.c
+++ b/contrib/libarchive/cpio/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
@@ -116,7 +129,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;
@@ -155,7 +175,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;
@@ -1507,7 +1527,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. */
@@ -1521,8 +1541,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);
@@ -1542,10 +1567,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);
}
@@ -1716,6 +1747,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.
@@ -1744,7 +1821,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__)
@@ -1794,6 +1871,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.
@@ -2236,17 +2377,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 */
@@ -2332,6 +2533,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");
@@ -2379,7 +2593,8 @@ main(int argc, char **argv)
#endif
break;
case 'q':
- verbosity--;
+ if (!vlevel)
+ verbosity--;
break;
case 'r':
refdir = option_arg;
@@ -2388,7 +2603,8 @@ main(int argc, char **argv)
until_failure++;
break;
case 'v':
- verbosity++;
+ if (!vlevel)
+ verbosity++;
break;
default:
fprintf(stderr, "Unrecognized option '%c'\n",
@@ -2501,78 +2717,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/cpio/test/test.h b/contrib/libarchive/cpio/test/test.h
index fdecb3e..b9e7030 100644
--- a/contrib/libarchive/cpio/test/test.h
+++ b/contrib/libarchive/cpio/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 *);
diff --git a/contrib/libarchive/cpio/test/test_pathmatch.c b/contrib/libarchive/cpio/test/test_pathmatch.c
deleted file mode 100644
index 177c2bc..0000000
--- a/contrib/libarchive/cpio/test/test_pathmatch.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/*-
- * 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 "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_pathmatch)
-{
- assertEqualInt(1, lafe_pathmatch("a/b/c", "a/b/c", 0));
- assertEqualInt(0, lafe_pathmatch("a/b/", "a/b/c", 0));
- assertEqualInt(0, lafe_pathmatch("a/b", "a/b/c", 0));
- assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b/", 0));
- assertEqualInt(0, lafe_pathmatch("a/b/c", "a/b", 0));
-
- /* Empty pattern only matches empty string. */
- assertEqualInt(1, lafe_pathmatch("","", 0));
- assertEqualInt(0, lafe_pathmatch("","a", 0));
- assertEqualInt(1, lafe_pathmatch("*","", 0));
- assertEqualInt(1, lafe_pathmatch("*","a", 0));
- assertEqualInt(1, lafe_pathmatch("*","abcd", 0));
- /* SUSv2: * matches / */
- assertEqualInt(1, lafe_pathmatch("*","abcd/efgh/ijkl", 0));
- assertEqualInt(1, lafe_pathmatch("abcd*efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(1, lafe_pathmatch("abcd***efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(1, lafe_pathmatch("abcd***/efgh/ijkl","abcd/efgh/ijkl", 0));
- assertEqualInt(0, lafe_pathmatch("?", "", 0));
- assertEqualInt(0, lafe_pathmatch("?", "\0", 0));
- assertEqualInt(1, lafe_pathmatch("?", "a", 0));
- assertEqualInt(0, lafe_pathmatch("?", "ab", 0));
- assertEqualInt(1, lafe_pathmatch("?", ".", 0));
- assertEqualInt(1, lafe_pathmatch("?", "?", 0));
- assertEqualInt(1, lafe_pathmatch("a", "a", 0));
- assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
- assertEqualInt(0, lafe_pathmatch("a", "ab", 0));
- assertEqualInt(1, lafe_pathmatch("a?c", "abc", 0));
- /* SUSv2: ? matches / */
- assertEqualInt(1, lafe_pathmatch("a?c", "a/c", 0));
- assertEqualInt(1, lafe_pathmatch("a?*c*", "a/c", 0));
- assertEqualInt(1, lafe_pathmatch("*a*", "a/c", 0));
- assertEqualInt(1, lafe_pathmatch("*a*", "/a/c", 0));
- assertEqualInt(1, lafe_pathmatch("*a*", "defaaaaaaa", 0));
- assertEqualInt(0, lafe_pathmatch("a*", "defghi", 0));
- assertEqualInt(0, lafe_pathmatch("*a*", "defghi", 0));
-
- /* Character classes */
- assertEqualInt(1, lafe_pathmatch("abc[def", "abc[def", 0));
- assertEqualInt(0, lafe_pathmatch("abc[def]", "abc[def", 0));
- assertEqualInt(0, lafe_pathmatch("abc[def", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[def]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[def]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[def]", "abcf", 0));
- assertEqualInt(0, lafe_pathmatch("abc[def]", "abcg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d*f]", "abc*", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d*f]", "abcdefghi", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d*", "abcdefghi", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d*", "abc[defghi", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-f]", "abcf", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-f]", "abcg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abca", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcf", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abch", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abci", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abcj", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-k]", "abck", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abcl", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-k]", "abc-", 0));
-
- /* [] matches nothing, [!] is the same as ? */
- assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcdefg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcqefg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[]efg", "abcefg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcdefg", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!]efg", "abcqefg", 0));
- assertEqualInt(0, lafe_pathmatch("abc[!]efg", "abcefg", 0));
-
- /* I assume: Trailing '-' is non-special. */
- assertEqualInt(0, lafe_pathmatch("abc[d-fh-]", "abcl", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abch", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-fh-]", "abc-", 0));
-
- /* ']' can be backslash-quoted within a character class. */
- assertEqualInt(1, lafe_pathmatch("abc[\\]]", "abc]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abc]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\]d]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abc]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\]]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d]e]", "abcde]", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\]e]", "abc]", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d\\]e]", "abcd]e", 0));
- assertEqualInt(0, lafe_pathmatch("abc[d]e]", "abc]", 0));
-
- /* backslash-quoted chars can appear as either end of a range. */
- assertEqualInt(1, lafe_pathmatch("abc[\\d-f]gh", "abcegh", 0));
- assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abcggh", 0));
- assertEqualInt(0, lafe_pathmatch("abc[\\d-f]gh", "abc\\gh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d-\\f]gh", "abcegh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[\\d-\\f]gh", "abcegh", 0));
- /* backslash-quoted '-' isn't special. */
- assertEqualInt(0, lafe_pathmatch("abc[d\\-f]gh", "abcegh", 0));
- assertEqualInt(1, lafe_pathmatch("abc[d\\-f]gh", "abc-gh", 0));
-
- /* Leading '!' negates a character class. */
- assertEqualInt(0, lafe_pathmatch("abc[!d]", "abcd", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!d]", "abce", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!d]", "abcc", 0));
- assertEqualInt(0, lafe_pathmatch("abc[!d-z]", "abcq", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!d-gi-z]", "abch", 0));
- assertEqualInt(1, lafe_pathmatch("abc[!fgijkl]", "abch", 0));
- assertEqualInt(0, lafe_pathmatch("abc[!fghijkl]", "abch", 0));
-
- /* Backslash quotes next character. */
- assertEqualInt(0, lafe_pathmatch("abc\\[def]", "abc\\d", 0));
- assertEqualInt(1, lafe_pathmatch("abc\\[def]", "abc[def]", 0));
- assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc[def]", 0));
- assertEqualInt(0, lafe_pathmatch("abc\\\\[def]", "abc\\[def]", 0));
- assertEqualInt(1, lafe_pathmatch("abc\\\\[def]", "abc\\d", 0));
- assertEqualInt(1, lafe_pathmatch("abcd\\", "abcd\\", 0));
- assertEqualInt(0, lafe_pathmatch("abcd\\", "abcd\\[", 0));
- assertEqualInt(0, lafe_pathmatch("abcd\\", "abcde", 0));
- assertEqualInt(0, lafe_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, lafe_pathmatch("a/b/", "a/bc", 0));
- assertEqualInt(1, lafe_pathmatch("a/./b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a\\/./b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a/\\./b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a/.\\/b", "a/b", 0));
- assertEqualInt(0, lafe_pathmatch("a\\/\\.\\/b", "a/b", 0));
- assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def/", 0));
- assertEqualInt(1, lafe_pathmatch("abc/def", "./././abc/./def", 0));
- assertEqualInt(1, lafe_pathmatch("abc/def/././//", "./././abc/./def/", 0));
- assertEqualInt(1, lafe_pathmatch(".////abc/.//def", "./././abc/./def", 0));
- assertEqualInt(1, lafe_pathmatch("./abc?def/", "abc/def/", 0));
- failure("\"?./\" is not the same as \"/./\"");
- assertEqualInt(0, lafe_pathmatch("./abc?./def/", "abc/def/", 0));
- failure("Trailing '/' should match no trailing '/'");
- assertEqualInt(1, lafe_pathmatch("./abc/./def/", "abc/def", 0));
- failure("Trailing '/./' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc/./def/./", "abc/def", 0));
- failure("Trailing '/.' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc/./def/.", "abc/def", 0));
- assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/", 0));
- failure("Trailing '/./' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc/./def", "abc/def/./", 0));
- failure("Trailing '/.' is still the same directory.");
- assertEqualInt(1, lafe_pathmatch("./abc*/./def", "abc/def/.", 0));
-
- /* Matches not anchored at beginning. */
- assertEqualInt(0,
- lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(0,
- lafe_pathmatch("^bcd", "abcd", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(1,
- lafe_pathmatch("b/c/d", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(0,
- lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
- assertEqualInt(0,
- lafe_pathmatch("^b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_START));
-
- /* Matches not anchored at end. */
- assertEqualInt(0,
- lafe_pathmatch("bcd", "abcd", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd/", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("abcd", "abcd/.", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("abc", "abcd", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("a/b/c$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c/", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("a/b/c/$", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c/$", "a/b/c/", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(1,
- lafe_pathmatch("a/b/c/$", "a/b/c", PATHMATCH_NO_ANCHOR_END));
- assertEqualInt(0,
- lafe_pathmatch("b/c", "a/b/c/d", PATHMATCH_NO_ANCHOR_END));
-}
OpenPOWER on IntegriCloud