@@ -764,8 +764,25 @@ private module Stage2 {
764764
765765 class Cc = boolean ;
766766
767+ class CcCall extends Cc {
768+ CcCall ( ) { this = true }
769+ }
770+
771+ class CcNoCall extends Cc {
772+ CcNoCall ( ) { this = false }
773+ }
774+
767775 Cc ccAny ( ) { result = false }
768776
777+ bindingset [ call, c, outercc]
778+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) { any ( ) }
779+
780+ bindingset [ call, c]
781+ CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call ) { any ( ) }
782+
783+ bindingset [ innercc, inner, call]
784+ predicate checkCallContextReturn ( Cc innercc , DataFlowCallable inner , DataFlowCall call ) { any ( ) }
785+
769786 predicate flowCand ( Node node , ApApprox apa , Configuration config ) {
770787 Stage1:: revFlow ( node , config ) and exists ( apa )
771788 }
@@ -828,14 +845,12 @@ private module Stage2 {
828845 )
829846 or
830847 // flow into a callable
831- fwdFlowIn ( _, node , _, _, ap , config ) and
832- cc = true and
848+ fwdFlowIn ( _, node , _, cc , _, ap , config ) and
833849 if parameterThroughFlowNodeCand1 ( node , config ) then argAp = apSome ( ap ) else argAp = apNone ( )
834850 or
835851 // flow out of a callable
836852 exists ( DataFlowCall call |
837- fwdFlowOut ( call , node , cc , argAp , ap , config ) and
838- cc = ccAny ( )
853+ fwdFlowOut ( call , node , any ( CcNoCall innercc ) , cc , argAp , ap , config )
839854 or
840855 exists ( Ap argAp0 |
841856 fwdFlowOutFromArg ( call , node , argAp0 , ap , config ) and
@@ -878,23 +893,28 @@ private module Stage2 {
878893
879894 pragma [ nomagic]
880895 private predicate fwdFlowIn (
881- DataFlowCall call , ParameterNode p , Cc cc , ApOption argAp , Ap ap , Configuration config
896+ DataFlowCall call , ParameterNode p , Cc outercc , Cc innercc , ApOption argAp , Ap ap ,
897+ Configuration config
882898 ) {
883899 exists ( ArgumentNode arg , boolean allowsFieldFlow |
884- fwdFlow ( arg , cc , argAp , ap , config ) and
885- flowIntoCallNodeCand1 ( call , arg , p , allowsFieldFlow , config )
900+ fwdFlow ( arg , outercc , argAp , ap , config ) and
901+ flowIntoCallNodeCand1 ( call , arg , p , allowsFieldFlow , config ) and
902+ innercc = getCallContextCall ( call , p .getEnclosingCallable ( ) , outercc )
886903 |
887904 ap instanceof ApNil or allowsFieldFlow = true
888905 )
889906 }
890907
891908 pragma [ nomagic]
892909 private predicate fwdFlowOut (
893- DataFlowCall call , Node node , Cc cc , ApOption argAp , Ap ap , Configuration config
910+ DataFlowCall call , Node node , Cc innercc , Cc ccOut , ApOption argAp , Ap ap , Configuration config
894911 ) {
895- exists ( ReturnNodeExt ret , boolean allowsFieldFlow |
896- fwdFlow ( ret , cc , argAp , ap , config ) and
897- flowOutOfCallNodeCand1 ( call , ret , node , allowsFieldFlow , config )
912+ exists ( ReturnNodeExt ret , boolean allowsFieldFlow , DataFlowCallable inner |
913+ fwdFlow ( ret , innercc , argAp , ap , config ) and
914+ flowOutOfCallNodeCand1 ( call , ret , node , allowsFieldFlow , config ) and
915+ inner = ret .getEnclosingCallable ( ) and
916+ checkCallContextReturn ( innercc , inner , call ) and
917+ ccOut = getCallContextReturn ( inner , call )
898918 |
899919 ap instanceof ApNil or allowsFieldFlow = true
900920 )
@@ -904,7 +924,7 @@ private module Stage2 {
904924 private predicate fwdFlowOutFromArg (
905925 DataFlowCall call , Node node , Ap argAp , Ap ap , Configuration config
906926 ) {
907- fwdFlowOut ( call , node , true , apSome ( argAp ) , ap , config )
927+ fwdFlowOut ( call , node , any ( CcCall ccc ) , _ , apSome ( argAp ) , ap , config )
908928 }
909929
910930 /**
@@ -915,7 +935,7 @@ private module Stage2 {
915935 DataFlowCall call , Cc cc , ApOption argAp , Ap ap , Configuration config
916936 ) {
917937 exists ( ParameterNode p |
918- fwdFlowIn ( call , p , cc , argAp , ap , config ) and
938+ fwdFlowIn ( call , p , cc , _ , argAp , ap , config ) and
919939 parameterThroughFlowNodeCand1 ( p , config )
920940 )
921941 }
@@ -1288,8 +1308,25 @@ private module Stage3 {
12881308
12891309 class Cc = boolean ;
12901310
1311+ class CcCall extends Cc {
1312+ CcCall ( ) { this = true }
1313+ }
1314+
1315+ class CcNoCall extends Cc {
1316+ CcNoCall ( ) { this = false }
1317+ }
1318+
12911319 Cc ccAny ( ) { result = false }
12921320
1321+ bindingset [ call, c, outercc]
1322+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) { any ( ) }
1323+
1324+ bindingset [ call, c]
1325+ CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call ) { any ( ) }
1326+
1327+ bindingset [ innercc, inner, call]
1328+ predicate checkCallContextReturn ( Cc innercc , DataFlowCallable inner , DataFlowCall call ) { any ( ) }
1329+
12931330 predicate flowCand ( Node node , ApApprox apa , Configuration config ) {
12941331 Stage2:: revFlow ( node , _, _, apa , config )
12951332 }
@@ -1360,16 +1397,14 @@ private module Stage3 {
13601397 )
13611398 or
13621399 // flow into a callable
1363- fwdFlowIn ( _, node , _, _, ap , config ) and
1364- cc = true and
1400+ fwdFlowIn ( _, node , _, cc , _, ap , config ) and
13651401 if Stage2:: revFlow ( node , true , _, unbindBool ( ap .toBoolNonEmpty ( ) ) , config )
13661402 then argAp = apSome ( ap )
13671403 else argAp = apNone ( )
13681404 or
13691405 // flow out of a callable
13701406 exists ( DataFlowCall call |
1371- fwdFlowOut ( call , node , cc , argAp , ap , config ) and
1372- cc = ccAny ( )
1407+ fwdFlowOut ( call , node , any ( CcNoCall innercc ) , cc , argAp , ap , config )
13731408 or
13741409 exists ( Ap argAp0 |
13751410 fwdFlowOutFromArg ( call , node , argAp0 , ap , config ) and
@@ -1411,23 +1446,28 @@ private module Stage3 {
14111446
14121447 pragma [ nomagic]
14131448 private predicate fwdFlowIn (
1414- DataFlowCall call , ParameterNode p , Cc cc , ApOption argAp , Ap ap , Configuration config
1449+ DataFlowCall call , ParameterNode p , Cc outercc , Cc innercc , ApOption argAp , Ap ap ,
1450+ Configuration config
14151451 ) {
14161452 exists ( ArgumentNode arg , boolean allowsFieldFlow |
1417- fwdFlow ( arg , cc , argAp , ap , config ) and
1418- flowIntoCallNodeCand2 ( call , arg , p , allowsFieldFlow , config )
1453+ fwdFlow ( arg , outercc , argAp , ap , config ) and
1454+ flowIntoCallNodeCand2 ( call , arg , p , allowsFieldFlow , config ) and
1455+ innercc = getCallContextCall ( call , p .getEnclosingCallable ( ) , outercc )
14191456 |
14201457 ap instanceof ApNil or allowsFieldFlow = true
14211458 )
14221459 }
14231460
14241461 pragma [ nomagic]
14251462 private predicate fwdFlowOut (
1426- DataFlowCall call , Node node , Cc cc , ApOption argAp , Ap ap , Configuration config
1463+ DataFlowCall call , Node node , Cc innercc , Cc ccOut , ApOption argAp , Ap ap , Configuration config
14271464 ) {
1428- exists ( ReturnNodeExt ret , boolean allowsFieldFlow |
1429- fwdFlow ( ret , cc , argAp , ap , config ) and
1430- flowOutOfCallNodeCand2 ( call , ret , node , allowsFieldFlow , config )
1465+ exists ( ReturnNodeExt ret , boolean allowsFieldFlow , DataFlowCallable inner |
1466+ fwdFlow ( ret , innercc , argAp , ap , config ) and
1467+ flowOutOfCallNodeCand2 ( call , ret , node , allowsFieldFlow , config ) and
1468+ inner = ret .getEnclosingCallable ( ) and
1469+ checkCallContextReturn ( innercc , inner , call ) and
1470+ ccOut = getCallContextReturn ( inner , call )
14311471 |
14321472 ap instanceof ApNil or allowsFieldFlow = true
14331473 )
@@ -1437,7 +1477,7 @@ private module Stage3 {
14371477 private predicate fwdFlowOutFromArg (
14381478 DataFlowCall call , Node node , Ap argAp , Ap ap , Configuration config
14391479 ) {
1440- fwdFlowOut ( call , node , true , apSome ( argAp ) , ap , config )
1480+ fwdFlowOut ( call , node , any ( CcCall ccc ) , _ , apSome ( argAp ) , ap , config )
14411481 }
14421482
14431483 /**
@@ -1448,7 +1488,7 @@ private module Stage3 {
14481488 DataFlowCall call , Cc cc , ApOption argAp , Ap ap , Configuration config
14491489 ) {
14501490 exists ( ParameterNode p |
1451- fwdFlowIn ( call , p , cc , argAp , ap , config ) and
1491+ fwdFlowIn ( call , p , cc , _ , argAp , ap , config ) and
14521492 Stage2:: revFlow ( p , true , TBooleanSome ( _) , unbindBool ( ap .toBoolNonEmpty ( ) ) , config )
14531493 )
14541494 }
@@ -1857,8 +1897,30 @@ private module Stage4 {
18571897
18581898 class Cc = CallContext ;
18591899
1900+ class CcCall = CallContextCall ;
1901+
1902+ class CcNoCall = CallContextNoCall ;
1903+
18601904 Cc ccAny ( ) { result instanceof CallContextAny }
18611905
1906+ bindingset [ call, c, outercc]
1907+ CcCall getCallContextCall ( DataFlowCall call , DataFlowCallable c , Cc outercc ) {
1908+ c = resolveCall ( call , outercc ) and
1909+ if recordDataFlowCallSite ( call , c ) then result = TSpecificCall ( call ) else result = TSomeCall ( )
1910+ }
1911+
1912+ bindingset [ call, c]
1913+ CcNoCall getCallContextReturn ( DataFlowCallable c , DataFlowCall call ) {
1914+ if reducedViableImplInReturn ( c , call ) then result = TReturn ( c , call ) else result = ccAny ( )
1915+ }
1916+
1917+ bindingset [ innercc, inner, call]
1918+ predicate checkCallContextReturn ( Cc innercc , DataFlowCallable inner , DataFlowCall call ) {
1919+ resolveReturn ( innercc , inner , call )
1920+ or
1921+ innercc .( CallContextCall ) .matchesCall ( call )
1922+ }
1923+
18621924 predicate flowCand ( Node node , ApApprox apa , Configuration config ) {
18631925 Stage3:: revFlow ( node , _, _, apa , config )
18641926 }
@@ -1934,10 +1996,7 @@ private module Stage4 {
19341996 or
19351997 // flow out of a callable
19361998 exists ( DataFlowCall call |
1937- exists ( DataFlowCallable c |
1938- fwdFlowOut ( call , node , any ( CallContextNoCall innercc ) , c , argAp , ap , config ) and
1939- if reducedViableImplInReturn ( c , call ) then cc = TReturn ( c , call ) else cc = TAnyCallContext ( )
1940- )
1999+ fwdFlowOut ( call , node , any ( CcNoCall innercc ) , cc , argAp , ap , config )
19412000 or
19422001 exists ( Ap argAp0 |
19432002 fwdFlowOutFromArg ( call , node , argAp0 , ap , config ) and
@@ -2009,35 +2068,27 @@ private module Stage4 {
20092068 DataFlowCall call , ParameterNode p , Cc outercc , Cc innercc , ApOption argAp , Ap ap ,
20102069 Configuration config
20112070 ) {
2012- exists ( ArgumentNode arg , boolean allowsFieldFlow , DataFlowCallable c |
2071+ exists ( ArgumentNode arg , boolean allowsFieldFlow |
20132072 fwdFlow ( arg , outercc , argAp , ap , config ) and
20142073 flowIntoCallNodeCand2 ( call , arg , p , allowsFieldFlow , config ) and
2015- c = p .getEnclosingCallable ( ) and
2016- c = resolveCall ( call , outercc ) and
20172074 flowCand ( p , _, unbind ( config ) ) and
2018- if recordDataFlowCallSite ( call , c )
2019- then innercc = TSpecificCall ( call )
2020- else innercc = TSomeCall ( )
2075+ innercc = getCallContextCall ( call , p .getEnclosingCallable ( ) , outercc )
20212076 |
20222077 ap instanceof ApNil or allowsFieldFlow = true
20232078 )
20242079 }
20252080
20262081 pragma [ nomagic]
20272082 private predicate fwdFlowOut (
2028- DataFlowCall call , Node node , Cc innercc , DataFlowCallable innerc , ApOption argAp , Ap ap ,
2029- Configuration config
2083+ DataFlowCall call , Node node , Cc innercc , Cc ccOut , ApOption argAp , Ap ap , Configuration config
20302084 ) {
2031- exists ( ReturnNodeExt ret , boolean allowsFieldFlow |
2085+ exists ( ReturnNodeExt ret , boolean allowsFieldFlow , DataFlowCallable inner |
20322086 fwdFlow ( ret , innercc , argAp , ap , config ) and
20332087 flowOutOfCallNodeCand2 ( call , ret , node , allowsFieldFlow , config ) and
2034- innerc = ret .getEnclosingCallable ( ) and
2088+ inner = ret .getEnclosingCallable ( ) and
20352089 flowCand ( node , _, unbind ( config ) ) and
2036- (
2037- resolveReturn ( innercc , innerc , call )
2038- or
2039- innercc .( CallContextCall ) .matchesCall ( call )
2040- )
2090+ checkCallContextReturn ( innercc , inner , call ) and
2091+ ccOut = getCallContextReturn ( inner , call )
20412092 |
20422093 ap instanceof ApNil or allowsFieldFlow = true
20432094 )
@@ -2047,7 +2098,7 @@ private module Stage4 {
20472098 private predicate fwdFlowOutFromArg (
20482099 DataFlowCall call , Node node , Ap argAp , Ap ap , Configuration config
20492100 ) {
2050- fwdFlowOut ( call , node , any ( CallContextCall ccc ) , _, apSome ( argAp ) , ap , config )
2101+ fwdFlowOut ( call , node , any ( CcCall ccc ) , _, apSome ( argAp ) , ap , config )
20512102 }
20522103
20532104 /**
0 commit comments