From 34a5841b019c8c38d55aad3981e3fb919d9ee60c Mon Sep 17 00:00:00 2001 From: Alex Kenion Date: Tue, 24 Oct 2023 11:35:34 -0400 Subject: [PATCH] Improved messaging around file inclusion/exclusion patterns --- wordfence/cli/malwarescan/definition.py | 8 ++++---- wordfence/cli/malwarescan/malwarescan.py | 16 ++++++++++++++-- wordfence/scanning/filtering.py | 13 +++++++++++-- 3 files changed, 29 insertions(+), 8 deletions(-) diff --git a/wordfence/cli/malwarescan/definition.py b/wordfence/cli/malwarescan/definition.py index 41b4dcd3..6c60246b 100644 --- a/wordfence/cli/malwarescan/definition.py +++ b/wordfence/cli/malwarescan/definition.py @@ -89,8 +89,8 @@ }, "include-files-pattern": { "short_name": "N", - "description": "PCRE regex allow pattern. Only matching filenames will" - " be scanned.", + "description": "Python regex allow pattern. Only matching filenames " + "will be scanned.", "context": "ALL", "argument_type": "OPTION_REPEATABLE", "default": None, @@ -100,8 +100,8 @@ }, "exclude-files-pattern": { "short_name": "X", - "description": "PCRE regex deny pattern. Matching filenames will not " - "be scanned.", + "description": "Python regex deny pattern. Matching filenames will " + "not be scanned.", "context": "ALL", "argument_type": "OPTION_REPEATABLE", "default": None, diff --git a/wordfence/cli/malwarescan/malwarescan.py b/wordfence/cli/malwarescan/malwarescan.py index 577db943..41f02da4 100644 --- a/wordfence/cli/malwarescan/malwarescan.py +++ b/wordfence/cli/malwarescan/malwarescan.py @@ -86,13 +86,25 @@ def _initialize_file_filter(self) -> filtering.FileFilter: if self.config.include_files_pattern is not None: has_include_overrides = True for pattern in self.config.include_files_pattern: - filter.add(filtering.filter_pattern(pattern)) + try: + filter.add(filtering.filter_pattern(pattern)) + except filtering.InvalidPatternException: + raise Exception( + 'File inclusion pattern must be a Python regex, ' + f'received: "{pattern}"' + ) if self.config.exclude_files is not None: for name in self.config.exclude_files: filter.add(filtering.filter_filename(name), False) if self.config.exclude_files_pattern is not None: for pattern in self.config.exclude_files_pattern: - filter.add(filtering.filter_pattern(pattern), False) + try: + filter.add(filtering.filter_pattern(pattern), False) + except filtering.InvalidPatternException: + raise Exception( + 'File exclusion pattern must be a Python regex, ' + f'received: "{pattern}"' + ) if not has_include_overrides: filter.add(filtering.filter_php) filter.add(filtering.filter_html) diff --git a/wordfence/scanning/filtering.py b/wordfence/scanning/filtering.py index dcf5d093..2c7b2ed1 100644 --- a/wordfence/scanning/filtering.py +++ b/wordfence/scanning/filtering.py @@ -98,6 +98,15 @@ def __call__(self, path: str) -> bool: return matches_regex(self.pattern, path) +class InvalidPatternException(Exception): + + def __init__(self, pattern: str): + self.pattern = pattern + + def filter_pattern(regex: str) -> Callable[[str], bool]: - pattern = re.compile(regex) - return Filter(pattern) + try: + pattern = re.compile(regex) + return Filter(pattern) + except re.error: + raise InvalidPatternException(regex)