From 98070ce97fe47f395e2524b40a01e65c954bc97f Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sat, 9 Jan 2016 14:50:49 +0530 Subject: [PATCH] Tag Mapper: Do not allow the user to create rules with invalid regular expressions --- src/calibre/ebooks/metadata/tag_mapper.py | 7 +++++-- src/calibre/gui2/tag_mapper.py | 12 ++++++++++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/calibre/ebooks/metadata/tag_mapper.py b/src/calibre/ebooks/metadata/tag_mapper.py index 5b92c8468f..e8a2d54c3d 100644 --- a/src/calibre/ebooks/metadata/tag_mapper.py +++ b/src/calibre/ebooks/metadata/tag_mapper.py @@ -10,6 +10,9 @@ from collections import deque REGEX_FLAGS = regex.VERSION1 | regex.WORD | regex.FULLCASE | regex.IGNORECASE | regex.UNICODE +def compile_pat(pat): + return regex.compile(pat, flags=REGEX_FLAGS) + def matcher(rule): mt = rule['match_type'] if mt == 'one_of': @@ -21,11 +24,11 @@ def matcher(rule): return lambda x: x not in tags if mt == 'matches': - pat = regex.compile(rule['query'], flags=REGEX_FLAGS) + pat = compile_pat(rule['query']) return lambda x: pat.match(x) is not None if mt == 'not_matches': - pat = regex.compile(rule['query'], flags=REGEX_FLAGS) + pat = compile_pat(rule['query']) return lambda x: pat.match(x) is None return lambda x: False diff --git a/src/calibre/gui2/tag_mapper.py b/src/calibre/gui2/tag_mapper.py index 6de73f1fd9..6bf5cf4943 100644 --- a/src/calibre/gui2/tag_mapper.py +++ b/src/calibre/gui2/tag_mapper.py @@ -14,7 +14,7 @@ from PyQt5.Qt import ( QStaticText, Qt, QStyle, QToolButton, QInputDialog, QMenu ) -from calibre.ebooks.metadata.tag_mapper import map_tags +from calibre.ebooks.metadata.tag_mapper import map_tags, compile_pat from calibre.gui2 import error_dialog, elided_text, Application, question_dialog from calibre.gui2.widgets2 import Dialog from calibre.utils.config import JSONConfig @@ -60,6 +60,7 @@ class RuleEdit(QWidget): h.addWidget(q) for action, text in self.MATCH_TYPE_MAP.iteritems(): q.addItem(text, action) + q.currentIndexChanged.connect(self.update_state) self.la2 = la = QLabel(':\xa0') h.addWidget(la) self.query = q = QLineEdit(self) @@ -83,7 +84,7 @@ class RuleEdit(QWidget): replace = self.action.currentData() == 'replace' self.la3.setVisible(replace), self.replace.setVisible(replace) tt = _('A comma separated list of tags') - if 'pattern' in self.match_type.currentData(): + if 'matches' in self.match_type.currentData(): tt = _('A regular expression') self.query.setToolTip(tt) @@ -114,6 +115,13 @@ class RuleEdit(QWidget): error_dialog(self, _('Query required'), _( 'You must provide a value for the tag to match'), show=True) return False + if 'matches' in rule['match_type']: + try: + compile_pat(rule['query']) + except Exception: + error_dialog(self, _('Query invalid'), _( + '%s is not a valid regular expression') % rule['query'], show=True) + return False return True class RuleEditDialog(Dialog):