allura-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From brond...@apache.org
Subject [16/38] git commit: [#4019] ticket:515 added escape for search query
Date Wed, 30 Apr 2014 18:15:48 GMT
[#4019] ticket:515 added escape for search query


Project: http://git-wip-us.apache.org/repos/asf/allura/repo
Commit: http://git-wip-us.apache.org/repos/asf/allura/commit/c063f30a
Tree: http://git-wip-us.apache.org/repos/asf/allura/tree/c063f30a
Diff: http://git-wip-us.apache.org/repos/asf/allura/diff/c063f30a

Branch: refs/heads/master
Commit: c063f30ad867b5a607c88fb513cad1b9ceab376a
Parents: 21e03c0
Author: Yaroslav Sokolovsky <yaroslav.sokolovsky@gmail.com>
Authored: Wed Jan 8 16:39:47 2014 +0200
Committer: Dave Brondsema <dbrondsema@slashdotmedia.com>
Committed: Wed Apr 30 15:55:11 2014 +0000

----------------------------------------------------------------------
 Allura/allura/lib/search.py                     |  3 +-
 Allura/allura/lib/solr.py                       | 37 ++++++++++++++++++++
 Allura/allura/model/artifact.py                 | 14 +++++++-
 Allura/allura/tests/unit/test_artifact.py       |  9 +++++
 Allura/allura/tests/unit/test_solr.py           |  7 +++-
 ForgeTracker/forgetracker/search.py             |  1 +
 .../forgetracker/tests/functional/test_root.py  |  1 -
 7 files changed, 68 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/Allura/allura/lib/search.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/search.py b/Allura/allura/lib/search.py
index 3b05bdc..b57859c 100644
--- a/Allura/allura/lib/search.py
+++ b/Allura/allura/lib/search.py
@@ -29,6 +29,7 @@ from pylons import request
 from pysolr import SolrError
 
 from allura.lib import helpers as h
+from allura.lib.solr import escape_solr_arg
 from allura.model import ArtifactReference
 from .markdown_extensions import ForgeExtension
 
@@ -96,7 +97,7 @@ def search_artifact(atype, q, history=False, rows=10, short_timeout=False,
filte
         'mount_point_s:%s' % c.app.config.options.mount_point ]
     for name, values in (filter or {}).iteritems():
         field_name = name + '_s'
-        fq.append(' OR '.join('%s:%s' % (field_name, v) for v in values))
+        fq.append(' OR '.join('%s:%s' % (field_name, escape_solr_arg(v)) for v in values))
     if not history:
         fq.append('is_history_b:False')
     return search(q, fq=fq, rows=rows, short_timeout=short_timeout, ignore_errors=False,
**kw)

http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/Allura/allura/lib/solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/lib/solr.py b/Allura/allura/lib/solr.py
index 23ae556..e2019eb 100644
--- a/Allura/allura/lib/solr.py
+++ b/Allura/allura/lib/solr.py
@@ -21,6 +21,43 @@ from tg import config
 from paste.deploy.converters import asbool
 import pysolr
 
+escape_rules = {'+': r'\+',
+               '-': r'\-',
+               '&': r'\&',
+               '|': r'\|',
+               '!': r'\!',
+               '(': r'\(',
+               ')': r'\)',
+               '{': r'\{',
+               '}': r'\}',
+               '[': r'\[',
+               ']': r'\]',
+               '^': r'\^',
+               '~': r'\~',
+               '*': r'\*',
+               '?': r'\?',
+               ':': r'\:',
+               '"': r'\"',
+               ';': r'\;'}
+
+
+def escaped_seq(term):
+    """ Yield the next string based on the
+        next character (either this char
+        or escaped version """
+    for char in term:
+        if char in escape_rules.keys():
+            yield escape_rules[char]
+        else:
+            yield char
+
+
+def escape_solr_arg(term):
+    """ Apply escaping to the passed in query terms
+        escaping special characters like : , etc"""
+    term = term.replace('\\', r'\\')   # escape \ first
+    return "".join([nextStr for nextStr in escaped_seq(term)])
+
 
 def make_solr_from_config(push_servers, query_server=None, **kwargs):
     """

http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/Allura/allura/model/artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/model/artifact.py b/Allura/allura/model/artifact.py
index b781f4e..5d28df3 100644
--- a/Allura/allura/model/artifact.py
+++ b/Allura/allura/model/artifact.py
@@ -31,8 +31,11 @@ from webhelpers import feedgenerator as FG
 
 from allura.lib import helpers as h
 from allura.lib import security
+
+from allura.lib.solr import escape_solr_arg
 from .session import main_orm_session
 from .session import project_orm_session
+
 from .session import artifact_orm_session
 from .index import ArtifactReference
 from .types import ACL, MarkdownCache
@@ -130,9 +133,18 @@ class Artifact(MappedClass):
     def translate_query(cls, q, fields):
         """Return a translated Solr query (``q``), where generic field
         identifiers are replaced by the 'strongly typed' versions defined in
-        ``fields``.
+        ``fields``. Escape arguments
 
         """
+        new_q = []
+        for part in q.split(' '):
+            if ':' in part:
+                field, val = part.split(':', 1)
+                new_q.append('%s:%s' % (field, escape_solr_arg(val)))
+            else:
+                new_q.append(escape_solr_arg(part))
+        q = ' '.join(new_q)
+
         for f in fields:
             if '_' in f:
                 base, typ = f.rsplit('_', 1)

http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/Allura/allura/tests/unit/test_artifact.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_artifact.py b/Allura/allura/tests/unit/test_artifact.py
index 6e470c0..9f1bfd3 100644
--- a/Allura/allura/tests/unit/test_artifact.py
+++ b/Allura/allura/tests/unit/test_artifact.py
@@ -27,3 +27,12 @@ class TestArtifact(unittest.TestCase):
         query = 'foo:1 AND bar:2 AND foo_bar_baz:3'
         q = M.Artifact.translate_query(query, fields)
         self.assertEqual(q, 'foo_s:1 AND bar_ws:2 AND foo_bar_baz:3')
+
+        query = '!status:wont-fix OR !status:closed'
+        q = M.Artifact.translate_query(query, fields)
+        self.assertEqual(q, '!status:wont\-fix OR !status:closed')
+
+        query = '!status:wont-fix OR !status:closed AND _milestone::'
+        fields = ['_milestone_s']
+        q = M.Artifact.translate_query(query, fields)
+        self.assertEqual(q, '!status:wont\-fix OR !status:closed AND _milestone_s:\:')

http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/Allura/allura/tests/unit/test_solr.py
----------------------------------------------------------------------
diff --git a/Allura/allura/tests/unit/test_solr.py b/Allura/allura/tests/unit/test_solr.py
index 02da952..a789ca7 100644
--- a/Allura/allura/tests/unit/test_solr.py
+++ b/Allura/allura/tests/unit/test_solr.py
@@ -24,7 +24,7 @@ from markupsafe import Markup
 from allura.lib import helpers as h
 from allura.tests import decorators as td
 from alluratest.controller import setup_basic_test
-from allura.lib.solr import Solr
+from allura.lib.solr import Solr, escape_solr_arg
 from allura.lib.search import solarize, search_app
 
 
@@ -203,3 +203,8 @@ class TestSearch_app(unittest.TestCase):
                 'text_match': Markup('less scary but still dangerous &amp;lt;script&amp;gt;alert(1)&amp;lt;/script&amp;gt;
blah <strong>bar</strong> foo foo'),
             }]
         ))
+
+    def test_escape_solr_arg(self):
+        text = 'milestone_s:: wont-fix'
+        escaped_text = escape_solr_arg(text)
+        assert_equal(escaped_text, 'milestone_s\:\: wont\-fix')

http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/ForgeTracker/forgetracker/search.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/search.py b/ForgeTracker/forgetracker/search.py
index a1f5243..223781a 100644
--- a/ForgeTracker/forgetracker/search.py
+++ b/ForgeTracker/forgetracker/search.py
@@ -48,6 +48,7 @@ def get_facets(solr_hit):
         return {}
     def reformat(field):
         name, val = field
+        # drop "_s"
         name = name[:-2]
         new_val = []
         for i in range(0, len(val), 2):

http://git-wip-us.apache.org/repos/asf/allura/blob/c063f30a/ForgeTracker/forgetracker/tests/functional/test_root.py
----------------------------------------------------------------------
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index 3efab34..1586309 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -1103,7 +1103,6 @@ class TestFunctionalController(TrackerTestController):
             'milestones-0.due_date': ''
         })
         ticket_view = self.app.get('/p/test/bugs/1/')
-        assert '1.0' not in ticket_view
         assert 'zzzé' in ticket_view
 
     def test_milestone_close(self):


Mime
View raw message