forked from github/codeql-coding-standards
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathArrayFunctionArgumentNumberOfElements.ql
More file actions
78 lines (69 loc) · 2.47 KB
/
ArrayFunctionArgumentNumberOfElements.ql
File metadata and controls
78 lines (69 loc) · 2.47 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* @id c/misra/array-function-argument-number-of-elements
* @name RULE-17-5: An array founction argument shall have an appropriate number of elements
* @description The function argument corresponding to an array parameter shall have an appropriate
* number of elements.
* @kind problem
* @precision high
* @problem.severity error
* @tags external/misra/id/rule-17-5
* correctness
* external/misra/c/2012/third-edition-first-revision
* external/misra/obligation/required
*/
import cpp
import codingstandards.c.misra
import semmle.code.cpp.dataflow.new.DataFlow
/**
* Models a function parameter of type array with specified size
* ```
* void f1(int ar[3]);
* ```
*/
class ArrayParameter extends Parameter {
ArrayParameter() { this.getType().(ArrayType).hasArraySize() }
Expr getAMatchingArgument() {
exists(FunctionCall fc |
this.getFunction() = fc.getTarget() and
result = fc.getArgument(this.getIndex())
)
}
int getArraySize() { result = this.getType().(ArrayType).getArraySize() }
}
/**
* The number of initialized elements in an ArrayAggregateLiteral.
* In the following examples the result=2
* ```
* int arr3[3] = {1, 2};
* int arr2[2] = {1, 2, 3};
* ```
*/
int countElements(ArrayAggregateLiteral l) { result = count(l.getAnElementExpr(_)) }
module SmallArrayConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node src) { src.asExpr() instanceof ArrayAggregateLiteral }
predicate isSink(DataFlow::Node sink) {
sink.asIndirectExpr() = any(ArrayParameter p).getAMatchingArgument()
}
}
module SmallArrayFlow = DataFlow::Global<SmallArrayConfig>;
from Expr arg, ArrayParameter p
where
not isExcluded(arg, Contracts6Package::arrayFunctionArgumentNumberOfElementsQuery()) and
arg = p.getAMatchingArgument() and
(
// the argument is a value and not an array
not arg.getType() instanceof DerivedType
or
// the argument is an array too small
arg.getType().(ArrayType).getArraySize() < p.getArraySize()
or
// the argument is a pointer and its value does not come from a literal of the correct
arg.getType() instanceof PointerType and
not exists(ArrayAggregateLiteral l, DataFlow::Node arg_node | arg_node.asIndirectExpr() = arg |
SmallArrayFlow::flow(DataFlow::exprNode(l), arg_node) and
countElements(l) >= p.getArraySize()
)
)
select arg,
"The function argument does not have a sufficient number or elements declared in the $@.", p,
"parameter"