@@ -710,6 +710,32 @@ module DataFlow {
710710 override CIL:: Expr getArgument ( int i ) { result = call .getArgument ( i ) }
711711 }
712712
713+ private ControlFlowElement getAScope ( boolean exactScope ) {
714+ exists ( ExprStepConfiguration c |
715+ c .stepsToExpr ( _, _, result , exactScope , _) or
716+ c .stepsToDefinition ( _, _, result , exactScope , _)
717+ )
718+ }
719+
720+ private ControlFlowElement getANonExactScopeChild ( ControlFlowElement scope ) {
721+ scope = getAScope ( false ) and
722+ result = scope
723+ or
724+ result = getANonExactScopeChild ( scope ) .getAChild ( )
725+ }
726+
727+ pragma [ noinline]
728+ private ControlFlow:: BasicBlock getABasicBlockInScope (
729+ ControlFlowElement scope , boolean exactScope
730+ ) {
731+ result .getANode ( ) .getElement ( ) = getANonExactScopeChild ( scope ) and
732+ exactScope = false
733+ or
734+ scope = getAScope ( true ) and
735+ result .getANode ( ) .getElement ( ) = scope and
736+ exactScope = true
737+ }
738+
713739 /**
714740 * A helper class for defining expression-based data flow steps, while properly
715741 * taking control flow into account.
@@ -745,6 +771,7 @@ module DataFlow {
745771 none ( )
746772 }
747773
774+ pragma [ nomagic]
748775 private predicate reachesBasicBlockExprRec (
749776 Expr exprFrom , Expr exprTo , ControlFlowElement scope , boolean exactScope ,
750777 boolean isSuccessor , ControlFlow:: Nodes:: ElementNode cfnFrom , ControlFlow:: BasicBlock bb
@@ -769,20 +796,17 @@ module DataFlow {
769796 cfnFrom = exprFrom .getAControlFlowNode ( ) and
770797 bb = cfnFrom .getBasicBlock ( )
771798 or
799+ this .stepsToExpr ( exprFrom , exprTo , scope , exactScope , isSuccessor ) and
772800 exists ( ControlFlowElement scope0 , boolean exactScope0 |
773801 this
774802 .reachesBasicBlockExprRec ( exprFrom , exprTo , scope0 , exactScope0 , isSuccessor , cfnFrom ,
775- bb ) and
776- this .stepsToExpr ( exprFrom , exprTo , scope , exactScope , isSuccessor )
803+ bb )
777804 |
778- exactScope0 = false and
779- bb .getANode ( ) .getElement ( ) = scope0 .getAChild * ( )
780- or
781- exactScope0 = true and
782- bb .getANode ( ) .getElement ( ) = scope0
805+ bb = getABasicBlockInScope ( scope0 , exactScope0 )
783806 )
784807 }
785808
809+ pragma [ nomagic]
786810 private predicate reachesBasicBlockDefinitionRec (
787811 Expr exprFrom , AssignableDefinition defTo , ControlFlowElement scope , boolean exactScope ,
788812 boolean isSuccessor , ControlFlow:: Nodes:: ElementNode cfnFrom , ControlFlow:: BasicBlock bb
@@ -809,17 +833,13 @@ module DataFlow {
809833 cfnFrom = exprFrom .getAControlFlowNode ( ) and
810834 bb = cfnFrom .getBasicBlock ( )
811835 or
836+ this .stepsToDefinition ( exprFrom , defTo , scope , exactScope , isSuccessor ) and
812837 exists ( ControlFlowElement scope0 , boolean exactScope0 |
813838 this
814839 .reachesBasicBlockDefinitionRec ( exprFrom , defTo , scope0 , exactScope0 , isSuccessor ,
815- cfnFrom , bb ) and
816- this .stepsToDefinition ( exprFrom , defTo , scope , exactScope , isSuccessor )
840+ cfnFrom , bb )
817841 |
818- exactScope0 = false and
819- bb .getANode ( ) .getElement ( ) = scope0 .getAChild * ( )
820- or
821- exactScope0 = true and
822- bb .getANode ( ) .getElement ( ) = scope0
842+ bb = getABasicBlockInScope ( scope0 , exactScope0 )
823843 )
824844 }
825845
@@ -1030,13 +1050,20 @@ module DataFlow {
10301050 )
10311051 }
10321052
1033- private Expr getALibraryFlowParent ( Expr exprFrom , Expr exprTo , boolean preservesValue ) {
1053+ private Expr getALibraryFlowParentFrom ( Expr exprFrom , Expr exprTo , boolean preservesValue ) {
10341054 libraryFlow ( exprFrom , exprTo , preservesValue ) and
10351055 result = exprFrom
10361056 or
1037- exists ( Expr mid | mid = getALibraryFlowParent ( exprFrom , exprTo , preservesValue ) |
1057+ result .getAChildExpr ( ) = getALibraryFlowParentFrom ( exprFrom , exprTo , preservesValue )
1058+ }
1059+
1060+ private Expr getALibraryFlowParentTo ( Expr exprFrom , Expr exprTo , boolean preservesValue ) {
1061+ libraryFlow ( exprFrom , exprTo , preservesValue ) and
1062+ result = exprTo
1063+ or
1064+ exists ( Expr mid | mid = getALibraryFlowParentTo ( exprFrom , exprTo , preservesValue ) |
10381065 result .getAChildExpr ( ) = mid and
1039- not mid . getAChildExpr * ( ) = exprTo
1066+ not mid = getALibraryFlowParentFrom ( exprFrom , exprTo , preservesValue )
10401067 )
10411068 }
10421069
@@ -1045,8 +1072,8 @@ module DataFlow {
10451072 ) {
10461073 // To not pollute the definitions in `LibraryTypeDataFlow.qll` with syntactic scope,
10471074 // simply use the nearest common parent expression for `exprFrom` and `exprTo`
1048- scope = getALibraryFlowParent ( exprFrom , exprTo , preservesValue ) and
1049- scope . getAChildExpr * ( ) = exprTo and
1075+ scope = getALibraryFlowParentFrom ( exprFrom , exprTo , preservesValue ) and
1076+ scope = getALibraryFlowParentTo ( exprFrom , exprTo , preservesValue ) and
10501077 // Similarly, for simplicity allow following both forwards and backwards edges from
10511078 // `exprFrom` to `exprTo`
10521079 ( isSuccessor = true or isSuccessor = false )
@@ -1220,6 +1247,12 @@ module DataFlow {
12201247 LocalFlow:: localFlowStep ( pred , succ , config )
12211248 }
12221249
1250+ pragma [ noinline]
1251+ private predicate jumpStepCand1 ( Node pred , Node succ , Configuration config ) {
1252+ nodeCand1 ( succ , config ) and
1253+ jumpStep ( pred , succ )
1254+ }
1255+
12231256 pragma [ noinline]
12241257 predicate flowIntoCallableStepCand1 (
12251258 CallNode call , ArgumentNode arg , ParameterNode p , Configuration config
@@ -1249,9 +1282,8 @@ module DataFlow {
12491282 localFlowStepCand1 ( mid , node , config )
12501283 )
12511284 or
1252- nodeCand1 ( node , config ) and
12531285 exists ( Node mid | nodeCandFwd2 ( mid , _, config ) |
1254- jumpStep ( mid , node ) and
1286+ jumpStepCand1 ( mid , node , config ) and
12551287 fromArg = false
12561288 )
12571289 or
0 commit comments