Skip to content

Commit 77fa2b7

Browse files
committed
Add QLDocs and comments
1 parent 8ecc213 commit 77fa2b7

File tree

1 file changed

+49
-1
lines changed

1 file changed

+49
-1
lines changed

cpp/misra/src/rules/RULE-8-7-1/PointerArithmeticFormsAnInvalidPointer.ql

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@ import codingstandards.cpp.misra
1717
import semmle.code.cpp.dataflow.new.TaintTracking
1818
import semmle.code.cpp.security.BufferAccess
1919

20+
/**
21+
* A declaration of a variable that is of an array type.
22+
*/
2023
class ArrayDeclaration extends VariableDeclarationEntry {
2124
int length;
2225

@@ -28,6 +31,9 @@ class ArrayDeclaration extends VariableDeclarationEntry {
2831
int getLength() { result = length }
2932
}
3033

34+
/**
35+
* A call to a function that dynamically allocates memory on the heap.
36+
*/
3137
class HeapAllocationFunctionCall extends FunctionCall {
3238
AllocationFunction heapAllocFunction;
3339

@@ -39,6 +45,9 @@ class HeapAllocationFunctionCall extends FunctionCall {
3945

4046
predicate isReallocCall() { heapAllocFunction.getName() = "realloc" }
4147

48+
/**
49+
* Get the minimum estimated number of bytes allocated.
50+
*/
4251
abstract int getMinNumBytes();
4352
}
4453

@@ -62,6 +71,9 @@ class ReallocFunctionCall extends HeapAllocationFunctionCall {
6271
override int getMinNumBytes() { result = lowerBound(this.getArgument(1)) }
6372
}
6473

74+
/**
75+
* The
76+
*/
6577
class NarrowedHeapAllocationFunctionCall extends Cast {
6678
HeapAllocationFunctionCall alloc;
6779

@@ -72,6 +84,15 @@ class NarrowedHeapAllocationFunctionCall extends Cast {
7284
rawResult =
7385
alloc.getMinNumBytes() / this.getUnderlyingType().(PointerType).getBaseType().getSize()
7486
|
87+
/*
88+
* The `SimpleRangeAnalysis` library is not perfect, and sometimes can widen to both ends
89+
* of the type bound.
90+
*
91+
* Since it does not make sense for a object to have negative length or even zero (the
92+
* rule dictates that non-array objects should have length of 0), we clip the range and
93+
* make the minimum number of elements to 1.
94+
*/
95+
7596
result = rawResult.maximum(1)
7697
)
7798
}
@@ -85,6 +106,9 @@ newtype TPointerFormation =
85106
TArrayExpr(ArrayExprBA arrayExpr) or
86107
TPointerArithmetic(PointerArithmeticOperation pointerArithmetic)
87108

109+
/**
110+
* Any kind of allocation of an array, either allocated on the stack or the heap.
111+
*/
88112
class ArrayAllocation extends TArrayAllocation {
89113
ArrayDeclaration asStackAllocation() { this = TStackAllocation(result) }
90114

@@ -109,12 +133,19 @@ class ArrayAllocation extends TArrayAllocation {
109133
result = this.asDynamicAllocation().getLocation()
110134
}
111135

136+
/**
137+
* Gets the node associated with this allocation.
138+
*/
112139
DataFlow::Node getNode() {
113140
result.asUninitialized() = this.asStackAllocation().getVariable() or
114141
result.asConvertedExpr() = this.asDynamicAllocation()
115142
}
116143
}
117144

145+
/**
146+
* Any kind of pointer formation that derives from a base pointer, either as an arithmetic operation
147+
* on pointers, or an array access expression.
148+
*/
118149
class PointerFormation extends TPointerFormation {
119150
ArrayExprBA asArrayExpr() { this = TArrayExpr(result) }
120151

@@ -125,6 +156,9 @@ class PointerFormation extends TPointerFormation {
125156
result = this.asPointerArithmetic().toString()
126157
}
127158

159+
/**
160+
* Gets the offset of this pointer formation as calculated in relation to the base pointer.
161+
*/
128162
int getOffset() {
129163
result = this.asArrayExpr().getArrayOffset().getValue().toInt()
130164
or
@@ -137,11 +171,17 @@ class PointerFormation extends TPointerFormation {
137171
)
138172
}
139173

174+
/**
175+
* Gets the expression associated with this pointer formation.
176+
*/
140177
Expr asExpr() {
141178
result = this.asArrayExpr() or
142-
/*.getArrayBase()*/ result = this.asPointerArithmetic()
179+
result = this.asPointerArithmetic()
143180
}
144181

182+
/**
183+
* Gets the data-flow node associated with this pointer formation.
184+
*/
145185
DataFlow::Node getNode() { result.asExpr() = this.asExpr() }
146186

147187
Location getLocation() {
@@ -204,6 +244,10 @@ module Copied {
204244

205245
import Copied
206246

247+
/**
248+
* A data flow configuration that starts from the allocation of an array and ends at a
249+
* pointer derived from that array.
250+
*/
207251
module TrackArrayConfig implements DataFlow::ConfigSig {
208252
predicate isSource(DataFlow::Node node) {
209253
exists(ArrayAllocation arrayAllocation | node = arrayAllocation.getNode())
@@ -221,6 +265,10 @@ module TrackArrayConfig implements DataFlow::ConfigSig {
221265

222266
module TrackArray = DataFlow::Global<TrackArrayConfig>;
223267

268+
/**
269+
* Holds if the offset of a pointer formation, as referred to by `pointerFormationNode`,
270+
* exceeds the length of the declared array, as represented by `arrayDeclarationNode`.
271+
*/
224272
predicate arrayIndexExceedsBounds(
225273
DataFlow::Node arrayDeclarationNode, DataFlow::Node pointerFormationNode, int pointerOffset,
226274
int arrayLength

0 commit comments

Comments
 (0)