@@ -6,6 +6,7 @@ private import python
66private import DataFlowPrivate
77import semmle.python.dataflow.new.TypeTracker
88import Attributes
9+ import LocalSources
910private import semmle.python.essa.SsaCompute
1011
1112/**
@@ -135,7 +136,7 @@ class Node extends TNode {
135136 LocalSourceNode backtrack ( TypeBackTracker t2 , TypeBackTracker t ) { t2 = t .step ( result , this ) }
136137
137138 /**
138- * Gets a local source node from which data may flow to this node in zero or more local steps.
139+ * Gets a local source node from which data may flow to this node in zero or more local data-flow steps.
139140 */
140141 LocalSourceNode getALocalSource ( ) { result .flowsTo ( this ) }
141142}
@@ -215,7 +216,7 @@ ExprNode exprNode(DataFlowExpr e) { result.getNode().getNode() = e }
215216 * The value of a parameter at function entry, viewed as a node in a data
216217 * flow graph.
217218 */
218- class ParameterNode extends CfgNode {
219+ class ParameterNode extends CfgNode , LocalSourceNode {
219220 ParameterDefinition def ;
220221
221222 ParameterNode ( ) {
@@ -237,6 +238,9 @@ class ParameterNode extends CfgNode {
237238 Parameter getParameter ( ) { result = def .getParameter ( ) }
238239}
239240
241+ /** Gets a node corresponding to parameter `p`. */
242+ ParameterNode parameterNode ( Parameter p ) { result .getParameter ( ) = p }
243+
240244/** A data flow node that represents a call argument. */
241245class ArgumentNode extends Node {
242246 ArgumentNode ( ) { this = any ( DataFlowCall c ) .getArg ( _) }
@@ -467,108 +471,6 @@ class BarrierGuard extends GuardNode {
467471 }
468472}
469473
470- private predicate comes_from_cfgnode ( Node node ) {
471- exists ( CfgNode first , Node second |
472- simpleLocalFlowStep ( first , second ) and
473- simpleLocalFlowStep * ( second , node )
474- )
475- }
476-
477- /**
478- * A data flow node that is a source of local flow. This includes things like
479- * - Expressions
480- * - Function parameters
481- */
482- class LocalSourceNode extends Node {
483- cached
484- LocalSourceNode ( ) {
485- not comes_from_cfgnode ( this ) and
486- not this instanceof ModuleVariableNode
487- or
488- this = any ( ModuleVariableNode mvn ) .getARead ( )
489- }
490-
491- /** Holds if this `LocalSourceNode` can flow to `nodeTo` in one or more local flow steps. */
492- pragma [ inline]
493- predicate flowsTo ( Node nodeTo ) { Cached:: hasLocalSource ( nodeTo , this ) }
494-
495- /**
496- * Gets a reference (read or write) of attribute `attrName` on this node.
497- */
498- AttrRef getAnAttributeReference ( string attrName ) { Cached:: namedAttrRef ( this , attrName , result ) }
499-
500- /**
501- * Gets a read of attribute `attrName` on this node.
502- */
503- AttrRead getAnAttributeRead ( string attrName ) { result = getAnAttributeReference ( attrName ) }
504-
505- /**
506- * Gets a reference (read or write) of any attribute on this node.
507- */
508- AttrRef getAnAttributeReference ( ) {
509- Cached:: namedAttrRef ( this , _, result )
510- or
511- Cached:: dynamicAttrRef ( this , result )
512- }
513-
514- /**
515- * Gets a read of any attribute on this node.
516- */
517- AttrRead getAnAttributeRead ( ) { result = getAnAttributeReference ( ) }
518-
519- /**
520- * Gets a call to this node.
521- */
522- CallCfgNode getACall ( ) { Cached:: call ( this , result ) }
523- }
524-
525- cached
526- private module Cached {
527- /**
528- * Holds if `source` is a `LocalSourceNode` that can reach `sink` via local flow steps.
529- *
530- * The slightly backwards parametering ordering is to force correct indexing.
531- */
532- cached
533- predicate hasLocalSource ( Node sink , LocalSourceNode source ) {
534- source = sink
535- or
536- exists ( Node second |
537- simpleLocalFlowStep ( source , second ) and
538- simpleLocalFlowStep * ( second , sink )
539- )
540- }
541-
542- /**
543- * Holds if `base` flows to the base of `ref` and `ref` has attribute name `attr`.
544- */
545- cached
546- predicate namedAttrRef ( LocalSourceNode base , string attr , AttrRef ref ) {
547- base .flowsTo ( ref .getObject ( ) ) and
548- ref .getAttributeName ( ) = attr
549- }
550-
551- /**
552- * Holds if `base` flows to the base of `ref` and `ref` has no known attribute name.
553- */
554- cached
555- predicate dynamicAttrRef ( LocalSourceNode base , AttrRef ref ) {
556- base .flowsTo ( ref .getObject ( ) ) and
557- not exists ( ref .getAttributeName ( ) )
558- }
559-
560- /**
561- * Holds if `func` flows to the callee of `call`.
562- */
563- cached
564- predicate call ( LocalSourceNode func , CallCfgNode call ) {
565- exists ( CfgNode n |
566- func .flowsTo ( n ) and
567- n = call .getFunction ( )
568- )
569- }
570- }
571-
572474/**
573475 * Algebraic datatype for tracking data content associated with values.
574476 * Content can be collection elements or object attributes.
0 commit comments