[meld] filters: Break out forgiving regex compilation and add a test



commit c99a2dd74a6f942012bde08376bbcd53a6825f83
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Sun Oct 28 07:52:33 2018 +1000

    filters: Break out forgiving regex compilation and add a test

 meld/filters.py      | 28 +++++++++++++++-------------
 test/test_filters.py | 12 ++++++++++++
 2 files changed, 27 insertions(+), 13 deletions(-)
---
diff --git a/meld/filters.py b/meld/filters.py
index 0012bfa5..e0ea730e 100644
--- a/meld/filters.py
+++ b/meld/filters.py
@@ -13,10 +13,23 @@
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+import logging
 import re
 
 from . import misc
 
+log = logging.getLogger(__name__)
+
+
+def try_compile(regex, flags=0):
+    try:
+        compiled = re.compile(regex, flags)
+    except re.error:
+        log.warning(
+            'Error compiling regex {!r} with flags {!r}'.format(regex, flags))
+        compiled = None
+    return compiled
+
 
 class FilterEntry:
 
@@ -37,12 +50,7 @@ class FilterEntry:
             # TODO: Register a custom error handling function to replace
             # encoding errors with '.'?
             regex = regex.encode('utf8', 'replace')
-
-        try:
-            compiled = re.compile(regex, re.M)
-        except re.error:
-            compiled = None
-        return compiled
+        return try_compile(regex, re.M)
 
     @classmethod
     def _compile_shell_pattern(cls, pattern):
@@ -55,13 +63,7 @@ class FilterEntry:
             regex = "(%s)$" % "|".join(regexes)
         else:
             regex = misc.shell_to_regex(bits[0])
-
-        try:
-            compiled = re.compile(regex)
-        except re.error:
-            compiled = None
-
-        return compiled
+        return try_compile(regex)
 
     @classmethod
     def new_from_gsetting(cls, elements, filter_type):
diff --git a/test/test_filters.py b/test/test_filters.py
index 403c39b8..61acb310 100644
--- a/test/test_filters.py
+++ b/test/test_filters.py
@@ -26,3 +26,15 @@ def test_file_filters(patterns, filename, expected_match):
     # that's what we test here, even if it looks a bit weird.
     match = any(f.filter.match(filename) for f in filters)
     assert match == expected_match
+
+
+@pytest.mark.parametrize("pattern", [
+    r'*.foo*',  # Trailing wildcard
+    r'\xfoo',  # Invalid escape
+])
+def test_bad_regex_compilation(pattern):
+    from meld.filters import FilterEntry
+
+    f = FilterEntry.new_from_gsetting(
+        ("name", True, pattern), FilterEntry.REGEX)
+    assert f.filter is None


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]