summaryrefslogtreecommitdiff
path: root/mysys/mf_wcomp.c
diff options
context:
space:
mode:
authorunknown <serg@serg.mylan>2003-07-22 22:21:23 +0200
committerunknown <serg@serg.mylan>2003-07-22 22:21:23 +0200
commit1cf4eea19d870f9e6fe147ec36b7df0eef1514cf (patch)
tree0eec29de18641195250ca526517244f6f0b0e820 /mysys/mf_wcomp.c
parentb413e5c420c3cdb32b519f67aaacf7ad1126d71e (diff)
downloadmariadb-git-1cf4eea19d870f9e6fe147ec36b7df0eef1514cf.tar.gz
now GRANT db.* ... compares patterns correctly to prevent privilege escalation
Diffstat (limited to 'mysys/mf_wcomp.c')
-rw-r--r--mysys/mf_wcomp.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/mysys/mf_wcomp.c b/mysys/mf_wcomp.c
index bdcfb0501d8..62a5a02eaea 100644
--- a/mysys/mf_wcomp.c
+++ b/mysys/mf_wcomp.c
@@ -23,11 +23,12 @@
char wild_many='*';
char wild_one='?';
-char wild_prefix=0;
+char wild_prefix=0; /* QQ this can potentially cause a SIGSEGV */
-int wild_compare(register const char *str, register const char *wildstr)
+int wild_compare(register const char *str, register const char *wildstr,
+ pbool str_is_pattern)
{
- reg3 int flag;
+ char cmp;
DBUG_ENTER("wild_compare");
while (*wildstr)
@@ -35,33 +36,55 @@ int wild_compare(register const char *str, register const char *wildstr)
while (*wildstr && *wildstr != wild_many && *wildstr != wild_one)
{
if (*wildstr == wild_prefix && wildstr[1])
+ {
wildstr++;
- if (*wildstr++ != *str++) DBUG_RETURN(1);
+ if (str_is_pattern && *str++ != wild_prefix)
+ DBUG_RETURN(1);
+ }
+ if (*wildstr++ != *str++)
+ DBUG_RETURN(1);
}
- if (! *wildstr ) DBUG_RETURN (*str != 0);
+ if (! *wildstr )
+ DBUG_RETURN(*str != 0);
if (*wildstr++ == wild_one)
{
- if (! *str++) DBUG_RETURN (1); /* One char; skipp */
+ if (! *str || (str_is_pattern && *str == wild_many))
+ DBUG_RETURN(1); /* One char; skipp */
+ if (*str++ == wild_prefix && str_is_pattern && *str)
+ str++;
}
else
{ /* Found '*' */
- if (!*wildstr) DBUG_RETURN(0); /* '*' as last char: OK */
- flag=(*wildstr != wild_many && *wildstr != wild_one);
- do
+ while (str_is_pattern && *str == wild_many)
+ str++;
+ for (; *wildstr == wild_many || *wildstr == wild_one; wildstr++)
+ if (*wildstr == wild_many)
+ {
+ while (str_is_pattern && *str == wild_many)
+ str++;
+ }
+ else
+ {
+ if (str_is_pattern && *str == wild_prefix && str[1])
+ str+=2;
+ else if (! *str++)
+ DBUG_RETURN (1);
+ }
+ if (!*wildstr)
+ DBUG_RETURN(0); /* '*' as last char: OK */
+ if ((cmp= *wildstr) == wild_prefix && wildstr[1] && !str_is_pattern)
+ cmp=wildstr[1];
+ for(;;str++)
{
- if (flag)
- {
- char cmp;
- if ((cmp= *wildstr) == wild_prefix && wildstr[1])
- cmp=wildstr[1];
- while (*str && *str != cmp)
- str++;
- if (!*str) DBUG_RETURN (1);
- }
- if (wild_compare(str,wildstr) == 0) DBUG_RETURN (0);
- } while (*str++ && wildstr[0] != wild_many);
+ while (*str && *str != cmp)
+ str++;
+ if (!*str)
+ DBUG_RETURN (1);
+ if (wild_compare(str,wildstr,str_is_pattern) == 0)
+ DBUG_RETURN (0);
+ }
DBUG_RETURN(1);
}
}
- DBUG_RETURN (*str != '\0');
+ DBUG_RETURN (*str != 0);
} /* wild_compare */