Skip to content

Commit

Permalink
Add functionality to validate analyzer and checker options
Browse files Browse the repository at this point in the history
When specifying invalid checker and analyzer config,
the CodeChecker analyze command used to give a warning
but continued running.
This functionality throws an error and prevents the
analysis from running in this case.

Co-authored-by: Kristóf Umann <dkszelethus@gmail.com>
  • Loading branch information
2 people authored and Nora Zinaeddin committed Apr 11, 2024
1 parent 11dc7da commit 86e9191
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 40 deletions.
71 changes: 36 additions & 35 deletions analyzer/codechecker_analyzer/cmd/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
from codechecker_analyzer.analyzers import analyzer_types, clangsa
from codechecker_analyzer.arg import \
OrderedCheckersAction, OrderedConfigAction, existing_abspath, \
analyzer_config, checker_config
analyzer_config, checker_config, AnalyzerConfig, CheckerConfig

from codechecker_analyzer.buildlog import log_parser

from codechecker_common import arg, logger, cmd_config, review_status_handler
Expand Down Expand Up @@ -800,28 +801,27 @@ def is_analyzer_config_valid(analyzer_conf: List[AnalyzerConfig]) -> bool:
Ensure that the analyzer_config parameter is set to a valid value
by verifying if it belongs to the set of allowed values.
"""
analyzer = analyzer_conf.__getitem__(0).analyzer

if analyzer in analyzer_types.supported_analyzers:
analyzer_class = analyzer_types.supported_analyzers[analyzer]
else:
LOG.error(f"Invalid --analyzer-config parameter: {analyzer} is not "
f"a supported analyzer. The supported analyzers are "
f"{', '.join(a for a in analyzer_types.supported_analyzers)}"
f".")
return False

if not isinstance(analyzer_conf, list):
return False

analyzers = [analyzer[0] for analyzer in
analyzer_class.get_analyzer_config()]

# Make sure "[clang-tidy] Allow to override checker list #3203" works
if analyzer_class.ANALYZER_NAME == 'clang-tidy':
analyzers.append('take-config-from-directory')
supported_analyzers = analyzer_types.supported_analyzers
configured_analyzers = [cfg.analyzer for cfg in analyzer_conf]
for analyzer in configured_analyzers:
if analyzer not in supported_analyzers:
LOG.error(f"Invalid --analyzer-config parameter: {analyzer} is"
f" not a supported analyzer. The supported analyzers are"
f" {', '.join(a for a in supported_analyzers)}.")
return False

for cfg in analyzer_conf:
analyzer_class = supported_analyzers[cfg.analyzer]
analyzers = [analyzer[0] for analyzer in
analyzer_class.get_analyzer_config()]

# Make sure "[clang-tidy] Allow to override checker list #3203" works
if analyzer_class.ANALYZER_NAME == 'clang-tidy':
analyzers.append('take-config-from-directory')

if cfg.analyzer == analyzer_class.ANALYZER_NAME and \
cfg.option not in analyzers:
LOG.error(f"Invalid --analyzer-config parameter: "
Expand All @@ -830,32 +830,32 @@ def is_analyzer_config_valid(analyzer_conf: List[AnalyzerConfig]) -> bool:
f"--analyzer-config {analyzer_class.ANALYZER_NAME}' "
f"command to check available configs.")
return False
return True

return True


def is_checker_config_valid(checker_conf: List[CheckerConfig]) -> bool:
"""
Ensure that the checker_config parameter is set to a valid value
by verifying if it belongs to the set of allowed values.
"""
analyzer = checker_conf.__getitem__(0).analyzer

if analyzer in analyzer_types.supported_analyzers:
analyzer_class = analyzer_types.supported_analyzers[analyzer]
else:
LOG.error(f"Invalid --checker-config parameter: {analyzer} is not "
f"a supported analyzer. The supported analyzers are "
f"{', '.join(a for a in analyzer_types.supported_analyzers)}"
f".")
return False

if not isinstance(checker_conf, list):
return False

checkers = [checker[0] for checker in
analyzer_class.get_analyzer_checkers()]
supported_analyzers = analyzer_types.supported_analyzers
configured_analyzers = [cfg.analyzer for cfg in checker_conf]
for analyzer in configured_analyzers:
if analyzer not in supported_analyzers:
LOG.error(f"Invalid --checker-config parameter: {analyzer} is not "
f"a supported analyzer. The supported analyzers are"
f" {', '.join(a for a in supported_analyzers)}.")
return False

for cfg in checker_conf:
analyzer_class = supported_analyzers[cfg.analyzer]
checkers = [checker[0] for checker in
analyzer_class.get_analyzer_checkers()]

if cfg.analyzer == analyzer_class.ANALYZER_NAME and \
cfg.checker not in checkers:
LOG.error(
Expand All @@ -865,7 +865,8 @@ def is_checker_config_valid(checker_conf: List[CheckerConfig]) -> bool:
f"--checker-config' command to see available checkers."
)
return False
return True

return True


def get_affected_file_paths(
Expand Down Expand Up @@ -1007,8 +1008,8 @@ def main(args):

# Validate analyzer and checker config (if any)
config_validator = {
'analyzer_config': validate_analyzer_parameter,
'checker_config': validate_checker_parameter
'analyzer_config': is_analyzer_config_valid,
'checker_config': is_checker_config_valid
}
for conf, validate_func in config_validator.items():
if conf in args and not validate_func(getattr(args, conf)):
Expand Down
8 changes: 3 additions & 5 deletions analyzer/tests/unit/test_checker_handling.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
import is_compiler_warning
from codechecker_analyzer.arg import AnalyzerConfig, CheckerConfig
from codechecker_analyzer.cmd.analyze import \
validate_analyzer_parameter, validate_checker_parameter
is_analyzer_config_valid, is_checker_config_valid

from codechecker_analyzer import analyzer_context
from codechecker_analyzer.buildlog import log_parser
Expand Down Expand Up @@ -408,10 +408,8 @@ def test_analyze_wrong_parameters(self):
analyzer_cfg = [AnalyzerConfig('asd', '123', 'value')]
checker_cfg = [CheckerConfig('clangsa', 'asd', '123', 'value')]

analyzer_func = validate_analyzer_parameter(analyzer_cfg)
checker_func = validate_checker_parameter(checker_cfg)

[self.assertFalse(func) for func in [analyzer_func, checker_func]]
self.assertFalse(is_analyzer_config_valid(analyzer_cfg))
self.assertFalse(is_checker_config_valid(checker_cfg))

def test_enable_all_disable_warning(self):
"""
Expand Down

0 comments on commit 86e9191

Please sign in to comment.