[tracker/tracker-0.6] Fix corner cases in the RDF parser wrt '%', '[' and '*' chars. Fully fixes NB#123030.
- From: Carlos Garnacho <carlosg src gnome org>
- To: svn-commits-list gnome org
- Subject: [tracker/tracker-0.6] Fix corner cases in the RDF parser wrt '%', '[' and '*' chars. Fully fixes NB#123030.
- Date: Fri, 19 Jun 2009 07:44:48 -0400 (EDT)
commit 11f5e6d1394a85d551787b320754f109f09993a8
Author: Carlos Garnacho <carlosg gnome org>
Date: Fri Jun 19 13:31:23 2009 +0200
Fix corner cases in the RDF parser wrt '%', '[' and '*' chars. Fully fixes NB#123030.
* if the RDF parser finds '*' globs, it's now translated to a LIKE clause, so we do not
have to escape '[' to "[[]". This also makes RDF glob search caseless for ASCII.
* Add a boolean parameter to tracker_escape_db_string() to escape '%' or not, based
on what's the string going to be used for. Literal comparisons do not need these
escaped, and will look for the wrong string if it is.
src/libtracker-common/tracker-utils.c | 12 ++++--
src/libtracker-common/tracker-utils.h | 3 +-
src/libtracker-data/tracker-data-update.c | 14 ++++---
src/libtracker-data/tracker-rdf-query.c | 66 ++++++++++++++++++-----------
src/libtracker-db/tracker-db-manager.c | 4 +-
5 files changed, 61 insertions(+), 38 deletions(-)
---
diff --git a/src/libtracker-common/tracker-utils.c b/src/libtracker-common/tracker-utils.c
index b1bb538..b36f0d3 100644
--- a/src/libtracker-common/tracker-utils.c
+++ b/src/libtracker-common/tracker-utils.c
@@ -104,7 +104,8 @@ tracker_string_replace (const gchar *haystack,
gchar *
tracker_escape_db_string (const gchar *str,
- gboolean add_quotes)
+ gboolean add_quotes,
+ gboolean escape_percent)
{
gchar *escaped, *p;
guint len;
@@ -131,9 +132,12 @@ tracker_escape_db_string (const gchar *str,
switch (*str) {
case '\'':
case '%':
- /* These chars need to be twice in the escaped string */
- *p = *str;
- p++;
+ if (*str != '%' || escape_percent) {
+ /* These chars need to be twice in the escaped string */
+ *p = *str;
+ p++;
+ }
+
/* Fall through */
default:
*p = *str;
diff --git a/src/libtracker-common/tracker-utils.h b/src/libtracker-common/tracker-utils.h
index 48ef635..a3529a6 100644
--- a/src/libtracker-common/tracker-utils.h
+++ b/src/libtracker-common/tracker-utils.h
@@ -36,7 +36,8 @@ gchar * tracker_string_replace (const gchar *haystack,
gchar * tracker_string_remove (gchar *haystack,
const gchar *needle);
gchar * tracker_escape_db_string (const gchar *str,
- gboolean add_quotes);
+ gboolean add_quotes,
+ gboolean escape_percent);
gchar * tracker_seconds_estimate_to_string (gdouble seconds_elapsed,
gboolean short_string,
guint items_done,
diff --git a/src/libtracker-data/tracker-data-update.c b/src/libtracker-data/tracker-data-update.c
index 2c4cbe3..61bca90 100644
--- a/src/libtracker-data/tracker-data-update.c
+++ b/src/libtracker-data/tracker-data-update.c
@@ -755,7 +755,7 @@ tracker_data_update_replace_service (const gchar *udi,
}
file_mtime = atoi (modified);
- escaped_path = tracker_escape_db_string (path, FALSE);
+ escaped_path = tracker_escape_db_string (path, FALSE, TRUE);
basename = g_path_get_basename (escaped_path);
dirname = g_path_get_dirname (escaped_path);
@@ -932,13 +932,15 @@ tracker_data_update_metadata_context_add (TrackerDataUpdateMetadataContext *cont
const gchar *value,
const gchar *function)
{
+ gchar *escaped;
+
+ escaped = tracker_escape_db_string (value, TRUE, TRUE);
+
if (G_UNLIKELY (function)) {
- gchar *escaped;
gchar *wrapped;
- escaped = tracker_escape_db_string (value, TRUE);
- wrapped = g_strdup_printf ("%s(%s)",
- function,
+ wrapped = g_strdup_printf ("%s(%s)",
+ function,
escaped);
g_free (escaped);
@@ -948,7 +950,7 @@ tracker_data_update_metadata_context_add (TrackerDataUpdateMetadataContext *cont
} else {
g_hash_table_replace (context->data,
g_strdup (column),
- tracker_escape_db_string (value, TRUE));
+ escaped);
}
}
diff --git a/src/libtracker-data/tracker-rdf-query.c b/src/libtracker-data/tracker-rdf-query.c
index 3b70948..1d1cfe3 100644
--- a/src/libtracker-data/tracker-rdf-query.c
+++ b/src/libtracker-data/tracker-rdf-query.c
@@ -742,12 +742,27 @@ start_element_handler (GMarkupParseContext *context,
}
}
+static void
+replace_wildcards (gchar *str)
+{
+ gchar *c;
+
+ /* Replace glob-like wildcards
+ * with % so we can use LIKE clauses
+ */
+ for (c = str; *c; c++) {
+ if (*c == '*') {
+ *c = '%';
+ }
+ }
+}
+
static gboolean
build_sql (ParserData *data)
{
TrackerFieldData *field_data;
ParseState state;
- gchar *avalue, *value, *sub;
+ gchar *avalue, *value, *sub, *val;
const gchar *where_field;
GString *str;
gchar **s;
@@ -764,9 +779,10 @@ build_sql (ParserData *data)
state = peek_state (data);
avalue = tracker_escape_db_string (data->current_value,
- state != STATE_END_DATE &&
- state != STATE_END_INTEGER &&
- state != STATE_END_FLOAT);
+ (state != STATE_END_DATE &&
+ state != STATE_END_INTEGER &&
+ state != STATE_END_FLOAT),
+ FALSE);
field_data = add_metadata_field (data, data->current_field, FALSE, TRUE, FALSE);
@@ -809,9 +825,12 @@ build_sql (ParserData *data)
case OP_EQUALS:
sub = strchr (data->current_value, '*');
if (sub) {
- g_string_append_printf (str, " (%s glob '%s') ",
- where_field,
- data->current_value);
+ val = tracker_escape_db_string (data->current_value, FALSE, TRUE);
+ replace_wildcards (val);
+
+ g_string_append_printf (str, " (%s like '%s') ",
+ where_field, val);
+ g_free (val);
} else {
/* FIXME This check is too fragile */
if ( !strlen(value) || (strcmp(value, "''") == 0) ) {
@@ -821,8 +840,7 @@ build_sql (ParserData *data)
where_field);
} else {
g_string_append_printf (str, " (%s = %s) ",
- where_field,
- value);
+ where_field, value);
}
}
break;
@@ -852,31 +870,35 @@ build_sql (ParserData *data)
break;
case OP_CONTAINS:
+ val = tracker_escape_db_string (data->current_value, FALSE, TRUE);
sub = strchr (data->current_value, '*');
if (sub) {
+ replace_wildcards (val);
g_string_append_printf (str, " (%s like '%%%%%s%%%%') ",
- where_field,
- data->current_value);
+ where_field, val);
} else {
g_string_append_printf (str, " (%s like '%%%%%s%%%%') ",
- where_field,
- data->current_value);
+ where_field, val);
}
+
+ g_free (val);
break;
case OP_STARTS:
+ val = tracker_escape_db_string (data->current_value, FALSE, TRUE);
sub = strchr (data->current_value, '*');
if (sub) {
+ replace_wildcards (val);
g_string_append_printf (str, " (%s like '%s') ",
- where_field,
- data->current_value);
+ where_field, val);
} else {
g_string_append_printf (str, " (%s like '%s%%%%') ",
- where_field,
- data->current_value);
+ where_field, val);
}
+
+ g_free (val);
break;
case OP_REGEX:
@@ -1095,13 +1117,7 @@ text_handler (GMarkupParseContext *context,
case STATE_STRING:
case STATE_DATE:
case STATE_FLOAT:
- {
- gchar *str;
-
- str = g_strstrip (g_strndup (text, text_len));
- data->current_value = tracker_escape_db_string (str, FALSE);
- g_free (str);
- }
+ data->current_value = g_strstrip (g_strndup (text, text_len));
break;
default:
break;
@@ -1290,7 +1306,7 @@ tracker_rdf_query_to_sql (TrackerDBInterface *iface,
}
list = g_hash_table_lookup (table, key);
- list = g_list_prepend (list, tracker_escape_db_string (value, TRUE));
+ list = g_list_prepend (list, tracker_escape_db_string (value, TRUE, FALSE));
g_hash_table_insert (table, g_strdup (key), list);
g_free (full);
diff --git a/src/libtracker-db/tracker-db-manager.c b/src/libtracker-db/tracker-db-manager.c
index 43e9e15..e1e79aa 100644
--- a/src/libtracker-db/tracker-db-manager.c
+++ b/src/libtracker-db/tracker-db-manager.c
@@ -512,7 +512,7 @@ load_metadata_file (TrackerDBInterface *iface,
} else {
gchar *escaped_value;
- escaped_value = tracker_escape_db_string (new_value, TRUE);
+ escaped_value = tracker_escape_db_string (new_value, TRUE, FALSE);
tracker_db_interface_execute_query (iface, NULL,
"update MetaDataTypes set %s = %s where ID = %d",
@@ -675,7 +675,7 @@ load_service_file (TrackerDBInterface *iface,
value = g_key_file_get_string (key_file, groups[i], keys[j], NULL);
new_value = tracker_string_boolean_to_string_gint (value);
- escaped_value = tracker_escape_db_string (new_value, TRUE);
+ escaped_value = tracker_escape_db_string (new_value, TRUE, FALSE);
/* Special case "Parent */
if (g_ascii_strcasecmp (keys[j], "parent") == 0) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]