diff --git a/addons/cert.py b/addons/cert.py index 6f4a22d7c..92bfe6835 100755 --- a/addons/cert.py +++ b/addons/cert.py @@ -82,6 +82,18 @@ def isStandardFunction(token): return False return True +# Is this a function call +def isFunctionCall(token, function_names, number_of_arguments=None): + if not token.isName: + return False + if token.str not in function_names: + return False + if (token.next is None) or token.next.str != '(' or token.next != token.astParent: + return False + if number_of_arguments is None: + return True + return len(cppcheckdata.getArguments(token)) == number_of_arguments + # Get function arguments def getArgumentsRecursive(tok, arguments): if tok is None: @@ -247,7 +259,19 @@ def str05(data): if parent.isAssignmentOp and parentOp1.valueType: if (parentOp1.valueType.type in ('char', 'wchar_t')) and parentOp1.valueType.pointer and not parentOp1.valueType.constness: reportError(parentOp1, 'style', 'Use pointers to const when referring to string literals', 'STR05-C') - + +# STR07-C +# Use the bounds-checking interfaces for string manipulation +def str07(data): + for token in data.tokenlist: + if not isFunctionCall(token, ('strcpy', 'strcat')): + continue + args = cppcheckdata.getArguments(token) + if len(args)!=2: + continue + if args[1].isString: + continue + reportError(token, 'style', 'Use the bounds-checking interfaces %s_s()' % (token.str), 'STR07-C') for arg in sys.argv[1:]: if arg == '-verify': @@ -275,6 +299,7 @@ for arg in sys.argv[1:]: exp46(cfg) int31(cfg, data.platform) str05(cfg) + str07(cfg) msc30(cfg) if VERIFY: diff --git a/addons/test/cert-test.c b/addons/test/cert-test.c index d57b107eb..73c409ed4 100644 --- a/addons/test/cert-test.c +++ b/addons/test/cert-test.c @@ -1,8 +1,5 @@ // To test: // ~/cppcheck/cppcheck --dump cert-test.c && python ../cert.py -verify cert-test.c.dump -#include -#include - struct S { short a; short b; @@ -70,3 +67,11 @@ void str05() wchar_t *str2 = L"hello"; //cert-STR05-C } +void str07(char *buf, const char *newBuf) +{ + const char *str="test"; + strcat(buf,"bla"); + strcat(buf, str); //cert-STR07-C + strcat(buf, newBuf); //cert-STR07-C + strcpy(str, newBuf); //cert-STR07-C +}