Strengthen against sqlite failures in FTS functions (Red Hat #1026283)

This commit is contained in:
Debarshi Ray 2013-12-03 18:15:09 +01:00
parent 50b2bfee20
commit 496a99a220
2 changed files with 146 additions and 3 deletions

View File

@ -0,0 +1,136 @@
From 00b71d0f9ae3f4d2b7bc8fa2afe08cd89c5c9c35 Mon Sep 17 00:00:00 2001
From: Carlos Garnacho <carlosg@gnome.org>
Date: Tue, 3 Dec 2013 16:17:54 +0100
Subject: [PATCH] fts: Strengthen against sqlite failures in FTS functions
function_weights() and function_property_names() (used respectively by
SPARQL fts:rank and fts:offsets functions), initialize all data at first
from the database, so it's available in memory for posterior runs,
although currently those are being quite optimistic about the database
return values in several ways, so:
- Ensure no infinite loops happen on sqlite3_step() if the stmt trips
into some unexpected state. SQLITE_BUSY still does keep looping though.
- As initialization here is a failable task, stop using g_once_init_*
and use an static GMutex so initialization can be tried later again
if it failed previously.
- For the cases where initialization failed, propagate the error code
on the sqlite3_context.
Based on work by Tim Waugh and Michael Catanzaro.
https://bugzilla.redhat.com/show_bug.cgi?id=1026283
---
src/libtracker-fts/tracker-fts.c | 52 +++++++++++++++++++++++++++-------------
1 file changed, 36 insertions(+), 16 deletions(-)
diff --git a/src/libtracker-fts/tracker-fts.c b/src/libtracker-fts/tracker-fts.c
index 530d831..446a4a6 100644
--- a/src/libtracker-fts/tracker-fts.c
+++ b/src/libtracker-fts/tracker-fts.c
@@ -127,13 +127,15 @@ function_weights (sqlite3_context *context,
sqlite3_value *argv[])
{
static guint *weights = NULL;
- static gsize weights_initialized = 0;
+ static GMutex mutex;
+ int rc = SQLITE_DONE;
- if (g_once_init_enter (&weights_initialized)) {
+ g_mutex_lock (&mutex);
+
+ if (G_UNLIKELY (weights == NULL)) {
GArray *weight_array;
sqlite3_stmt *stmt;
sqlite3 *db;
- int rc;
weight_array = g_array_new (FALSE, FALSE, sizeof (guint));
db = sqlite3_context_db_handle (context);
@@ -149,18 +151,26 @@ function_weights (sqlite3_context *context,
guint weight;
weight = sqlite3_column_int (stmt, 0);
g_array_append_val (weight_array, weight);
+ } else if (rc != SQLITE_BUSY) {
+ break;
}
}
+ sqlite3_finalize (stmt);
+
if (rc == SQLITE_DONE) {
- rc = sqlite3_finalize (stmt);
+ weights = (guint *) g_array_free (weight_array, FALSE);
+ } else {
+ g_array_free (weight_array, TRUE);
}
-
- weights = (guint *) g_array_free (weight_array, FALSE);
- g_once_init_leave (&weights_initialized, (rc == SQLITE_OK));
}
- sqlite3_result_blob (context, weights, sizeof (weights), NULL);
+ g_mutex_unlock (&mutex);
+
+ if (rc == SQLITE_DONE)
+ sqlite3_result_blob (context, weights, sizeof (weights), NULL);
+ else
+ sqlite3_result_error_code (context, rc);
}
static void
@@ -169,13 +179,15 @@ function_property_names (sqlite3_context *context,
sqlite3_value *argv[])
{
static gchar **names = NULL;
- static gsize names_initialized = 0;
+ static GMutex mutex;
+ int rc = SQLITE_DONE;
- if (g_once_init_enter (&names_initialized)) {
+ g_mutex_lock (&mutex);
+
+ if (G_UNLIKELY (names == NULL)) {
GPtrArray *names_array;
sqlite3_stmt *stmt;
sqlite3 *db;
- int rc;
names_array = g_ptr_array_new ();
db = sqlite3_context_db_handle (context);
@@ -194,18 +206,26 @@ function_property_names (sqlite3_context *context,
name = sqlite3_column_text (stmt, 0);
g_ptr_array_add (names_array, g_strdup (name));
+ } else if (rc != SQLITE_BUSY) {
+ break;
}
}
+ sqlite3_finalize (stmt);
+
if (rc == SQLITE_DONE) {
- rc = sqlite3_finalize (stmt);
+ names = (gchar **) g_ptr_array_free (names_array, FALSE);
+ } else {
+ g_ptr_array_free (names_array, TRUE);
}
-
- names = (gchar **) g_ptr_array_free (names_array, FALSE);
- g_once_init_leave (&names_initialized, (rc == SQLITE_OK));
}
- sqlite3_result_blob (context, names, sizeof (names), NULL);
+ g_mutex_unlock (&mutex);
+
+ if (rc == SQLITE_DONE)
+ sqlite3_result_blob (context, names, sizeof (names), NULL);
+ else
+ sqlite3_result_error_code (context, rc);
}
static void
--
1.8.4.2

View File

@ -15,7 +15,7 @@
Summary: Desktop-neutral search tool and indexer
Name: tracker
Version: 0.16.4
Release: 1%{?dist}
Release: 2%{?dist}
License: GPLv2+
Group: Applications/System
URL: http://projects.gnome.org/tracker/
@ -25,8 +25,11 @@ Source0: http://download.gnome.org/sources/tracker/0.16/%{name}-%{version}.tar.x
# https://bugzilla.redhat.com/show_bug.cgi?id=771601
Patch1: tracker-0.15-onlyshowin.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=1026283
Patch2: 0001-fts-Strengthen-against-sqlite-failures-in-FTS-functi.patch
# https://bugzilla.gnome.org/show_bug.cgi?id=712142
Patch2: 0001-Bump-the-minimum-memory-requirement-to-768M.patch
Patch3: 0001-Bump-the-minimum-memory-requirement-to-768M.patch
BuildRequires: poppler-glib-devel libxml2-devel libgsf-devel libgxps-devel
BuildRequires: libuuid-devel
@ -141,7 +144,8 @@ This package contains the documentation for tracker
%setup -q
%patch1 -p1 -b .onlyshowin
%patch2 -p1 -b .memory
%patch2 -p1 -b .fts
%patch3 -p1 -b .memory
#%global evo_plugins_dir %(pkg-config evolution-plugin-3.0 --variable=plugindir)
@ -274,6 +278,9 @@ fi
%{_datadir}/gtk-doc/html/ontology/
%changelog
* Tue Dec 03 2013 Debarshi Ray <rishi@fedoraproject.org> - 0.16.4-2
- Strengthen against sqlite failures in FTS functions (Red Hat #1026283)
* Sun Nov 24 2013 Kalev Lember <kalevlember@gmail.com> - 0.16.4-1
- Update to 0.16.4
- Re-enable upower support