diff options
author | Patrick Totzke <patricktotzke@gmail.com> | 2017-12-02 17:37:53 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-12-02 17:37:53 +0000 |
commit | 94d17f5712bf48801783abfa7ce17fde2b011dfa (patch) | |
tree | 6bb85f164bdbd9019b04c04c866c0829020403f4 | |
parent | 5c2a735f9bb17e065bc3c83831dc62c0a2fb2d60 (diff) | |
parent | f89555064a810ad7fcb3cbe079639ac3f83ff07c (diff) |
Merge pull request #1180 from three-comrades/tag_complete
Tag completion: escape RE characters in search pattern.
-rw-r--r-- | alot/addressbook/__init__.py | 2 | ||||
-rw-r--r-- | alot/completion.py | 2 | ||||
-rw-r--r-- | alot/settings/manager.py | 2 | ||||
-rw-r--r-- | tests/addressbook/init_test.py | 9 | ||||
-rw-r--r-- | tests/completion_test.py | 9 | ||||
-rw-r--r-- | tests/settings/manager_test.py | 12 |
6 files changed, 33 insertions, 3 deletions
diff --git a/alot/addressbook/__init__.py b/alot/addressbook/__init__.py index 17800b33..28c4ecc7 100644 --- a/alot/addressbook/__init__.py +++ b/alot/addressbook/__init__.py @@ -34,7 +34,7 @@ class AddressBook(object): def lookup(self, query=''): """looks up all contacts where name or address match query""" res = [] - query = re.compile('.*%s.*' % query, self.reflags) + query = re.compile('.*%s.*' % re.escape(query), self.reflags) for name, email in self.get_contacts(): if query.match(name) or query.match(email): res.append((name, email)) diff --git a/alot/completion.py b/alot/completion.py index 78b22d5b..48824909 100644 --- a/alot/completion.py +++ b/alot/completion.py @@ -75,7 +75,7 @@ class StringlistCompleter(Completer): re_prefix = '.*' if self.match_anywhere else '' def match(s, m): - r = re_prefix + m + '.*' + r = '{}{}.*'.format(re_prefix, re.escape(m)) return re.match(r, s, flags=self.flags) is not None return [(a, len(a)) for a in self.resultlist if match(a, pref)] diff --git a/alot/settings/manager.py b/alot/settings/manager.py index c71fba42..98d534fb 100644 --- a/alot/settings/manager.py +++ b/alot/settings/manager.py @@ -320,7 +320,7 @@ class SettingsManager(object): fallback_focus = resolve_att(onebelow_focus, default_focus) for sec in cfg['tags'].sections: - if re.match('^' + sec + '$', tag): + if re.match('^{}$'.format(re.escape(sec)), tag): normal = resolve_att(colourpick(cfg['tags'][sec]['normal']), fallback_normal) focus = resolve_att(colourpick(cfg['tags'][sec]['focus']), diff --git a/tests/addressbook/init_test.py b/tests/addressbook/init_test.py index a7f3f9b5..7f642933 100644 --- a/tests/addressbook/init_test.py +++ b/tests/addressbook/init_test.py @@ -65,3 +65,12 @@ class TestAddressBook(unittest.TestCase): actual = abook.lookup('Own') expected = [contacts[1]] self.assertListEqual(actual, expected) + + def test_lookup_can_handle_special_regex_chars(self): + contacts = [('name [work]', 'email@example.com'), + ('My Own Name', 'other@example.com'), + ('someone', 'someone@example.com')] + abook = _AddressBook(contacts) + actual = abook.lookup('[wor') + expected = [contacts[0]] + self.assertListEqual(actual, expected) diff --git a/tests/completion_test.py b/tests/completion_test.py index 855df03f..5b335779 100644 --- a/tests/completion_test.py +++ b/tests/completion_test.py @@ -87,3 +87,12 @@ class AbooksCompleterTest(unittest.TestCase): expected = [(r""""all 'fanzy' \"stuff\" at, once" <all@example.com>""", 50)] self._assert_only_one_list_entry(actual, expected) + + +class StringlistCompleterTest(unittest.TestCase): + def test_dont_choke_on_special_regex_characters(self): + tags = ['[match]', 'nomatch'] + completer = completion.StringlistCompleter(tags) + actual = completer.complete('[', 1) + expected = [(tags[0], len(tags[0]))] + self.assertListEqual(actual, expected) diff --git a/tests/settings/manager_test.py b/tests/settings/manager_test.py index a09dbf15..975bcb0e 100644 --- a/tests/settings/manager_test.py +++ b/tests/settings/manager_test.py @@ -94,6 +94,18 @@ class TestSettingsManager(unittest.TestCase): setting = manager.get_notmuch_setting('foo', 'bar') self.assertIsNone(setting) + def test_dont_choke_on_regex_special_chars_in_tagstring(self): + tag = 'to**do' + with tempfile.NamedTemporaryFile(delete=False) as f: + f.write(textwrap.dedent("""\ + [tags] + [[{tag}]] + normal = '','', 'white','light red', 'white','#d66' + """.format(tag=tag))) + self.addCleanup(os.unlink, f.name) + manager = SettingsManager(alot_rc=f.name) + manager.get_tagstring_representation(tag) + class TestSettingsManagerGetAccountByAddress(utilities.TestCaseClassCleanup): """Test the get_account_by_address helper.""" |