From 99c7d536cc2c739a13c75bd94e7e0552734472a8 Mon Sep 17 00:00:00 2001 From: Satoru SATOH Date: Mon, 3 May 2021 19:13:17 +0900 Subject: [PATCH] Validate rules objects loaded from plugin rule modules (#1542) Validate rule objects loaded from plugin rule modules before those use to avoid issues because of broken rule modules. Signed-Off-By: Satoru SATOH --- src/ansiblelint/rules/__init__.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/ansiblelint/rules/__init__.py b/src/ansiblelint/rules/__init__.py index 3f5b1c178a..d5ce489087 100644 --- a/src/ansiblelint/rules/__init__.py +++ b/src/ansiblelint/rules/__init__.py @@ -176,10 +176,13 @@ def matchyaml(self, file: Lintable) -> List[MatchError]: return matches -def load_plugins(directory: str) -> List[AnsibleLintRule]: - """Return a list of rule classes.""" - result = [] +def is_valid_rule(rule: AnsibleLintRule) -> bool: + """Check if given rule is valid or not.""" + return isinstance(rule, AnsibleLintRule) and bool(rule.id) and bool(rule.shortdesc) + +def load_plugins(directory: str) -> Iterator[AnsibleLintRule]: + """Yield a rule class.""" for pluginfile in glob.glob(os.path.join(directory, '[A-Za-z]*.py')): pluginname = os.path.basename(pluginfile.replace('.py', '')) @@ -188,9 +191,13 @@ def load_plugins(directory: str) -> List[AnsibleLintRule]: if spec and isinstance(spec.loader, Loader): module = importlib.util.module_from_spec(spec) spec.loader.exec_module(module) - obj = getattr(module, pluginname)() - result.append(obj) - return result + try: + rule = getattr(module, pluginname)() + if is_valid_rule(rule): + yield rule + + except (TypeError, ValueError, AttributeError): + _logger.warning("Skipped invalid rule from %s", pluginname) class RulesCollection: