aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorantirez <antirez>2005-03-02 15:41:08 +0000
committerantirez <antirez>2005-03-02 15:41:08 +0000
commit193815c2578cbf0969d2cfe54ba4c0b9e7758c60 (patch)
treea0f2db4306b051b4c228ee914b3b93c44623e9db
parent94883fb48db43a0294a1c3dd749eb224a7c40c5f (diff)
downloadjimtcl-193815c2578cbf0969d2cfe54ba4c0b9e7758c60.zip
jimtcl-193815c2578cbf0969d2cfe54ba4c0b9e7758c60.tar.gz
jimtcl-193815c2578cbf0969d2cfe54ba4c0b9e7758c60.tar.bz2
binary safe JimStringMatch()
-rw-r--r--jim.c65
-rw-r--r--test.tcl93
2 files changed, 44 insertions, 114 deletions
diff --git a/jim.c b/jim.c
index 572e91a..d48fae4 100644
--- a/jim.c
+++ b/jim.c
@@ -160,47 +160,59 @@ static jim_wide JimStrtoll(const char *nptr, char **endptr, register int base)
#endif
/* Glob-style pattern matching. */
-static int JimStringMatch(char *pattern, char *string, int nocase)
+static int JimStringMatch(char *pattern, int patternLen,
+ char *string, int stringLen, int nocase)
{
- while(pattern[0]) {
+ while(patternLen) {
switch(pattern[0]) {
case '*':
- while (pattern[1] == '*')
+ while (pattern[1] == '*') {
pattern++;
- if (pattern[1] == '\0')
+ patternLen--;
+ }
+ if (patternLen == 1)
return 1; /* match */
- while(string[0]) {
- if (JimStringMatch(pattern+1, string, nocase))
+ while(stringLen) {
+ if (JimStringMatch(pattern+1, patternLen-1,
+ string, stringLen, nocase))
return 1; /* match */
string++;
+ stringLen--;
}
return 0; /* no match */
break;
case '?':
- if (string[0] == '\0')
+ if (stringLen == 0)
return 0; /* no match */
string++;
+ stringLen--;
break;
case '[':
{
int not, match;
pattern++;
+ patternLen--;
not = pattern[0] == '^';
- if (not) pattern++;
+ if (not) {
+ pattern++;
+ patternLen--;
+ }
match = 0;
while(1) {
if (pattern[0] == '\\') {
pattern++;
+ patternLen--;
if (pattern[0] == string[0])
match = 1;
} else if (pattern[0] == ']') {
break;
- } else if (pattern[0] == '\0') {
+ } else if (patternLen == 0) {
pattern--;
+ patternLen++;
break;
} else if (pattern[1] == '-' &&
- pattern[2] != '\0') {
+ patternLen >= 3) {
int start = pattern[0];
int end = pattern[2];
int c = string[0];
@@ -215,6 +227,7 @@ static int JimStringMatch(char *pattern, char *string, int nocase)
c = tolower(c);
}
pattern += 2;
+ patternLen -= 2;
if (c >= start && c <= end)
match = 1;
} else {
@@ -228,17 +241,21 @@ static int JimStringMatch(char *pattern, char *string, int nocase)
}
}
pattern++;
+ patternLen--;
}
if (not)
match = !match;
if (!match)
return 0; /* no match */
string++;
+ stringLen--;
break;
}
case '\\':
- if (pattern[1] != '\0')
+ if (patternLen >= 2) {
pattern++;
+ patternLen--;
+ }
/* fall through */
default:
if (!nocase) {
@@ -250,17 +267,20 @@ static int JimStringMatch(char *pattern, char *string, int nocase)
return 0; /* no match */
}
string++;
+ stringLen--;
break;
}
pattern++;
- if (string[0] == '\0') {
- while(*pattern == '*')
+ patternLen--;
+ if (stringLen == 0) {
+ while(*pattern == '*') {
pattern++;
+ patternLen--;
+ }
break;
}
}
- if (pattern[0] == '\0' &&
- string[0] == '\0')
+ if (patternLen == 0 && stringLen == 0)
return 1;
return 0;
}
@@ -280,7 +300,7 @@ int testGlobMatching(void)
if (len && buf[len-1] == '\n') {
buf[len-1] = '\0';
}
- printf("%d\n", JimStringMatch(buf, str, 0));
+ printf("%d\n", JimStringMatch(buf, strlen(buf), str, strlen(str), 0));
}
return 0;
}
@@ -1912,10 +1932,11 @@ int Jim_StringEqObj(Jim_Obj *aObjPtr, Jim_Obj *bObjPtr, int nocase)
int Jim_StringMatchObj(Jim_Obj *patternObjPtr, Jim_Obj *objPtr, int nocase)
{
char *pattern, *string;
+ int patternLen, stringLen;
- pattern = Jim_GetString(patternObjPtr, NULL);
- string = Jim_GetString(objPtr, NULL);
- return JimStringMatch(pattern, string, nocase);
+ pattern = Jim_GetString(patternObjPtr, &patternLen);
+ string = Jim_GetString(objPtr, &stringLen);
+ return JimStringMatch(pattern, patternLen, string, stringLen, nocase);
}
/* Convert a range, as returned by Jim_GetRange(), into
@@ -6954,11 +6975,13 @@ static Jim_Obj *JimCommandsList(Jim_Interp *interp, Jim_Obj *patternObjPtr)
Jim_HashEntry *he;
Jim_Obj *listObjPtr = Jim_NewListObj(interp, NULL, 0);
char *pattern;
+ int patternLen;
- pattern = patternObjPtr ? Jim_GetString(patternObjPtr, NULL) : NULL;
+ pattern = patternObjPtr ? Jim_GetString(patternObjPtr, &patternLen) : NULL;
htiter = Jim_GetHashTableIterator(&interp->commands);
while ((he = Jim_NextHashEntry(htiter)) != NULL) {
- if (pattern && !JimStringMatch(pattern, he->key, 0))
+ if (pattern && !JimStringMatch(pattern, patternLen, he->key,
+ strlen((char*)he->key), 0))
continue;
Jim_ListAppendElement(interp, listObjPtr,
Jim_NewStringObj(interp, he->key, -1));
diff --git a/test.tcl b/test.tcl
index 92cfb88..011fa21 100644
--- a/test.tcl
+++ b/test.tcl
@@ -634,99 +634,6 @@ catch {unset ::x}
catch {unset ::y}
################################################################################
-# STRING MATCH
-################################################################################
-
-test string-11.3 {string match} {
- string match abc abc
-} 1
-test string-11.5 {string match} {
- string match ab*c abc
-} 1
-test string-11.6 {string match} {
- string match ab**c abc
-} 1
-test string-11.7 {string match} {
- string match ab* abcdef
-} 1
-test string-11.8 {string match} {
- string match *c abc
-} 1
-test string-11.9 {string match} {
- string match *3*6*9 0123456789
-} 1
-test string-11.10 {string match} {
- string match *3*6*9 01234567890
-} 0
-test string-11.11 {string match} {
- string match a?c abc
-} 1
-test string-11.12 {string match} {
- string match a??c abc
-} 0
-test string-11.13 {string match} {
- string match ?1??4???8? 0123456789
-} 1
-test string-11.14 {string match} {
- string match {[abc]bc} abc
-} 1
-test string-11.15 {string match} {
- string match {a[abc]c} abc
-} 1
-test string-11.16 {string match} {
- string match {a[xyz]c} abc
-} 0
-test string-11.17 {string match} {
- string match {12[2-7]45} 12345
-} 1
-test string-11.18 {string match} {
- string match {12[ab2-4cd]45} 12345
-} 1
-test string-11.19 {string match} {
- string match {12[ab2-4cd]45} 12b45
-} 1
-test string-11.20 {string match} {
- string match {12[ab2-4cd]45} 12d45
-} 1
-test string-11.21 {string match} {
- string match {12[ab2-4cd]45} 12145
-} 0
-test string-11.22 {string match} {
- string match {12[ab2-4cd]45} 12545
-} 0
-test string-11.23 {string match} {
- string match {a\*b} a*b
-} 1
-test string-11.24 {string match} {
- string match {a\*b} ab
-} 0
-test string-11.25 {string match} {
- string match {a\*\?\[\]\\\x} "a*?\[\]\\x"
-} 1
-test string-11.26 {string match} {
- string match ** ""
-} 1
-test string-11.27 {string match} {
- string match *. ""
-} 0
-test string-11.28 {string match} {
- string match "" ""
-} 1
-test string-11.29 {string match} {
- string match \[a a
-} 1
-test string-11.31 {string match case} {
- string match a A
-} 0
-test string-11.34 {string match nocase} {
- string match -nocase a*f ABCDEf
-} 1
-test string-11.35 {string match case, false hope} {
- # This is true because '_' lies between the A-Z and a-z ranges
- string match {[A-z]} _
-} 1
-
-################################################################################
# IF
################################################################################