Skip to content

Commit 9e43da9

Browse files
committed
Python: DataFlowDispatch.qll annotations
1 parent 65d01e9 commit 9e43da9

File tree

1 file changed

+35
-0
lines changed

1 file changed

+35
-0
lines changed

python/ql/lib/semmle/python/dataflow/new/internal/DataFlowDispatch.qll

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
* Note: This hasn't been 100% realized yet, so we don't currently expose a predicate to
3232
* ask what targets any data-flow node has. But it's still the plan to do this!
3333
*/
34+
overlay[local?]
35+
module;
3436

3537
private import python
3638
private import DataFlowPublic
@@ -39,6 +41,7 @@ private import FlowSummaryImpl as FlowSummaryImpl
3941
private import semmle.python.internal.CachedStages
4042
private import semmle.python.dataflow.new.internal.TypeTrackingImpl::CallGraphConstruction as CallGraphConstruction
4143

44+
overlay[local]
4245
newtype TParameterPosition =
4346
/** Used for `self` in methods, and `cls` in classmethods. */
4447
TSelfParameterPosition() or
@@ -84,6 +87,7 @@ newtype TParameterPosition =
8487
TSynthDictSplatParameterPosition()
8588

8689
/** A parameter position. */
90+
overlay[local]
8791
class ParameterPosition extends TParameterPosition {
8892
/** Holds if this position represents a `self`/`cls` parameter. */
8993
predicate isSelf() { this = TSelfParameterPosition() }
@@ -146,6 +150,7 @@ class ParameterPosition extends TParameterPosition {
146150
}
147151
}
148152

153+
overlay[local]
149154
newtype TArgumentPosition =
150155
/** Used for `self` in methods, and `cls` in classmethods. */
151156
TSelfArgumentPosition() or
@@ -180,6 +185,7 @@ newtype TArgumentPosition =
180185
TDictSplatArgumentPosition()
181186

