|
18 | 18 |
|
19 | 19 | import cpp |
20 | 20 | import semmle.code.cpp.ir.dataflow.DataFlow |
21 | | -import DataFlow::PathGraph |
| 21 | +import CastToPointerArithFlow::PathGraph |
22 | 22 |
|
23 | 23 | Type getFullyConvertedType(DataFlow::Node node) { |
24 | 24 | result = node.asExpr().getFullyConverted().getUnspecifiedType() |
25 | 25 | } |
26 | 26 |
|
27 | | -class CastToPointerArithFlow extends DataFlow::Configuration { |
28 | | - CastToPointerArithFlow() { this = "CastToPointerArithFlow" } |
| 27 | +module CastToPointerArithFlowConfig implements DataFlow::StateConfigSig { |
| 28 | + class FlowState = Type; |
29 | 29 |
|
30 | | - override predicate isSource(DataFlow::Node node, DataFlow::FlowState state) { |
| 30 | + predicate isSource(DataFlow::Node node, FlowState state) { |
31 | 31 | not node.asExpr() instanceof Conversion and |
32 | 32 | exists(Type baseType1, Type baseType2 | |
33 | 33 | hasBaseType(node.asExpr(), baseType1) and |
34 | 34 | hasBaseType(node.asExpr().getConversion*(), baseType2) and |
35 | 35 | introducesNewField(baseType1, baseType2) |
36 | 36 | ) and |
37 | | - getFullyConvertedType(node).getName() = state |
| 37 | + getFullyConvertedType(node) = state |
38 | 38 | } |
39 | 39 |
|
40 | | - override predicate isSink(DataFlow::Node node, DataFlow::FlowState state) { |
| 40 | + predicate isSink(DataFlow::Node node, FlowState state) { |
41 | 41 | ( |
42 | 42 | exists(PointerAddExpr pae | pae.getAnOperand() = node.asExpr()) or |
43 | 43 | exists(ArrayExpr ae | ae.getArrayBase() = node.asExpr()) |
44 | 44 | ) and |
45 | | - getFullyConvertedType(node).getName() = state |
| 45 | + getFullyConvertedType(node) = state |
| 46 | + } |
| 47 | + |
| 48 | + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } |
| 49 | + |
| 50 | + predicate isAdditionalFlowStep( |
| 51 | + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 |
| 52 | + ) { |
| 53 | + none() |
46 | 54 | } |
47 | 55 | } |
48 | 56 |
|
@@ -72,14 +80,16 @@ predicate introducesNewField(Class derived, Class base) { |
72 | 80 | ) |
73 | 81 | } |
74 | 82 |
|
| 83 | +module CastToPointerArithFlow = DataFlow::MakeWithState<CastToPointerArithFlowConfig>; |
| 84 | + |
75 | 85 | pragma[nomagic] |
76 | | -predicate hasFullyConvertedType(DataFlow::PathNode node, Type t) { |
| 86 | +predicate hasFullyConvertedType(CastToPointerArithFlow::PathNode node, Type t) { |
77 | 87 | getFullyConvertedType(node.getNode()) = t |
78 | 88 | } |
79 | 89 |
|
80 | | -from DataFlow::PathNode source, DataFlow::PathNode sink, CastToPointerArithFlow cfg, Type t |
| 90 | +from CastToPointerArithFlow::PathNode source, CastToPointerArithFlow::PathNode sink, Type t |
81 | 91 | where |
82 | | - cfg.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and |
| 92 | + CastToPointerArithFlow::hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and |
83 | 93 | hasFullyConvertedType(source, t) and |
84 | 94 | hasFullyConvertedType(sink, t) |
85 | 95 | select sink, source, sink, "This pointer arithmetic may be done with the wrong type because of $@.", |
|
0 commit comments