From 0662c94d835e6c62c4f193538ae1b61a3e0da0ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sun, 22 Aug 2021 07:38:07 +0200 Subject: [PATCH] misra: implement rule 21.20 --- addons/misra.py | 50 +++++++++++++++++++++++++++++++++- addons/test/misra/misra-test.c | 6 ++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/addons/misra.py b/addons/misra.py index db13db1f4..1c2505fc8 100755 --- a/addons/misra.py +++ b/addons/misra.py @@ -3567,6 +3567,53 @@ class MisraChecker: if lhs and lhs.variable and simpleMatch(lhs.variable.typeStartToken, 'lconv'): self.reportError(token, 21, 19) + def misra_21_20(self, cfg): + assigned = {} + invalid = [] + for token in cfg.tokenlist: + # No sophisticated data flow analysis, bail out if control flow is "interrupted" + if token.str in ('{', '}', 'break', 'continue', 'return'): + assigned = {} + invalid = [] + continue + + # When pointer is assigned, remove it from 'assigned' and 'invalid' + if token.varId and token.varId > 0 and simpleMatch(token.next, '='): + for name in assigned.keys(): + while token.varId in assigned[name]: + assigned[name].remove(token.varId) + while token.varId in invalid: + invalid.remove(token.varId) + continue + + # Calling dangerous function + if token.str in ('asctime', 'ctime', 'gmtime', 'localtime', 'localeconv', 'getenv', 'setlocale', 'strerror'): + name, args = cppcheckdata.get_function_call_name_args(token) + if name and name == token.str: + # make assigned pointers invalid + for varId in assigned.get(name, ()): + if varId not in invalid: + invalid.append(varId) + + # assign pointer + parent = token.next + while parent.astParent and (parent.astParent.str == '+' or isCast(parent.astParent)): + parent = parent.astParent + if simpleMatch(parent.astParent, '='): + eq = parent.astParent + vartok = eq.previous + if vartok and vartok.varId and vartok.varId > 0: + if name not in assigned: + assigned[name] = [vartok.varId] + elif vartok.varId not in assigned[name]: + assigned[name].append(vartok.varId) + continue + + # taking value of invalid pointer.. + if token.astParent and token.varId: + if token.varId in invalid: + self.reportError(token, 21, 20) + def misra_21_21(self, cfg): for token in cfg.tokenlist: if token.str == 'system': @@ -4214,7 +4261,8 @@ class MisraChecker: self.executeCheck(2114, self.misra_21_14, cfg) self.executeCheck(2115, self.misra_21_15, cfg) self.executeCheck(2116, self.misra_21_16, cfg) - self.executeCheck(2121, self.misra_21_19, cfg) + self.executeCheck(2119, self.misra_21_19, cfg) + self.executeCheck(2120, self.misra_21_20, cfg) self.executeCheck(2121, self.misra_21_21, cfg) # 22.4 is already covered by Cppcheck writeReadOnlyFile self.executeCheck(2205, self.misra_22_5, cfg) diff --git a/addons/test/misra/misra-test.c b/addons/test/misra/misra-test.c index e06788a66..0bed3382b 100644 --- a/addons/test/misra/misra-test.c +++ b/addons/test/misra/misra-test.c @@ -1809,6 +1809,12 @@ static void misra_21_19(void) { conv->decimal_point = "^"; // 21.19 } +static void misra_21_20(void) { + const char *res1 = setlocale ( LC_ALL, 0 ); + (void) setlocale ( LC_MONETARY, "French" ); + if (res1) {} // 21.20 14.4 +} + static void misra_21_21(void) { (void)system("ls"); // 21.21 }