From 9b0409ea8829a78e04289517445d04604989b875 Mon Sep 17 00:00:00 2001 From: Charles Haley Date: Thu, 28 Nov 2013 12:46:10 +0100 Subject: [PATCH] Fix #1255671: escaped parenthesis do not work in any search expression, and match_books does not escape parenthesis. --- src/calibre/gui2/dialogs/match_books.py | 4 +++- src/calibre/utils/search_query_parser.py | 11 +++++++---- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/dialogs/match_books.py b/src/calibre/gui2/dialogs/match_books.py index 6ac7aa533c..72abab9c07 100644 --- a/src/calibre/gui2/dialogs/match_books.py +++ b/src/calibre/gui2/dialogs/match_books.py @@ -107,7 +107,9 @@ class MatchBooks(QDialog, Ui_MatchBooks): self.buttonBox.rejected.connect(self.reject) self.ignore_next_key = False - self.search_text.setText(self.device_db[self.current_device_book_id].title) + search_text= self.device_db[self.current_device_book_id].title + search_text = search_text.replace('(', '\\(').replace(')', '\\)') + self.search_text.setText(search_text) def return_pressed(self): self.ignore_next_key = True diff --git a/src/calibre/utils/search_query_parser.py b/src/calibre/utils/search_query_parser.py index 12ac9b3931..d3950577d2 100644 --- a/src/calibre/utils/search_query_parser.py +++ b/src/calibre/utils/search_query_parser.py @@ -177,14 +177,17 @@ class Parser(object): def parse(self, expr, locations): self.locations = locations - # Strip out escaped backslashes and escaped quotes so that the + # Strip out escaped backslashes, quotes and parens so that the # lex scanner doesn't get confused. We put them back later. expr = expr.replace(u'\\\\', u'\x01').replace(u'\\"', u'\x02') + expr = expr.replace(u'\\(', u'\x03').replace(u'\\)', u'\x04') self.tokens = self.lex_scanner.scan(expr)[0] for (i,tok) in enumerate(self.tokens): tt, tv = tok if tt == self.WORD or tt == self.QUOTED_WORD: - self.tokens[i] = (tt, tv.replace(u'\x01', u'\\').replace(u'\x02', u'"')) + self.tokens[i] = (tt, + tv.replace(u'\x01', u'\\').replace(u'\x02', u'"'). + replace(u'\x03', u'(').replace(u'\x04', u')')) self.current_token = 0 prog = self.or_expression() @@ -219,10 +222,10 @@ class Parser(object): return self.location_expression() def location_expression(self): - if self.token() == '(': + if self.token_type() == self.OPCODE and self.token() == '(': self.advance() res = self.or_expression() - if self.token(advance=True) != ')': + if self.token_type() != self.OPCODE or self.token(advance=True) != ')': raise ParseException(_('missing )')) return res if self.token_type() not in (self.WORD, self.QUOTED_WORD):