@@ -6,6 +6,7 @@ private import python
6
6
private import DataFlowPrivate
7
7
import semmle.python.dataflow.new.TypeTracker
8
8
import Attributes
9
+ import LocalSources
9
10
private import semmle.python.essa.SsaCompute
10
11
11
12
/**
@@ -138,6 +139,11 @@ class Node extends TNode {
138
139
* Gets a local source node from which data may flow to this node in zero or more local steps.
139
140
*/
140
141
LocalSourceNode getALocalSource ( ) { result .flowsTo ( this ) }
142
+
143
+ /**
144
+ * Gets a local source node from which data may flow to this node in zero or more local steps.
145
+ */
146
+ LocalSourceNode getALocalTaintSource ( ) { result .taintFlowsTo ( this ) }
141
147
}
142
148
143
149
/** A data-flow node corresponding to an SSA variable. */
@@ -215,7 +221,7 @@ ExprNode exprNode(DataFlowExpr e) { result.getNode().getNode() = e }
215
221
* The value of a parameter at function entry, viewed as a node in a data
216
222
* flow graph.
217
223
*/
218
- class ParameterNode extends CfgNode {
224
+ class ParameterNode extends CfgNode , LocalSourceNode {
219
225
ParameterDefinition def ;
220
226
221
227
ParameterNode ( ) {
@@ -237,6 +243,9 @@ class ParameterNode extends CfgNode {
237
243
Parameter getParameter ( ) { result = def .getParameter ( ) }
238
244
}
239
245
246
+ /** Gets a node corresponding to parameter `p`. */
247
+ ParameterNode parameterNode ( Parameter p ) { result .getParameter ( ) = p }
248
+
240
249
/** A data flow node that represents a call argument. */
241
250
class ArgumentNode extends Node {
242
251
ArgumentNode ( ) { this = any ( DataFlowCall c ) .getArg ( _) }
@@ -467,103 +476,6 @@ class BarrierGuard extends GuardNode {
467
476
}
468
477
}
469
478
470
- /**
471
- * A data flow node that is a source of local flow. This includes things like
472
- * - Expressions
473
- * - Function parameters
474
- */
475
- class LocalSourceNode extends Node {
476
- LocalSourceNode ( ) {
477
- not simpleLocalFlowStep + ( any ( CfgNode n ) , this ) and
478
- not this instanceof ModuleVariableNode
479
- or
480
- this = any ( ModuleVariableNode mvn ) .getARead ( )
481
- }
482
-
483
- /** Holds if this `LocalSourceNode` can flow to `nodeTo` in one or more local flow steps. */
484
- pragma [ inline]
485
- predicate flowsTo ( Node nodeTo ) { Cached:: hasLocalSource ( nodeTo , this ) }
486
-
487
- /**
488
- * Gets a reference (read or write) of attribute `attrName` on this node.
489
- */
490
- AttrRef getAnAttributeReference ( string attrName ) { Cached:: namedAttrRef ( this , attrName , result ) }
491
-
492
- /**
493
- * Gets a read of attribute `attrName` on this node.
494
- */
495
- AttrRead getAnAttributeRead ( string attrName ) { result = getAnAttributeReference ( attrName ) }
496
-
497
- /**
498
- * Gets a reference (read or write) of any attribute on this node.
499
- */
500
- AttrRef getAnAttributeReference ( ) {
501
- Cached:: namedAttrRef ( this , _, result )
502
- or
503
- Cached:: dynamicAttrRef ( this , result )
504
- }
505
-
506
- /**
507
- * Gets a read of any attribute on this node.
508
- */
509
- AttrRead getAnAttributeRead ( ) { result = getAnAttributeReference ( ) }
510
-
511
- /**
512
- * Gets a call to this node.
513
- */
514
- CallCfgNode getACall ( ) { Cached:: call ( this , result ) }
515
- }
516
-
517
- cached
518
- private module Cached {
519
- /**
520
- * Holds if `source` is a `LocalSourceNode` that can reach `sink` via local flow steps.
521
- *
522
- * The slightly backwards parametering ordering is to force correct indexing.
523
- */
524
- cached
525
- predicate hasLocalSource ( Node sink , Node source ) {
526
- // Declaring `source` to be a `SourceNode` currently causes a redundant check in the
527
- // recursive case, so instead we check it explicitly here.
528
- source = sink and
529
- source instanceof LocalSourceNode
530
- or
531
- exists ( Node mid |
532
- hasLocalSource ( mid , source ) and
533
- simpleLocalFlowStep ( mid , sink )
534
- )
535
- }
536
-
537
- /**
538
- * Holds if `base` flows to the base of `ref` and `ref` has attribute name `attr`.
539
- */
540
- cached
541
- predicate namedAttrRef ( LocalSourceNode base , string attr , AttrRef ref ) {
542
- base .flowsTo ( ref .getObject ( ) ) and
543
- ref .getAttributeName ( ) = attr
544
- }
545
-
546
- /**
547
- * Holds if `base` flows to the base of `ref` and `ref` has no known attribute name.
548
- */
549
- cached
550
- predicate dynamicAttrRef ( LocalSourceNode base , AttrRef ref ) {
551
- base .flowsTo ( ref .getObject ( ) ) and
552
- not exists ( ref .getAttributeName ( ) )
553
- }
554
-
555
- /**
556
- * Holds if `func` flows to the callee of `call`.
557
- */
558
- cached
559
- predicate call ( LocalSourceNode func , CallCfgNode call ) {
560
- exists ( CfgNode n |
561
- func .flowsTo ( n ) and
562
- n = call .getFunction ( )
563
- )
564
- }
565
- }
566
-
567
479
/**
568
480
* Algebraic datatype for tracking data content associated with values.
569
481
* Content can be collection elements or object attributes.
0 commit comments