Skip to content

Commit bd3e06b

Browse files
Fix 18-1 amendment use-use flow
1 parent 0c7b503 commit bd3e06b

File tree

3 files changed

+16
-9
lines changed

3 files changed

+16
-9
lines changed

cpp/common/src/codingstandards/cpp/rules/donotusepointerarithmetictoaddressdifferentarrays/DoNotUsePointerArithmeticToAddressDifferentArrays.qll

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ abstract class ArrayLikeAccess extends Expr {
3333
*/
3434
class ArrayVariableAccess extends ArrayLikeAccess, VariableAccess {
3535
int size;
36-
36+
3737
ArrayVariableAccess() { size = getType().(ArrayType).getArraySize() }
3838

3939
override Variable getElement() { result = getTarget() }
@@ -47,7 +47,7 @@ class ArrayVariableAccess extends ArrayLikeAccess, VariableAccess {
4747

4848
/**
4949
* Get the size of the object pointed to by a type (pointer or array).
50-
*
50+
*
5151
* Depth of type unwrapping depends on the type. Pointer will be dereferenced only once: the element
5252
* size of `T*` is `sizeof(T)` while the element size of `T**` is `sizeof(T*)`. However, array types
5353
* will be deeply unwrapped, as the pointed to size of `T[][]` is `sizeof(T)`. These processes
@@ -88,7 +88,17 @@ class CastedToBytePointer extends ArrayLikeAccess, Conversion {
8888

8989
override int getSize() { result = size }
9090

91-
override DataFlow::Node getNode() { result.asConvertedExpr() = this }
91+
override DataFlow::Node getNode() {
92+
// Carefully avoid use-use flow, which would mean any later usage of the original pointer value
93+
// after the cast would be considered a usage of the byte pointer value.
94+
//
95+
// To fix this, we currently assume the value is assigned to a variable, and find that variable
96+
// with `.asDefinition()` like so:
97+
exists(DataFlow::Node conversion |
98+
conversion.asConvertedExpr() = this and
99+
result.asDefinition() = conversion.asExpr()
100+
)
101+
}
92102
}
93103

94104
/**
@@ -272,4 +282,4 @@ query predicate problems(Expr arrayPointerCreation, string message, Element arra
272282
"Array pointer " + derivedArrayPointerOrPointerOperand.getName() + " points " +
273283
difference.toString() + " " + denomination + " past the end of $@."
274284
)
275-
}
285+
}

cpp/common/test/rules/donotusepointerarithmetictoaddressdifferentarrays/DoNotUsePointerArithmeticToAddressDifferentArrays.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,3 @@
66
| test.cpp:25:15:25:21 | & ... | Array pointer p14 points 1 element past the end of $@. | test.cpp:2:7:2:8 | l1 | l1 |
77
| test.cpp:30:15:30:21 | & ... | Array pointer p17 points 1 element past the end of $@. | test.cpp:28:24:28:42 | (unsigned char *)... | cast to btye pointer (unsigned char *)... |
88
| test.cpp:35:15:35:21 | & ... | Array pointer p20 points 1 element past the end of $@. | test.cpp:33:24:33:43 | (unsigned char *)... | cast to btye pointer (unsigned char *)... |
9-
| test.cpp:43:15:43:23 | & ... | Array pointer p23 points 96 elements past the end of $@. | test.cpp:28:24:28:42 | (unsigned char *)... | cast to btye pointer (unsigned char *)... |

cpp/common/test/rules/donotusepointerarithmetictoaddressdifferentarrays/test.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,7 @@ void f1() {
3636

3737
// Casting to a pointer to a differently sized type that isn't char
3838
// invalidates analysis
39-
int l3[3];
40-
long *p21 = (long*)&l1;
39+
long *p21 = (long *)&l1;
4140
void *p22 = &p21[0]; // COMPLIANT
42-
// Not compliant, but we shouldn't detect it, but we do for the wrong reason:
43-
void *p23 = &p21[100]; // NON_COMPLIANT[FALSE_NEGATIVE][FALSE_POSITIVE]
41+
void *p23 = &p21[100]; // NON_COMPLIANT[FALSE_NEGATIVE]
4442
}

0 commit comments

Comments
 (0)