mirror of
https://github.com/RsyncProject/rsync.git
synced 2026-10-25 15:18:16 -04:00
- Added [:class:] handling to the character-class code.
- Use explicit unsigned characters for proper set checks. - Made the character-class code honor backslash escapes. - Accept '^' as a class-negation character in addition to '!'.
This commit is contained in:
1 parent
84229c7ac9
commit
e11c425119
1 file changed
+52
-7
+52
-7
@@ -12,21 +12,24 @@
|
||||
#include "rsync.h"
|
||||
|
||||
/* What character marks an inverted character class? */
|
||||
#define NEGATE_CLASS '!'
|
||||
#define NEGATE_CLASS '!'
|
||||
#define NEGATE_CLASS2 '^'
|
||||
|
||||
#define FALSE 0
|
||||
#define TRUE 1
|
||||
#define ABORT_ALL -1
|
||||
#define ABORT_TO_STARSTAR -2
|
||||
|
||||
#define CC_EQ(class, len, litmatch) ((len) == sizeof (litmatch)-1 && strncmp(class, litmatch, len) == 0)
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
int wildmatch_iteration_count;
|
||||
#endif
|
||||
|
||||
static int domatch(const char *p, const char *text)
|
||||
static int domatch(const unsigned char *p, const unsigned char *text)
|
||||
{
|
||||
int matched, special;
|
||||
char ch, prev;
|
||||
unsigned char ch, prev;
|
||||
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count++;
|
||||
@@ -73,6 +76,10 @@ static int domatch(const char *p, const char *text)
|
||||
return ABORT_ALL;
|
||||
case '[':
|
||||
ch = *++p;
|
||||
#ifdef NEGATE_CLASS2
|
||||
if (ch == NEGATE_CLASS2)
|
||||
ch = NEGATE_CLASS;
|
||||
#endif
|
||||
/* Assign literal TRUE/FALSE because of "matched" comparison. */
|
||||
special = ch == NEGATE_CLASS? TRUE : FALSE;
|
||||
if (special) {
|
||||
@@ -84,9 +91,46 @@ static int domatch(const char *p, const char *text)
|
||||
do {
|
||||
if (!ch)
|
||||
return FALSE;
|
||||
if (ch == '-' && prev && p[1] && p[1] != ']') {
|
||||
if (*text <= *++p && *text >= prev)
|
||||
if (ch == '\\') {
|
||||
ch = *++p;
|
||||
if (!ch)
|
||||
return FALSE;
|
||||
if (*text == ch)
|
||||
matched = TRUE;
|
||||
}
|
||||
else if (ch == '-' && prev && p[1] && p[1] != ']') {
|
||||
ch = *++p;
|
||||
if (ch == '\\') {
|
||||
ch = *++p;
|
||||
if (!ch)
|
||||
return FALSE;
|
||||
}
|
||||
if (*text <= ch && *text >= prev)
|
||||
matched = TRUE;
|
||||
ch = 0; /* This makes "prev" get set to 0. */
|
||||
}
|
||||
else if (ch == '[' && p[1] == ':') {
|
||||
unsigned const char *s = p += 2;
|
||||
int i;
|
||||
while ((ch = *p) && (ch != ':' || p[1] != ']')) p++;
|
||||
if (!ch)
|
||||
return FALSE;
|
||||
i = p - s;
|
||||
ch = *text;
|
||||
if ((CC_EQ(s,i, "alnum") && isalnum(ch))
|
||||
|| (CC_EQ(s,i, "alpha") && isalpha(ch))
|
||||
|| (CC_EQ(s,i, "blank") && isblank(ch))
|
||||
|| (CC_EQ(s,i, "cntrl") && iscntrl(ch))
|
||||
|| (CC_EQ(s,i, "digit") && isdigit(ch))
|
||||
|| (CC_EQ(s,i, "graph") && isgraph(ch))
|
||||
|| (CC_EQ(s,i, "lower") && islower(ch))
|
||||
|| (CC_EQ(s,i, "print") && isprint(ch))
|
||||
|| (CC_EQ(s,i, "punct") && ispunct(ch))
|
||||
|| (CC_EQ(s,i, "space") && isspace(ch))
|
||||
|| (CC_EQ(s,i, "upper") && isupper(ch))
|
||||
|| (CC_EQ(s,i,"xdigit") && isxdigit(ch)))
|
||||
matched = TRUE;
|
||||
p++;
|
||||
ch = 0; /* This makes "prev" get set to 0. */
|
||||
}
|
||||
else if (*text == ch)
|
||||
@@ -101,10 +145,11 @@ static int domatch(const char *p, const char *text)
|
||||
return *text == '\0';
|
||||
}
|
||||
|
||||
int wildmatch(const char *p, const char *text)
|
||||
/* Find the pattern (p) in the text string (t). */
|
||||
int wildmatch(const char *p, const char *t)
|
||||
{
|
||||
#ifdef WILD_TEST_ITERATIONS
|
||||
wildmatch_iteration_count = 0;
|
||||
#endif
|
||||
return domatch(p, text) == TRUE;
|
||||
return domatch((const unsigned char*)p, (const unsigned char*)t) == TRUE;
|
||||
}
|
||||
Reference in new issue
Block a user