lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
}
- if (archive_match_path_excluded(cpio->matching, entry))
+ r = archive_match_path_excluded(cpio->matching, entry);
+ if (r < 0)
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->matching));
+ if (r)
continue;
if (cpio->option_rename)
cpio_rename(entry);
lafe_errc(1, archive_errno(a),
"%s", archive_error_string(a));
}
- if (archive_match_path_excluded(cpio->matching, entry))
+ r = archive_match_path_excluded(cpio->matching, entry);
+ if (r < 0)
+ lafe_errc(1, 0, "%s", archive_error_string(cpio->matching));
+ if (r)
continue;
if (cpio->verbose)
list_item_verbose(cpio, entry);
return (ARCHIVE_FATAL);
}
+static int
+error_pattern(struct archive_match *a)
+{
+ archive_set_error(&(a->archive), EINVAL, "Failed to apply pattern");
+ a->archive.state = ARCHIVE_STATE_FATAL;
+ return (ARCHIVE_FATAL);
+}
+
/*
* Create an ARCHIVE_MATCH object.
*/
*
* Returns 1 if archive entry is excluded.
* Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
+ * Returns <0 if some error happened.
*/
int
archive_match_excluded(struct archive *_a, struct archive_entry *entry)
#else
r = path_excluded(a, 1, archive_entry_pathname(entry));
#endif
+ if (r < 0)
+ return (error_pattern(a));
if (r != 0)
return (r);
}
*
* Returns 1 if archive entry is excluded.
* Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
+ * Returns <0 if some error happened.
*/
int
archive_match_path_excluded(struct archive *_a,
struct archive_entry *entry)
{
struct archive_match *a;
+ int r;
archive_check_magic(_a, ARCHIVE_MATCH_MAGIC,
ARCHIVE_STATE_NEW, "archive_match_path_excluded");
if ((a->setflag & PATTERN_IS_SET) == 0)
return (0);
#if defined(_WIN32) && !defined(__CYGWIN__)
- return (path_excluded(a, 0, archive_entry_pathname_w(entry)));
+ r = path_excluded(a, 0, archive_entry_pathname_w(entry));
#else
- return (path_excluded(a, 1, archive_entry_pathname(entry)));
+ r = path_excluded(a, 1, archive_entry_pathname(entry));
#endif
+ if (r < 0)
+ return (error_pattern(a));
+ return (r);
}
/*
*
* Returns 1 if archive entry is excluded.
* Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
+ * Returns <0 if some error happened.
*/
int
archive_match_time_excluded(struct archive *_a,
*
* Returns 1 if archive entry is excluded.
* Returns 0 if archive entry is not excluded.
- * Returns <0 if something error happened.
+ * Returns <0 if some error happened.
*/
int
archive_match_owner_excluded(struct archive *_a,
#include "archive_pathmatch.h"
+#define MAX_RECURSION 100
+
/*
* Check whether a character 'c' is matched by a list specification [...]:
* * Leading '!' or '^' negates the class.
}
static int
-pm(const char *p, const char *s, int flags)
+pm(const char *p, const char *s, int flags, int depth)
{
const char *end;
+ int r;
+
+ if (depth > MAX_RECURSION)
+ return (-1);
/*
* Ignore leading './', './/', '././', etc.
if (*p == '\0')
return (1);
while (*s) {
- if (pm(p, s, flags))
- return (1);
+ r = pm(p, s, flags, depth + 1);
+ if (r)
+ return (r);
++s;
}
return (0);
}
static int
-pm_w(const wchar_t *p, const wchar_t *s, int flags)
+pm_w(const wchar_t *p, const wchar_t *s, int flags, int depth)
{
const wchar_t *end;
+ int r;
+
+ if (depth > MAX_RECURSION)
+ return (-1);
/*
* Ignore leading './', './/', '././', etc.
if (*p == L'\0')
return (1);
while (*s) {
- if (pm_w(p, s, flags))
- return (1);
+ r = pm_w(p, s, flags, depth + 1);
+ if (r)
+ return (r);
++s;
}
return (0);
++p;
while (*s == '/')
++s;
- return (pm(p, s, flags));
+ return (pm(p, s, flags, 0));
}
/* If start is unanchored, try to match start of each path element. */
if (flags & PATHMATCH_NO_ANCHOR_START) {
for ( ; s != NULL; s = strchr(s, '/')) {
+ int r;
+
if (*s == '/')
s++;
- if (pm(p, s, flags))
- return (1);
+ r = pm(p, s, flags, 0);
+ if (r)
+ return (r);
}
return (0);
}
/* Default: Match from beginning. */
- return (pm(p, s, flags));
+ return (pm(p, s, flags, 0));
}
int
++p;
while (*s == L'/')
++s;
- return (pm_w(p, s, flags));
+ return (pm_w(p, s, flags, 0));
}
/* If start is unanchored, try to match start of each path element. */
if (flags & PATHMATCH_NO_ANCHOR_START) {
for ( ; s != NULL; s = wcschr(s, L'/')) {
+ int r;
+
if (*s == L'/')
s++;
- if (pm_w(p, s, flags))
- return (1);
+ r = pm_w(p, s, flags, 0);
+ if (r)
+ return (r);
}
return (0);
}
/* Default: Match from beginning. */
- return (pm_w(p, s, flags));
+ return (pm_w(p, s, flags, 0));
}
r = ioctl(*fd, FS_IOC_FIEMAP, fm);
if (r < 0) {
- /* When something error happens, it is better we
+ /* When some error happens, it is better we
* should return ARCHIVE_OK because an earlier
* version(<2.6.28) cannot perform FS_IOC_FIEMAP. */
goto exit_setup_sparse_fiemap;
if (a->matching) {
r = archive_match_path_excluded(a->matching, entry);
if (r < 0) {
- archive_set_error(&(a->archive), errno,
+ archive_set_error(&(a->archive), archive_errno(a->matching),
"%s", archive_error_string(a->matching));
return (r);
}
if (a->matching) {
r = archive_match_time_excluded(a->matching, entry);
if (r < 0) {
- archive_set_error(&(a->archive), errno,
+ archive_set_error(&(a->archive), archive_errno(a->matching),
"%s", archive_error_string(a->matching));
return (r);
}
if (a->matching) {
r = archive_match_owner_excluded(a->matching, entry);
if (r < 0) {
- archive_set_error(&(a->archive), errno,
+ archive_set_error(&(a->archive), archive_errno(a->matching),
"%s", archive_error_string(a->matching));
return (r);
}
if (a->matching) {
r = archive_match_path_excluded(a->matching, entry);
if (r < 0) {
- archive_set_error(&(a->archive), errno,
+ archive_set_error(&(a->archive), archive_errno(a->matching),
"%s", archive_error_string(a->matching));
return (r);
}
if (a->matching) {
r = archive_match_time_excluded(a->matching, entry);
if (r < 0) {
- archive_set_error(&(a->archive), errno,
+ archive_set_error(&(a->archive), archive_errno(a->matching),
"%s", archive_error_string(a->matching));
return (r);
}
if (a->matching) {
r = archive_match_owner_excluded(a->matching, entry);
if (r < 0) {
- archive_set_error(&(a->archive), errno,
+ archive_set_error(&(a->archive), archive_errno(a->matching),
"%s", archive_error_string(a->matching));
return (r);
}
for (;;) {
/* Support --fast-read option */
const char *p;
- if ((bsdtar->flags & OPTFLAG_FAST_READ) &&
- archive_match_path_unmatched_inclusions(bsdtar->matching) == 0)
- break;
+
+ if (bsdtar->flags & OPTFLAG_FAST_READ) {
+ r = archive_match_path_unmatched_inclusions(bsdtar->matching);
+ if (r < 0)
+ lafe_errc(1, 0, "%s", archive_error_string(a));
+ if (!r)
+ break;
+ }
r = archive_read_next_header(a, &entry);
progress_data.entry = entry;
* rewrite, there would be no way to exclude foo1/bar
* while allowing foo2/bar.)
*/
- if (archive_match_excluded(bsdtar->matching, entry))
+ r = archive_match_excluded(bsdtar->matching, entry);
+ if (r == ARCHIVE_FATAL)
+ lafe_errc(1, 0, "%s",
+ archive_error_string(bsdtar->matching));
+ if (r)
continue; /* Excluded by a pattern test. */
if (mode == 't') {
matching, &p)) == ARCHIVE_OK)
lafe_warnc(0, "%s: %s", p, msg);
if (r == ARCHIVE_FATAL)
- lafe_errc(1, errno, "Out of memory");
+ lafe_errc(1, 0, "%s", archive_error_string(matching));
return (archive_match_path_unmatched_inclusions(matching));
}
int e;
while (ARCHIVE_OK == (e = archive_read_next_header(ina, &in_entry))) {
- if (archive_match_excluded(bsdtar->matching, in_entry))
+ e = archive_match_excluded(bsdtar->matching, in_entry);
+ if (e < 0) {
+ if (!bsdtar->verbose)
+ lafe_errc(1, 0, "%s",
+ archive_error_string(bsdtar->matching));
+ else {
+ fprintf(stderr, ": %s",
+ archive_error_string(bsdtar->matching));
+ exit(1);
+ }
+ }
+ if (e)
continue;
if(edit_pathname(bsdtar, in_entry))
continue;