From f5a420af32a5bf03ffdddd35ab1155547d8fbee9 Mon Sep 17 00:00:00 2001 From: Nora Zinaeddin Date: Tue, 29 Oct 2024 16:29:04 +0100 Subject: [PATCH] Handle ambigous profile/group parameters Introduce the -e group: option, to improve handling of ambigous parameters (such as "security" etc.) --- .../analyzers/config_handler.py | 37 +++++++++++++------ analyzer/codechecker_analyzer/checkers.py | 3 +- analyzer/tests/unit/test_checker_handling.py | 33 +++++++++-------- 3 files changed, 46 insertions(+), 27 deletions(-) diff --git a/analyzer/codechecker_analyzer/analyzers/config_handler.py b/analyzer/codechecker_analyzer/analyzers/config_handler.py index bfc8be40fa..04c4835610 100644 --- a/analyzer/codechecker_analyzer/analyzers/config_handler.py +++ b/analyzer/codechecker_analyzer/analyzers/config_handler.py @@ -12,8 +12,10 @@ from abc import ABCMeta from enum import Enum +from string import Template import collections import platform +import sys import re from codechecker_analyzer import analyzer_context @@ -210,23 +212,36 @@ def initialize_checkers(self, profiles = checker_labels.get_description('profile') guidelines = checker_labels.occurring_values('guideline') + templ = Template("The ${entity} name '${identifier}' conflicts with a " + "checker(-group) name. Please use -e ${entity}: to " + "select checkers of a ${entity} or use -e group: " + "to select checkers which have a name " + "starting with '${identifier}'.") + for identifier, enabled in cmdline_enable: - if ':' in identifier: + if "group:" in identifier: + identifier = identifier.replace("group:", "") + self.set_checker_enabled(identifier, enabled) + elif ':' in identifier: for checker in checker_labels.checkers_by_labels([identifier]): self.set_checker_enabled(checker, enabled) elif identifier in profiles: if identifier in reserved_names: - LOG.warning("Profile name '%s' conflicts with a " - "checker(-group) name.", identifier) - for checker in checker_labels.checkers_by_labels( - [f'profile:{identifier}']): - self.set_checker_enabled(checker, enabled) + LOG.error(templ.substitute(entity="profile", + identifier=identifier)) + sys.exit(1) + else: + for checker in checker_labels.checkers_by_labels( + [f'profile:{identifier}']): + self.set_checker_enabled(checker, enabled) elif identifier in guidelines: if identifier in reserved_names: - LOG.warning("Guideline name '%s' conflicts with a " - "checker(-group) name.", identifier) - for checker in checker_labels.checkers_by_labels( - [f'guideline:{identifier}']): - self.set_checker_enabled(checker, enabled) + LOG.error(templ.substitute(entity="guideline", + identifier=identifier)) + sys.exit(1) + else: + for checker in checker_labels.checkers_by_labels( + [f'guideline:{identifier}']): + self.set_checker_enabled(checker, enabled) else: self.set_checker_enabled(identifier, enabled) diff --git a/analyzer/codechecker_analyzer/checkers.py b/analyzer/codechecker_analyzer/checkers.py index 1e9b6f7461..65bc57b031 100644 --- a/analyzer/codechecker_analyzer/checkers.py +++ b/analyzer/codechecker_analyzer/checkers.py @@ -23,7 +23,8 @@ def available(ordered_checkers, available_checkers): if checker_name.startswith('profile:') or \ checker_name.startswith('guideline:') or \ checker_name.startswith('severity:') or \ - checker_name.startswith('sei-cert:'): + checker_name.startswith('sei-cert:') or \ + checker_name.startswith('group:'): continue name_match = False diff --git a/analyzer/tests/unit/test_checker_handling.py b/analyzer/tests/unit/test_checker_handling.py index 7c5dd81db4..4aa96e5c6b 100644 --- a/analyzer/tests/unit/test_checker_handling.py +++ b/analyzer/tests/unit/test_checker_handling.py @@ -154,6 +154,10 @@ def f(checks, checkers): 'alpha.security.ArrayBound', 'alpha.security.MallocOverflow'] + sensitive_profile_alpha = [ + 'alpha.core.BoolAssignment', + 'alpha.core.TestAfterDivZero'] + # "default" profile. default_profile = [ 'security.FloatLoopCounter', @@ -199,7 +203,7 @@ def f(checks, checkers): # Enable alpha checkers explicitly. cfg_handler = ClangSA.construct_config_handler(args) - cfg_handler.initialize_checkers(checkers, [('alpha', True)]) + cfg_handler.initialize_checkers(checkers, [('group:alpha', True)]) self.assertTrue(all_with_status(CheckerState.ENABLED) (cfg_handler.checks(), security_profile_alpha)) self.assertTrue(all_with_status(CheckerState.ENABLED) @@ -216,10 +220,17 @@ def f(checks, checkers): # Enable "security" profile checkers without "profile:" prefix. cfg_handler = ClangSA.construct_config_handler(args) - cfg_handler.initialize_checkers(checkers, - [('security', True)]) + with self.assertRaises(SystemExit) as e: + cfg_handler.initialize_checkers(checkers, [('security', True)]) + self.assertEqual(e.exception.code, 1) + + # Enable "sensitive" profile checkers without "profile:" prefix. + cfg_handler = ClangSA.construct_config_handler(args) + cfg_handler.initialize_checkers(checkers, [('sensitive', True)]) + print(cfg_handler.checks()) + print(sensitive_profile_alpha) self.assertTrue(all_with_status(CheckerState.ENABLED) - (cfg_handler.checks(), security_profile_alpha)) + (cfg_handler.checks(), sensitive_profile_alpha)) self.assertTrue(all_with_status(CheckerState.ENABLED) (cfg_handler.checks(), default_profile)) @@ -232,10 +243,9 @@ def f(checks, checkers): # Enable "sei-cert" guideline checkers. cfg_handler = ClangSA.construct_config_handler(args) - cfg_handler.initialize_checkers(checkers, - [('sei-cert', True)]) - self.assertTrue(all_with_status(CheckerState.ENABLED) - (cfg_handler.checks(), cert_guideline)) + with self.assertRaises(SystemExit) as e: + cfg_handler.initialize_checkers(checkers, [('sei-cert', True)]) + self.assertEqual(e.exception.code, 1) # Disable "sei-cert" guideline checkers. cfg_handler = ClangSA.construct_config_handler(args) @@ -244,13 +254,6 @@ def f(checks, checkers): self.assertTrue(all_with_status(CheckerState.DISABLED) (cfg_handler.checks(), cert_guideline)) - # Disable "sei-cert" guideline checkers. - cfg_handler = ClangSA.construct_config_handler(args) - cfg_handler.initialize_checkers(checkers, - [('sei-cert', False)]) - self.assertTrue(all_with_status(CheckerState.DISABLED) - (cfg_handler.checks(), cert_guideline)) - cfg_handler = ClangSA.construct_config_handler(args) cfg_handler.initialize_checkers(checkers, [('default', False),