Fixed an issue parsing quoted search phrases that contain special characters.

master
Pacman Ghost 2 years ago
parent 49c608186c
commit a0410f5960
  1. 10
      asl_articles/search.py
  2. 5
      asl_articles/tests/test_search.py

@ -393,7 +393,15 @@ def _make_fts_query_string( query_string, search_aliases ): #pylint: disable=too
return "({})".format( " OR ".join( quote(v) for v in val ) )
def quote( val ):
"""Quote a string, if necessary."""
if not val.startswith( '"' ) or not val.endswith( '"' ):
# NOTE: We used to check for fully-quoted values i.e.
# not ( startswith " and endswith " )
# which becomes:
# not startswith " or not endswith "
# but this doesn't work with quoted multi-word phrases that contain special characters
# e.g. "J. R. Tracy", since we see that the first phrase ("J.) is not fully-quoted,
# and so we wrap it in quotes :-/ Instead, if we see a quote at either end of the word,
# we treat it as part of a quoted phrase (either single- or multi-word), and use it verbatim.
if not val.startswith( '"' ) and not val.endswith( '"' ):
if any( ch in val for ch in _SQLITE_FTS_SPECIAL_CHARS+" " ):
val = '"{}"'.format( val )
return val.replace( "'", "''" )

@ -583,6 +583,11 @@ def test_make_fts_query_string():
# 'foo AND "xyz 123" AND bar'
# )
# test some quoted phrases that wrap special characters
do_test( 'Mr. Jones', '"Mr." AND Jones' )
do_test( '"Mr. Jones"', '"Mr. Jones"' )
do_test( 'foo "Mr. Jones" bar', 'foo AND "Mr. Jones" AND bar' )
# test some incorrectly quoted phrases
do_test( '"', '' )
do_test( ' " " " ', '' )

Loading…
Cancel
Save