Move transforming function to common place

Move function for converting a MySQL account string to an
equivalent PCRE one, from Cache's rules.cc to mysql_utils.
This commit is contained in:
Johan Wikman 2016-12-29 10:57:35 +02:00
parent c6e155cf2b
commit 997bec868f
3 changed files with 86 additions and 75 deletions

View File

@ -44,4 +44,36 @@ MYSQL *mxs_mysql_real_connect(MYSQL *mysql, SERVER *server, const char *user, co
*/
bool mxs_mysql_trim_quotes(char *s);
typedef enum mxs_pcre_quote_approach
{
MXS_PCRE_QUOTE_VERBATIM, /*<! Quote all PCRE characters. */
MXS_PCRE_QUOTE_QUERY /*<! Quote all PCRE characters, except % that is converted into .*. */
} mxs_pcre_quote_approach_t;
typedef enum mxs_mysql_account_kind
{
MXS_MYSQL_ACCOUNT_WITH_WILDCARD, /*<! The input string contains a %. */
MXS_MYSQL_ACCOUNT_WITHOUT_WILDCARD /*<! The input string does not contain a %. */
} mxs_mysql_account_kind_t;
/**
* Convert MySQL/MariaDB account string to a pcre compatible one.
*
* In principle:
* - Quote all characters that have a special meaning in a PCRE context.
* - Optionally convert "%" into ".*".
*
* @param pcre The string to which the conversion should be copied.
* To be on the safe size, the buffer should be twice the
* size of 'mysql'.
* @param mysql The mysql account string.
* @param approach Whether % should be converted or not.
*
* @return Whether or not the account contains a wildcard.
*/
mxs_mysql_account_kind_t mxs_mysql_account_to_pcre(char *pcre,
const char *mysql,
mxs_pcre_quote_approach_t approach);
MXS_END_DECLS

View File

@ -235,3 +235,53 @@ bool mxs_mysql_trim_quotes(char *s)
return dequoted;
}
mxs_mysql_account_kind_t mxs_mysql_account_to_pcre(char *pcre,
const char *mysql,
mxs_pcre_quote_approach_t approach)
{
mxs_mysql_account_kind_t rv = MXS_MYSQL_ACCOUNT_WITHOUT_WILDCARD;
while (*mysql)
{
switch (*mysql)
{
case '%':
if (approach == MXS_PCRE_QUOTE_QUERY)
{
*pcre = '.';
pcre++;
*pcre = '*';
}
rv = MXS_MYSQL_ACCOUNT_WITH_WILDCARD;
break;
case '\'':
case '^':
case '.':
case '$':
case '|':
case '(':
case ')':
case '[':
case ']':
case '*':
case '+':
case '?':
case '{':
case '}':
*pcre++ = '\\';
// Flowthrough
default:
*pcre = *mysql;
}
++pcre;
++mysql;
}
*pcre = 0;
return rv;
}

View File

@ -138,21 +138,6 @@ static bool cache_rules_parse_array(CACHE_RULES *self, json_t *store, const char
static bool cache_rules_parse_store_element(CACHE_RULES *self, json_t *object, size_t index);
static bool cache_rules_parse_use_element(CACHE_RULES *self, json_t *object, size_t index);
typedef enum pcre_quote_approach
{
PCRE_QUOTE_VERBATIM,
PCRE_QUOTE_QUERY
} pcre_quote_approach_t;
typedef enum mysql_account_kind
{
MYSQL_ACCOUNT_WITH_WILDCARD,
MYSQL_ACCOUNT_WITHOUT_WILDCARD
} mysql_account_kind_t;
static mysql_account_kind_t mysql_to_pcre(char *pcre, const char *mysql, pcre_quote_approach_t approach);
/*
* API begin
*/
@ -618,14 +603,16 @@ static CACHE_RULE *cache_rule_create_simple_user(cache_rule_attribute_t attribut
}
else
{
mysql_to_pcre(pcre_user, user, PCRE_QUOTE_VERBATIM);
mxs_mysql_account_to_pcre(pcre_user, user, MXS_PCRE_QUOTE_VERBATIM);
}
if (mxs_mysql_trim_quotes(host))
{
char pcre_host[2 * len + 1]; // Surely enough
if (mysql_to_pcre(pcre_host, host, PCRE_QUOTE_QUERY) == MYSQL_ACCOUNT_WITH_WILDCARD)
mxs_mysql_account_kind_t rv = mxs_mysql_account_to_pcre(pcre_host, host, MXS_PCRE_QUOTE_QUERY);
if (rv == MXS_MYSQL_ACCOUNT_WITH_WILDCARD)
{
op = (op == CACHE_OP_EQ ? CACHE_OP_LIKE : CACHE_OP_UNLIKE);
@ -2044,61 +2031,3 @@ static bool cache_rules_parse_use_element(CACHE_RULES *self, json_t *object, siz
return rule != NULL;
}
/**
* Convert MySQL/MariaDB account string to a pcre compatible one.
*
* @param pcre The string to which the conversion should be copied.
* To be on the safe size, the buffer should be twice the
* size of 'mysql'.
* @param mysql The mysql account string.
* @param approach Whether % should be converted or not.
*
* @return Whether or not the account contains a wildcard.
*/
static mysql_account_kind_t mysql_to_pcre(char *pcre, const char *mysql, pcre_quote_approach_t approach)
{
mysql_account_kind_t rv = MYSQL_ACCOUNT_WITHOUT_WILDCARD;
while (*mysql)
{
switch (*mysql)
{
case '%':
if (approach == PCRE_QUOTE_QUERY)
{
*pcre = '.';
pcre++;
*pcre = '*';
}
rv = MYSQL_ACCOUNT_WITH_WILDCARD;
break;
case '\'':
case '^':
case '.':
case '$':
case '|':
case '(':
case ')':
case '[':
case ']':
case '*':
case '+':
case '?':
case '{':
case '}':
*pcre++ = '\\';
// Flowthrough
default:
*pcre = *mysql;
}
++pcre;
++mysql;
}
*pcre = 0;
return rv;
}