|
5 | 5 | * through the `Global` and `GlobalWithState` modules.
|
6 | 6 | */
|
7 | 7 |
|
8 |
| -import DataFlowParameter |
| 8 | +/** Provides language-specific data flow parameters. */ |
| 9 | +signature module DataFlowParameter { |
| 10 | + class Node { |
| 11 | + /** Gets a textual representation of this element. */ |
| 12 | + string toString(); |
| 13 | + |
| 14 | + /** |
| 15 | + * Holds if this element is at the specified location. |
| 16 | + * The location spans column `startcolumn` of line `startline` to |
| 17 | + * column `endcolumn` of line `endline` in file `filepath`. |
| 18 | + * For more information, see |
| 19 | + * [Locations](https://codeql.github.com/docs/writing-codeql-queries/providing-locations-in-codeql-queries/). |
| 20 | + */ |
| 21 | + predicate hasLocationInfo( |
| 22 | + string filepath, int startline, int startcolumn, int endline, int endcolumn |
| 23 | + ); |
| 24 | + } |
| 25 | + |
| 26 | + class ParameterNode extends Node; |
| 27 | + |
| 28 | + class ArgumentNode extends Node; |
| 29 | + |
| 30 | + class ReturnNode extends Node { |
| 31 | + ReturnKind getKind(); |
| 32 | + } |
| 33 | + |
| 34 | + class OutNode extends Node; |
| 35 | + |
| 36 | + class PostUpdateNode extends Node { |
| 37 | + Node getPreUpdateNode(); |
| 38 | + } |
| 39 | + |
| 40 | + class CastNode extends Node; |
| 41 | + |
| 42 | + predicate isParameterNode(ParameterNode p, DataFlowCallable c, ParameterPosition pos); |
| 43 | + |
| 44 | + predicate isArgumentNode(ArgumentNode n, DataFlowCall call, ArgumentPosition pos); |
| 45 | + |
| 46 | + DataFlowCallable nodeGetEnclosingCallable(Node node); |
| 47 | + |
| 48 | + DataFlowType getNodeType(Node node); |
| 49 | + |
| 50 | + predicate nodeIsHidden(Node node); |
| 51 | + |
| 52 | + class DataFlowExpr; |
| 53 | + |
| 54 | + /** Gets the node corresponding to `e`. */ |
| 55 | + Node exprNode(DataFlowExpr e); |
| 56 | + |
| 57 | + class DataFlowCall { |
| 58 | + /** Gets a textual representation of this element. */ |
| 59 | + string toString(); |
| 60 | + |
| 61 | + DataFlowCallable getEnclosingCallable(); |
| 62 | + } |
| 63 | + |
| 64 | + class DataFlowCallable { |
| 65 | + /** Gets a textual representation of this element. */ |
| 66 | + string toString(); |
| 67 | + } |
| 68 | + |
| 69 | + class ReturnKind { |
| 70 | + /** Gets a textual representation of this element. */ |
| 71 | + string toString(); |
| 72 | + } |
| 73 | + |
| 74 | + /** Gets a viable implementation of the target of the given `Call`. */ |
| 75 | + DataFlowCallable viableCallable(DataFlowCall c); |
| 76 | + |
| 77 | + /** |
| 78 | + * Holds if the set of viable implementations that can be called by `call` |
| 79 | + * might be improved by knowing the call context. |
| 80 | + */ |
| 81 | + predicate mayBenefitFromCallContext(DataFlowCall call, DataFlowCallable c); |
| 82 | + |
| 83 | + /** |
| 84 | + * Gets a viable dispatch target of `call` in the context `ctx`. This is |
| 85 | + * restricted to those `call`s for which a context might make a difference. |
| 86 | + */ |
| 87 | + DataFlowCallable viableImplInCallContext(DataFlowCall call, DataFlowCall ctx); |
| 88 | + |
| 89 | + /** |
| 90 | + * Gets a node that can read the value returned from `call` with return kind |
| 91 | + * `kind`. |
| 92 | + */ |
| 93 | + OutNode getAnOutNode(DataFlowCall call, ReturnKind kind); |
| 94 | + |
| 95 | + class DataFlowType { |
| 96 | + /** Gets a textual representation of this element. */ |
| 97 | + string toString(); |
| 98 | + } |
| 99 | + |
| 100 | + string ppReprType(DataFlowType t); |
| 101 | + |
| 102 | + bindingset[t1, t2] |
| 103 | + predicate compatibleTypes(DataFlowType t1, DataFlowType t2); |
| 104 | + |
| 105 | + predicate typeStrongerThan(DataFlowType t1, DataFlowType t2); |
| 106 | + |
| 107 | + class Content { |
| 108 | + /** Gets a textual representation of this element. */ |
| 109 | + string toString(); |
| 110 | + } |
| 111 | + |
| 112 | + predicate forceHighPrecision(Content c); |
| 113 | + |
| 114 | + /** |
| 115 | + * An entity that represents a set of `Content`s. |
| 116 | + * |
| 117 | + * The set may be interpreted differently depending on whether it is |
| 118 | + * stored into (`getAStoreContent`) or read from (`getAReadContent`). |
| 119 | + */ |
| 120 | + class ContentSet { |
| 121 | + /** Gets a content that may be stored into when storing into this set. */ |
| 122 | + Content getAStoreContent(); |
| 123 | + |
| 124 | + /** Gets a content that may be read from when reading from this set. */ |
| 125 | + Content getAReadContent(); |
| 126 | + } |
| 127 | + |
| 128 | + class ContentApprox { |
| 129 | + /** Gets a textual representation of this element. */ |
| 130 | + string toString(); |
| 131 | + } |
| 132 | + |
| 133 | + ContentApprox getContentApprox(Content c); |
| 134 | + |
| 135 | + class ParameterPosition { |
| 136 | + /** Gets a textual representation of this element. */ |
| 137 | + bindingset[this] |
| 138 | + string toString(); |
| 139 | + } |
| 140 | + |
| 141 | + class ArgumentPosition { |
| 142 | + /** Gets a textual representation of this element. */ |
| 143 | + bindingset[this] |
| 144 | + string toString(); |
| 145 | + } |
| 146 | + |
| 147 | + predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos); |
| 148 | + |
| 149 | + predicate simpleLocalFlowStep(Node node1, Node node2); |
| 150 | + |
| 151 | + /** |
| 152 | + * Holds if data can flow from `node1` to `node2` through a non-local step |
| 153 | + * that does not follow a call edge. For example, a step through a global |
| 154 | + * variable. |
| 155 | + */ |
| 156 | + predicate jumpStep(Node node1, Node node2); |
| 157 | + |
| 158 | + /** |
| 159 | + * Holds if data can flow from `node1` to `node2` via a read of `c`. Thus, |
| 160 | + * `node1` references an object with a content `c.getAReadContent()` whose |
| 161 | + * value ends up in `node2`. |
| 162 | + */ |
| 163 | + predicate readStep(Node node1, ContentSet c, Node node2); |
| 164 | + |
| 165 | + /** |
| 166 | + * Holds if data can flow from `node1` to `node2` via a store into `c`. Thus, |
| 167 | + * `node2` references an object with a content `c.getAStoreContent()` that |
| 168 | + * contains the value of `node1`. |
| 169 | + */ |
| 170 | + predicate storeStep(Node node1, ContentSet c, Node node2); |
| 171 | + |
| 172 | + /** |
| 173 | + * Holds if values stored inside content `c` are cleared at node `n`. For example, |
| 174 | + * any value stored inside `f` is cleared at the pre-update node associated with `x` |
| 175 | + * in `x.f = newValue`. |
| 176 | + */ |
| 177 | + predicate clearsContent(Node n, ContentSet c); |
| 178 | + |
| 179 | + /** |
| 180 | + * Holds if the value that is being tracked is expected to be stored inside content `c` |
| 181 | + * at node `n`. |
| 182 | + */ |
| 183 | + predicate expectsContent(Node n, ContentSet c); |
| 184 | + |
| 185 | + /** |
| 186 | + * Holds if the node `n` is unreachable when the call context is `call`. |
| 187 | + */ |
| 188 | + predicate isUnreachableInCall(Node n, DataFlowCall call); |
| 189 | + |
| 190 | + default int accessPathLimit() { result = 5 } |
| 191 | + |
| 192 | + /** |
| 193 | + * Holds if flow is allowed to pass from parameter `p` and back to itself as a |
| 194 | + * side-effect, resulting in a summary from `p` to itself. |
| 195 | + * |
| 196 | + * One example would be to allow flow like `p.foo = p.bar;`, which is disallowed |
| 197 | + * by default as a heuristic. |
| 198 | + */ |
| 199 | + predicate allowParameterReturnInSelf(ParameterNode p); |
| 200 | + |
| 201 | + class LambdaCallKind; |
| 202 | + |
| 203 | + /** Holds if `creation` is an expression that creates a lambda of kind `kind` for `c`. */ |
| 204 | + predicate lambdaCreation(Node creation, LambdaCallKind kind, DataFlowCallable c); |
| 205 | + |
| 206 | + /** Holds if `call` is a lambda call of kind `kind` where `receiver` is the lambda expression. */ |
| 207 | + predicate lambdaCall(DataFlowCall call, LambdaCallKind kind, Node receiver); |
| 208 | + |
| 209 | + /** Extra data-flow steps needed for lambda flow analysis. */ |
| 210 | + predicate additionalLambdaFlowStep(Node nodeFrom, Node nodeTo, boolean preservesValue); |
| 211 | + |
| 212 | + /** |
| 213 | + * Holds if `n` should never be skipped over in the `PathGraph` and in path |
| 214 | + * explanations. |
| 215 | + */ |
| 216 | + default predicate neverSkipInPathGraph(Node n) { none() } |
| 217 | + |
| 218 | + /** |
| 219 | + * Gets an additional term that is added to the `join` and `branch` computations to reflect |
| 220 | + * an additional forward or backwards branching factor that is not taken into account |
| 221 | + * when calculating the (virtual) dispatch cost. |
| 222 | + * |
| 223 | + * Argument `arg` is part of a path from a source to a sink, and `p` is the target parameter. |
| 224 | + */ |
| 225 | + int getAdditionalFlowIntoCallNodeTerm(ArgumentNode arg, ParameterNode p); |
| 226 | + |
| 227 | + predicate golangSpecificParamArgFilter(DataFlowCall call, ParameterNode p, ArgumentNode arg); |
| 228 | +} |
9 | 229 |
|
10 | 230 | module Configs<DataFlowParameter Lang> {
|
11 | 231 | private import Lang
|
12 |
| - private import DataFlowImplCommon::MakeImplCommon<Lang> |
| 232 | + private import internal.DataFlowImplCommon::MakeImplCommon<Lang> |
13 | 233 | import DataFlowImplCommonPublic
|
14 | 234 |
|
15 | 235 | /** An input configuration for data flow. */
|
@@ -213,7 +433,7 @@ module Configs<DataFlowParameter Lang> {
|
213 | 433 |
|
214 | 434 | module DataFlowMake<DataFlowParameter Lang> {
|
215 | 435 | private import Lang
|
216 |
| - private import DataFlowImpl::MakeImpl<Lang> |
| 436 | + private import internal.DataFlowImpl::MakeImpl<Lang> |
217 | 437 | import Configs<Lang>
|
218 | 438 |
|
219 | 439 | /**
|
|
0 commit comments