From b70e1df26c8b8bf6310771e1bdf7dbabb5dc608c Mon Sep 17 00:00:00 2001 From: Tim Blume Date: Thu, 31 Aug 2023 09:38:03 +0200 Subject: [PATCH] fix crash while checking misra_9 when initializing a union with {{0,0}} (#5250) This fixes a crash with following error: ``` Traceback (most recent call last): File "/usr/local/share/Cppcheck/addons/runaddon.py", line 8, in runpy.run_path(addon, run_name='__main__') File "", line 291, in run_path File "", line 98, in _run_module_code File "", line 88, in _run_code File "/usr/local/share/Cppcheck/addons/misra.py", line 4737, in main() File "/usr/local/share/Cppcheck/addons/misra.py", line 4679, in main checker.parseDump(item) File "/usr/local/share/Cppcheck/addons/misra.py", line 4335, in parseDump self.executeCheck(902, self.misra_9_2, cfg) File "/usr/local/share/Cppcheck/addons/misra.py", line 4246, in executeCheck check_function(*args) File "/usr/local/share/Cppcheck/addons/misra.py", line 2104, in misra_9_2 misra_9.misra_9_x(self, data, 902) File "/usr/local/share/Cppcheck/addons/misra_9.py", line 414, in misra_9_x parser.parseInitializer(ed, eq.astOperand2) File "/usr/local/share/Cppcheck/addons/misra_9.py", line 320, in parseInitializer child = self.root.getChildByValueElement(self.ed) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'getChildByValueElement' ``` A minimal example and testcase is added. The extra check for nextChild seems to fix it, however i did not read the whole codebase, so maybe this creates other issues. --------- Co-authored-by: Tim Blume --- addons/misra_9.py | 5 ++--- .../test/misra/crash_misra9_parseInitializer.c | 18 ++++++++++++++++++ addons/test/test-misra.py | 1 - 3 files changed, 20 insertions(+), 4 deletions(-) create mode 100644 addons/test/misra/crash_misra9_parseInitializer.c diff --git a/addons/misra_9.py b/addons/misra_9.py index f0f733719..89002f30d 100644 --- a/addons/misra_9.py +++ b/addons/misra_9.py @@ -293,7 +293,7 @@ class InitializerParser: # Fake dummy as nextChild (of current root) nextChild = dummyRoot - if self.token.astOperand1: + if nextChild and self.token.astOperand1: self.root = nextChild self.token = self.token.astOperand1 isFirstElement = True @@ -328,7 +328,7 @@ class InitializerParser: self.ed.parent.initializeChildren() else: - if self.ed.parent != self.root: + if self.root is not None and self.ed.parent != self.root: # Check if token is correct value type for self.root.children[?] child = self.root.getChildByValueElement(self.ed) if self.token.valueType: @@ -458,7 +458,6 @@ def misra_9_x(self, data, rule, rawTokens = None): # without it. if ed.valueType is None and not variable.isArray: continue - parser.parseInitializer(ed, eq.astOperand2) # print(rule, nameToken.str + '=', ed.getInitDump()) if rule == 902 and not ed.isMisra92Compliant(): diff --git a/addons/test/misra/crash_misra9_parseInitializer.c b/addons/test/misra/crash_misra9_parseInitializer.c new file mode 100644 index 000000000..8e3dcfd57 --- /dev/null +++ b/addons/test/misra/crash_misra9_parseInitializer.c @@ -0,0 +1,18 @@ +union { + struct { + uint8_t a; + uint8_t b; + } a; +} bar; + +struct foo { + uint8_t a; + union bar w; + uint8_t b; +}; + +struct foo asdf = { + 0, + {{0,0}}, + 1 +}; diff --git a/addons/test/test-misra.py b/addons/test/test-misra.py index ba1dbaae7..3701dc2f4 100644 --- a/addons/test/test-misra.py +++ b/addons/test/test-misra.py @@ -120,7 +120,6 @@ def test_rules_suppression(checker, capsys): assert found is None, 'Unexptected output:\n' + captured dump_remove(src) - def test_arguments_regression(): args_ok = ["-generate-table", "--rule-texts=./addons/test/assets/misra_rules_multiple_lines.txt",