cert.py: Added testcases for EXP42 and fixed the code a little

This commit is contained in:
Daniel Marjamäki 2018-01-23 17:18:47 +01:00
parent d46cd46d0f
commit 8eae9cdd60
2 changed files with 52 additions and 28 deletions

View File

@ -30,28 +30,29 @@ def simpleMatch(token, pattern):
token = token.next
return True
def isUnpackedStruct(var):
decl = var.typeStartToken
while decl and decl.isName:
if decl.str == 'struct':
structScope = decl.next.typeScope
if structScope:
linenr = int(structScope.classStart.linenr)
for line in open(structScope.classStart.file):
linenr -= 1
if linenr == 0:
return True
if re.match(r'#pragma\s+pack\s*\(', line):
return False
break
decl = decl.next
return False
def isUnpackedStruct(token):
if token.valueType is None:
return False
if token.valueType.typeScope is None:
return False;
if token.valueType.typeScope.type != "Struct":
return False
startToken = token.valueType.typeScope.classStart
linenr = int(startToken.linenr)
for line in open(startToken.file):
linenr -= 1
if linenr == 0:
return True
if linenr < 3 and re.match(r'#pragma\s+pack\s*\(', line):
return False
return True
def isLocalUnpackedStruct(arg):
if arg and arg.str == '&' and not arg.astOperand2:
arg = arg.astOperand1
return arg and arg.variable and (arg.variable.isLocal or arg.variable.isArgument) and isUnpackedStruct(arg.variable)
return arg and arg.variable and (arg.variable.isLocal or arg.variable.isArgument) and isUnpackedStruct(arg)
def isBitwiseOp(token):
@ -72,7 +73,7 @@ def isCast(expr):
# do not compare padding data
def exp42(data):
for token in data.tokenlist:
if token.str != '(' or not token.astOperand1:
if token.str != '(' or not token.astOperand1 or token.astOperand1.str != 'memcmp':
continue
arg1 = None
@ -82,7 +83,7 @@ def exp42(data):
arg1 = token.astOperand2.astOperand1.astOperand1
arg2 = token.astOperand2.astOperand1.astOperand2
if token.astOperand1.str == 'memcmp' and (isLocalUnpackedStruct(arg1) or isLocalUnpackedStruct(arg2)):
if isLocalUnpackedStruct(arg1) or isLocalUnpackedStruct(arg2):
reportError(
token, 'style', "Comparison of struct padding data " +
"(fix either by packing the struct using '#pragma pack' or by rewriting the comparison)", 'cert-EXP42-C')

View File

@ -1,9 +1,32 @@
// To test:
// ~/cppcheck/cppcheck --dump cert-test.c && python cert.py -verify cert-test.c.dump
unsigned char int31(int x) {
x = (unsigned char)1000; // cert-INT31-c
x = (signed char)0xff; // cert-INT31-c
x = (unsigned char)-1; // cert-INT31-c
x = (unsigned long long)-1; // cert-INT31-c
}
// To test:
// ~/cppcheck/cppcheck --dump cert-test.c && python ../cert.py -verify cert-test.c.dump
struct S {
short a;
short b;
};
#pragma pack()
struct PackedStruct {
short a;
short b;
};
void exp42()
{
struct S s1 = {1,2};
struct S s2 = {1,2};
memcmp(&s1, &s2, sizeof(struct S)); // cert-EXP42-C
struct PackedStruct s3 = {1,2};
struct PackedStruct s4 = {1,2};
memcmp(&s3, &s4, sizeof(struct S));
}
unsigned char int31(int x)
{
x = (unsigned char)1000; // cert-INT31-c
x = (signed char)0xff; // cert-INT31-c
x = (unsigned char)-1; // cert-INT31-c
x = (unsigned long long)-1; // cert-INT31-c
}