* mu-query.cc, mu-store.cc: use the escaping for some fields; update test case

This commit is contained in:
Dirk-Jan C. Binnema
2010-11-29 21:29:43 +02:00
parent bb5b1304e5
commit 3d3a4f8308
3 changed files with 39 additions and 111 deletions

View File

@ -288,97 +288,22 @@ mu_query_destroy (MuQuery *self)
g_free (self);
}
struct _CheckPrefix {
const char *pfx;
guint len;
gboolean match;
};
typedef struct _CheckPrefix CheckPrefix;
static void
each_check_prefix (MuMsgFieldId mfid, CheckPrefix *cpfx)
{
const char *field_name;
char field_shortcut;
if (!cpfx || cpfx->match)
return;
field_shortcut = mu_msg_field_shortcut (mfid);
if (field_shortcut == cpfx->pfx[0]) {
cpfx->match = TRUE;
return;
}
field_name = mu_msg_field_name (mfid);
if (field_name &&
strncmp (cpfx->pfx, field_name, cpfx->len) == 0) {
cpfx->match = TRUE;
return;
}
}
/* colon is a position inside q pointing at a ':' character. function
* determines whether the prefix is a registered prefix (like
* 'subject' or 'from' or 's') */
static gboolean
is_xapian_prefix (const char *q, const char *colon)
{
const char *cur;
if (colon == q)
return FALSE; /* : at beginning, not a prefix */
/* track back from colon until a boundary or beginning of the
* str */
for (cur = colon - 1; cur >= q; --cur) {
if (cur == q || !isalpha (*(cur-1))) {
CheckPrefix cpfx;
memset (&cpfx, 0, sizeof(CheckPrefix));
cpfx.pfx = cur;
cpfx.len = (colon - cur);
cpfx.match = FALSE;
mu_msg_field_foreach ((MuMsgFieldForEachFunc)
each_check_prefix,
&cpfx);
return (cpfx.match);
}
}
return FALSE;
}
/* preprocess a query to make them a bit more permissive */
char*
mu_query_preprocess (const char *query)
{
gchar *my_query;
gchar *cur;
g_return_val_if_fail (query, NULL);
my_query = g_strdup (query);
/* translate the the searchexpr to all lowercase; this
* will fixes some of the false-negatives. A full fix
* probably requires some custom query parser.
*/
my_query = mu_str_normalize(query, TRUE);
for (cur = my_query; *cur; ++cur) {
if (*cur == ':') /* we found a ':' */
/* if there's a registered xapian prefix before the
* ':', don't touch it. Otherwise replace ':' with
* a space'... ugly...
*/
if (!is_xapian_prefix (my_query, cur))
*cur = ' ';
}
/* remove accents and turn to lower-case */
mu_str_normalize_in_place (my_query, TRUE);
/* escape '@', single '_' and ':' if it's not following a
* xapian-pfx with '_' */
mu_str_ascii_xapian_escape_in_place (my_query);
return my_query;
}