Fix #12163 (misra.py: crashes when ctu-info line does not have certain attributes) (#5638)

This commit is contained in:
Daniel Marjamäki 2023-11-08 15:23:50 +01:00 committed by GitHub
parent 1fa785d81d
commit 617b7a39cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 38 additions and 18 deletions

View File

@ -4618,6 +4618,19 @@ class MisraChecker:
self.executeCheck(2209, self.misra_22_9, cfg) self.executeCheck(2209, self.misra_22_9, cfg)
self.executeCheck(2210, self.misra_22_10, cfg) self.executeCheck(2210, self.misra_22_10, cfg)
def read_ctu_info_line(self, line):
if not line.startswith('{'):
return None
try:
ctu_info = json.loads(line)
except json.decoder.JSONDecodeError:
return None
if 'summary' not in ctu_info:
return None
if 'data' not in ctu_info:
return None
return ctu_info
def analyse_ctu_info(self, ctu_info_files): def analyse_ctu_info(self, ctu_info_files):
all_typedef_info = {} all_typedef_info = {}
all_tagname_info = {} all_tagname_info = {}
@ -4639,12 +4652,11 @@ class MisraChecker:
try: try:
for filename in ctu_info_files: for filename in ctu_info_files:
for line in open(filename, 'rt'): for line in open(filename, 'rt'):
if not line.startswith('{'): s = self.read_ctu_info_line(line)
if s is None:
continue continue
summary_type = s.get('summary', '')
s = json.loads(line) summary_data = s.get('data', None)
summary_type = s['summary']
summary_data = s['data']
if summary_type == 'MisraTypedefInfo': if summary_type == 'MisraTypedefInfo':
for new_typedef_info in summary_data: for new_typedef_info in summary_data:

View File

@ -7,9 +7,11 @@
# Command in cppcheck directory: # Command in cppcheck directory:
# PYTHONPATH=./addons python3 -m pytest addons/test/test-misra.py # PYTHONPATH=./addons python3 -m pytest addons/test/test-misra.py
import os
import pytest import pytest
import re import re
import sys import sys
import tempfile
from .util import dump_create, dump_remove, convert_json_output from .util import dump_create, dump_remove, convert_json_output
@ -25,16 +27,6 @@ def remove_misra_config(s:str):
return ret return ret
def setup_module(module):
for f in TEST_SOURCE_FILES:
dump_create(f)
def teardown_module(module):
for f in TEST_SOURCE_FILES:
dump_remove(f)
@pytest.fixture(scope="function") @pytest.fixture(scope="function")
def checker(): def checker():
from addons.misra import MisraChecker, MisraSettings, get_args_parser from addons.misra import MisraChecker, MisraSettings, get_args_parser
@ -44,6 +36,15 @@ def checker():
return MisraChecker(settings) return MisraChecker(settings)
@pytest.fixture
def test_files():
for f in TEST_SOURCE_FILES:
dump_create(f)
yield
for f in TEST_SOURCE_FILES:
dump_remove(f)
def test_loadRuleTexts_structure(checker): def test_loadRuleTexts_structure(checker):
checker.loadRuleTexts("./addons/test/misra/misra_rules_structure.txt") checker.loadRuleTexts("./addons/test/misra/misra_rules_structure.txt")
assert(checker.ruleTexts.get(101, None) is None) assert(checker.ruleTexts.get(101, None) is None)
@ -83,7 +84,7 @@ def test_rules_misra_severity(checker):
assert(checker.ruleTexts[2104].misra_severity == '') assert(checker.ruleTexts[2104].misra_severity == '')
def test_json_out(checker, capsys): def test_json_out(checker, capsys, test_files):
sys.argv.append("--cli") sys.argv.append("--cli")
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.parseDump("./addons/test/misra/misra-test.c.dump") checker.parseDump("./addons/test/misra/misra-test.c.dump")
@ -96,7 +97,7 @@ def test_json_out(checker, capsys):
assert("Advisory" in json_output['c2012-20.1'][0]['extra']) assert("Advisory" in json_output['c2012-20.1'][0]['extra'])
def test_rules_cppcheck_severity(checker, capsys): def test_rules_cppcheck_severity(checker, capsys, test_files):
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.parseDump("./addons/test/misra/misra-test.c.dump") checker.parseDump("./addons/test/misra/misra-test.c.dump")
captured = capsys.readouterr().err captured = capsys.readouterr().err
@ -104,7 +105,7 @@ def test_rules_cppcheck_severity(checker, capsys):
assert("(warning)" not in captured) assert("(warning)" not in captured)
assert("(style)" in captured) assert("(style)" in captured)
def test_rules_cppcheck_severity_custom(checker, capsys): def test_rules_cppcheck_severity_custom(checker, capsys, test_files):
checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt") checker.loadRuleTexts("./addons/test/misra/misra_rules_dummy.txt")
checker.setSeverity("custom-severity") checker.setSeverity("custom-severity")
checker.parseDump("./addons/test/misra/misra-test.c.dump") checker.parseDump("./addons/test/misra/misra-test.c.dump")
@ -167,3 +168,10 @@ def test_arguments_regression():
sys.argv.remove(arg) sys.argv.remove(arg)
finally: finally:
sys.argv = sys_argv_old sys.argv = sys_argv_old
def test_read_ctu_info_line(checker):
assert checker.read_ctu_info_line('{') is None
assert checker.read_ctu_info_line('{"summary":"123"}') is None
assert checker.read_ctu_info_line('{"data":123}') is None
assert checker.read_ctu_info_line('{"summary":"123","data":123}') is not None