Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Silbe <sascha-pgp@silbe.org>2013-08-12 15:31:07 (GMT)
committer Sascha Silbe <sascha-pgp@silbe.org>2013-11-16 20:12:40 (GMT)
commit75fb8e0f3d8717c60090e87274dc3c124a4ae873 (patch)
tree805247351b75f5cb837e86131886eb4ecb8c04af
parentd7f76bcbf19e465e4f1bcae17e89f39153fdff3e (diff)
check Xapian query for imbalanced parentheses
When merging the root query with a user-provided Xapian query, special care must be taken. Asymmetric parentheses inside the user-provided query can close outer parenthesis used for logically combining the two queries, while still resulting in a valid query overall. Explicitly check that the parenthesis are well-balanced inside the user-provided query before using it. This is a security fix, but as the search functionality isn't exposed in journal2webdav so far there's no impact for any user.
-rw-r--r--fsemulation.py23
1 files changed, 23 insertions, 0 deletions
diff --git a/fsemulation.py b/fsemulation.py
index 7b8c088..2a73310 100644
--- a/fsemulation.py
+++ b/fsemulation.py
@@ -25,6 +25,7 @@ import threading
import time
import dbus
+import xapian
import sugar.mime
@@ -479,6 +480,8 @@ class DataStore(object):
xapian_query = query.get('query', '')
query.update(self._root_query)
if ('query' in self._root_query) and xapian_query:
+ if not check_xapian_query(xapian_query):
+ raise ValueError('Invalid Xapian query: %r' % xapian_query)
query['query'] = '(%s) AND (%s)' % (self._root_query['query'],
xapian_query)
return query
@@ -1107,3 +1110,23 @@ class FSEmulation(object):
def safe_name(name):
return name.replace(u'/', u'_')
+
+
+def check_xapian_query(query):
+ """Return False if Xapian query is invalid
+
+ Return False if the given Xapian query contains incorrectly balanced
+ parentheses. Return True otherwise.
+ """
+ num_parens = 0
+ inside_quote = False
+ for c in query:
+ if c == '"':
+ inside_quote = not inside_quote
+ elif c == '(' and not inside_quote:
+ num_parens +=1
+ elif c == ')' and not inside_quote:
+ if num_parens < 1:
+ return False
+ num_parens -= 1
+ return num_parens == 0