182187
/** An argument position. */
188+
overlay[local]
183189
class ArgumentPosition extends TArgumentPosition {
184190
/** Holds if this position represents a `self`/`cls` argument. */
185191
predicate isSelf() { this = TSelfArgumentPosition() }
@@ -248,6 +254,7 @@ predicate parameterMatch(ParameterPosition ppos, ArgumentPosition apos) {
248254
* `@staticmethod` decorator or by convention
249255
* (like a `__new__` method on a class is a classmethod even without the decorator).
250256
*/
257+
overlay[local]
251258
predicate isStaticmethod(Function func) {
252259
exists(NameNode id | id.getId() = "staticmethod" and id.isGlobal() |
253260
func.getADecorator() = id.getNode()
@@ -259,6 +266,7 @@ predicate isStaticmethod(Function func) {
259266
* `@classmethod` decorator or by convention
260267
* (like a `__new__` method on a class is a classmethod even without the decorator).
261268
*/
269+
overlay[local]
262270
predicate isClassmethod(Function func) {
263271
exists(NameNode id | id.getId() = "classmethod" and id.isGlobal() |
264272
func.getADecorator() = id.getNode()
@@ -275,6 +283,7 @@ predicate isClassmethod(Function func) {
275283
}
276284

277285
/** Holds if the function `func` has a `property` decorator. */
286+
overlay[local]
278287
predicate hasPropertyDecorator(Function func) {
279288
exists(NameNode id | id.getId() = "property" and id.isGlobal() |
280289
func.getADecorator() = id.getNode()
@@ -284,6 +293,7 @@ predicate hasPropertyDecorator(Function func) {
284293
/**
285294
* Holds if the function `func` has a `contextlib.contextmanager`.
286295
*/
296+
overlay[local]
287297
predicate hasContextmanagerDecorator(Function func) {
288298
exists(ControlFlowNode contextmanager |
289299
contextmanager.(NameNode).getId() = "contextmanager" and contextmanager.(NameNode).isGlobal()
@@ -298,20 +308,25 @@ predicate hasContextmanagerDecorator(Function func) {
298308
// Callables
299309
// =============================================================================
300310
/** A callable defined in library code, identified by a unique string. */
311+
overlay[local]
301312
abstract class LibraryCallable extends string {
302313
bindingset[this]
303314
LibraryCallable() { any() }
304315

305316
/** Gets a call to this library callable. */
317+
overlay[global]
306318
abstract CallCfgNode getACall();
307319

308320
/** Same as `getACall` but without referring to the call graph or API graph. */
321+
overlay[global]
309322
CallCfgNode getACallSimple() { none() }
310323

311324
/** Gets a data-flow node, where this library callable is used as a call-back. */
325+
overlay[global]
312326
abstract ArgumentNode getACallback();
313327
}
314328

329+
overlay[local]
315330
newtype TDataFlowCallable =
316331
/**
317332
* Is used as the target for all calls: plain functions, lambdas, methods on classes,
@@ -329,6 +344,7 @@ newtype TDataFlowCallable =
329344
TLibraryCallable(LibraryCallable callable)
330345

331346
/** A callable. */
347+
overlay[local]
332348
abstract class DataFlowCallable extends TDataFlowCallable {
333349
/** Gets a textual representation of this element. */
334350
abstract string toString();
@@ -350,6 +366,7 @@ abstract class DataFlowCallable extends TDataFlowCallable {
350366
}
351367

352368
/** A callable function. */
369+
overlay[local]
353370
abstract class DataFlowFunction extends DataFlowCallable, TFunction {
354371
Function func;
355372

@@ -370,6 +387,7 @@ abstract class DataFlowFunction extends DataFlowCallable, TFunction {
370387
/** Gets the positional parameter offset, to take into account self/cls parameters. */
371388
int positionalOffset() { result = 0 }
372389

390+
overlay[local]
373391
override ParameterNode getParameter(ParameterPosition ppos) {
374392
// Do not handle lower bound positions (such as `[1..]`) here
375393
// they are handled by parameter matching and would create
@@ -408,11 +426,13 @@ abstract class DataFlowFunction extends DataFlowCallable, TFunction {
408426
}
409427

410428
/** A plain (non-method) function. */
429+
overlay[local]
411430
class DataFlowPlainFunction extends DataFlowFunction {
412431
DataFlowPlainFunction() { not this instanceof DataFlowMethod }
413432
}
414433

415434
/** A method. */
435+
overlay[local]
416436
class DataFlowMethod extends DataFlowFunction {
417437
Class cls;
418438

@@ -431,11 +451,13 @@ class DataFlowMethod extends DataFlowFunction {
431451
}
432452

433453
/** A classmethod. */
454+
overlay[local]
434455
class DataFlowClassmethod extends DataFlowMethod {
435456
DataFlowClassmethod() { isClassmethod(func) }
436457
}
437458

438459
/** A staticmethod. */
460+
overlay[local]
439461
class DataFlowStaticmethod extends DataFlowMethod, DataFlowFunction {
440462
DataFlowStaticmethod() { isStaticmethod(func) }
441463

@@ -450,6 +472,7 @@ class DataFlowStaticmethod extends DataFlowMethod, DataFlowFunction {
450472
* A module. This is not actually a callable, but we need this so a
451473
* `ModuleVariableNode` have an enclosing callable.
452474
*/
475+
overlay[local]
453476
class DataFlowModuleScope extends DataFlowCallable, TModule {
454477
Module mod;
455478

@@ -466,6 +489,7 @@ class DataFlowModuleScope extends DataFlowCallable, TModule {
466489
override ParameterNode getParameter(ParameterPosition ppos) { none() }
467490
}
468491

492+
overlay[local]
469493
class LibraryCallableValue extends DataFlowCallable, TLibraryCallable {
470494
LibraryCallable callable;
471495

@@ -476,6 +500,7 @@ class LibraryCallableValue extends DataFlowCallable, TLibraryCallable {
476500
override string getQualifiedName() { result = callable.toString() }
477501

478502
/** Gets a data-flow node, where this library callable is used as a call-back. */
503+
overlay[global]
479504
ArgumentNode getACallback() { result = callable.getACallback() }
480505

481506
override Scope getScope() { none() }
@@ -1210,6 +1235,7 @@ predicate resolveCall(CallNode call, Function target, CallType type) {
12101235
* Holds if the argument of `call` at position `apos` is `arg`. This is just a helper
12111236
* predicate that maps ArgumentPositions to the arguments of the underlying `CallNode`.
12121237
*/
1238+
overlay[local]
12131239
cached
12141240
predicate normalCallArg(CallNode call, Node arg, ArgumentPosition apos) {
12151241
exists(int index |
@@ -1589,6 +1615,7 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
15891615
* The value of a parameter at function entry, viewed as a node in a data
15901616
* flow graph.
15911617
*/
1618+
overlay[local]
15921619
abstract class ParameterNodeImpl extends Node {
15931620
/** Gets the `Parameter` this `ParameterNode` represents. */
15941621
abstract Parameter getParameter();
@@ -1610,6 +1637,7 @@ abstract class ParameterNodeImpl extends Node {
16101637
*
16111638
* This is used for tracking flow through captured variables.
16121639
*/
1640+
overlay[local]
16131641
class SynthCapturedVariablesParameterNode extends ParameterNodeImpl,
16141642
TSynthCapturedVariablesParameterNode
16151643
{
@@ -1634,6 +1662,7 @@ class SynthCapturedVariablesParameterNode extends ParameterNodeImpl,
16341662
}
16351663

16361664
/** A parameter for a library callable with a flow summary. */
1665+
overlay[local]
16371666
class SummaryParameterNode extends ParameterNodeImpl, FlowSummaryNode {
16381667
SummaryParameterNode() {
16391668
FlowSummaryImpl::Private::summaryParameterNode(this.getSummaryNode(), _)
@@ -1684,6 +1713,7 @@ private class SummaryReturnNode extends FlowSummaryNode, ReturnNode {
16841713
override ReturnKind getKind() { result = rk }
16851714
}
16861715

1716+
overlay[global]
16871717
private class SummaryArgumentNode extends FlowSummaryNode, ArgumentNode {
16881718
private SummaryCall call_;
16891719
private ArgumentPosition pos_;
@@ -1737,6 +1767,7 @@ class SynthCapturedVariablesArgumentNode extends Node, TSynthCapturedVariablesAr
17371767
class CapturedVariablesArgumentNodeAsArgumentNode extends ArgumentNode,
17381768
SynthCapturedVariablesArgumentNode
17391769
{
1770+
overlay[global]
17401771
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
17411772
exists(CallNode callNode | callNode = this.getCallNode() |
17421773
callNode = call.getNode() and
@@ -1773,6 +1804,7 @@ class SynthCapturedVariablesArgumentPostUpdateNode extends PostUpdateNodeImpl,
17731804
}
17741805

17751806
/** A synthetic node representing the values of variables captured by a comprehension. */
1807+
overlay[local]
17761808
class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVariablesArgumentNode {
17771809
Comp comp;
17781810

@@ -1790,6 +1822,7 @@ class SynthCompCapturedVariablesArgumentNode extends Node, TSynthCompCapturedVar
17901822
class SynthCompCapturedVariablesArgumentNodeAsArgumentNode extends SynthCompCapturedVariablesArgumentNode,
17911823
ArgumentNode
17921824
{
1825+
overlay[global]
17931826
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
17941827
call.(ComprehensionCall).getComprehension() = comp and
17951828
pos.isLambdaSelf()
@@ -1834,12 +1867,14 @@ DataFlowCallable viableCallable(DataFlowCall call) {
18341867
// =============================================================================
18351868
// Remaining required data-flow things
18361869
// =============================================================================
1870+
overlay[local]
18371871
private newtype TReturnKind = TNormalReturnKind()
18381872

18391873
/**
18401874
* A return kind. A return kind describes how a value can be returned
18411875
* from a callable. For Python, this is simply a method return.
18421876
*/
1877+
overlay[local]
18431878
class ReturnKind extends TReturnKind {
18441879
/** Gets a textual representation of this element. */
18451880
string toString() { result = "return" }

0 commit comments

Comments
 (0)