@@ -1066,7 +1066,7 @@ private module LocalFlowBigStep {
10661066 * Holds if `node` can be the first node in a maximal subsequence of local
10671067 * flow steps in a dataflow path.
10681068 */
1069- private predicate localFlowEntry ( Node node , Configuration config ) {
1069+ predicate localFlowEntry ( Node node , Configuration config ) {
10701070 nodeCand2 ( node , config ) and
10711071 (
10721072 config .isSource ( node ) or
@@ -1650,94 +1650,105 @@ private class AccessPathOption extends TAccessPathOption {
16501650 * Holds if `node` is reachable with access path `ap` from a source in
16511651 * the configuration `config`.
16521652 *
1653- * The Boolean `fromArg ` records whether the node is reached through an
1653+ * The call context `cc ` records whether the node is reached through an
16541654 * argument in a call, and if so, `argAp` records the access path of that
16551655 * argument.
16561656 */
16571657private predicate flowFwd (
1658- Node node , boolean fromArg , AccessPathOption argAp , AccessPathFront apf , AccessPath ap ,
1658+ Node node , CallContext cc , AccessPathOption argAp , AccessPathFront apf , AccessPath ap ,
16591659 Configuration config
16601660) {
1661- flowFwd0 ( node , fromArg , argAp , apf , ap , config ) and
1661+ flowFwd0 ( node , cc , argAp , apf , ap , config ) and
16621662 flowCand ( node , _, _, apf , config )
16631663}
16641664
16651665private predicate flowFwd0 (
1666- Node node , boolean fromArg , AccessPathOption argAp , AccessPathFront apf , AccessPath ap ,
1666+ Node node , CallContext cc , AccessPathOption argAp , AccessPathFront apf , AccessPath ap ,
16671667 Configuration config
16681668) {
16691669 flowCand ( node , _, _, _, config ) and
16701670 config .isSource ( node ) and
1671- fromArg = false and
1671+ cc instanceof CallContextAny and
16721672 argAp = TAccessPathNone ( ) and
16731673 ap = TNil ( getNodeType ( node ) ) and
16741674 apf = ap .( AccessPathNil ) .getFront ( )
16751675 or
16761676 flowCand ( node , _, _, _, unbind ( config ) ) and
16771677 (
1678- exists ( Node mid |
1679- flowFwd ( mid , fromArg , argAp , apf , ap , config ) and
1680- localFlowBigStep ( mid , node , true , _, config , _ )
1678+ exists ( Node mid , LocalCallContext localCC |
1679+ flowFwdLocalEntry ( mid , cc , argAp , apf , ap , localCC , config ) and
1680+ localFlowBigStep ( mid , node , true , _, config , localCC )
16811681 )
16821682 or
1683- exists ( Node mid , AccessPathNil nil |
1684- flowFwd ( mid , fromArg , argAp , _, nil , config ) and
1685- localFlowBigStep ( mid , node , false , apf , config , _ ) and
1683+ exists ( Node mid , AccessPathNil nil , LocalCallContext localCC |
1684+ flowFwdLocalEntry ( mid , cc , argAp , _, nil , localCC , config ) and
1685+ localFlowBigStep ( mid , node , false , apf , config , localCC ) and
16861686 apf = ap .( AccessPathNil ) .getFront ( )
16871687 )
16881688 or
16891689 exists ( Node mid |
16901690 flowFwd ( mid , _, _, apf , ap , config ) and
16911691 jumpStep ( mid , node , config ) and
1692- fromArg = false and
1692+ cc instanceof CallContextAny and
16931693 argAp = TAccessPathNone ( )
16941694 )
16951695 or
16961696 exists ( Node mid , AccessPathNil nil |
16971697 flowFwd ( mid , _, _, _, nil , config ) and
16981698 additionalJumpStep ( mid , node , config ) and
1699- fromArg = false and
1699+ cc instanceof CallContextAny and
17001700 argAp = TAccessPathNone ( ) and
17011701 ap = TNil ( getNodeType ( node ) ) and
17021702 apf = ap .( AccessPathNil ) .getFront ( )
17031703 )
17041704 )
17051705 or
17061706 // store
1707- exists ( TypedContent tc | flowFwdStore ( node , tc , pop ( tc , ap ) , apf , fromArg , argAp , config ) )
1707+ exists ( TypedContent tc | flowFwdStore ( node , tc , pop ( tc , ap ) , apf , cc , argAp , config ) )
17081708 or
17091709 // read
17101710 exists ( TypedContent tc |
1711- flowFwdRead ( node , _, push ( tc , ap ) , apf , fromArg , argAp , config ) and
1711+ flowFwdRead ( node , _, push ( tc , ap ) , apf , cc , argAp , config ) and
17121712 flowFwdConsCand ( tc , apf , ap , config )
17131713 )
17141714 or
17151715 // flow into a callable
1716- flowFwdIn ( _, node , _, _, apf , ap , config ) and
1717- fromArg = true and
1716+ flowFwdIn ( _, node , _, cc , _, apf , ap , config ) and
17181717 if flowCand ( node , true , _, apf , config )
17191718 then argAp = TAccessPathSome ( ap )
17201719 else argAp = TAccessPathNone ( )
17211720 or
17221721 // flow out of a callable
17231722 exists ( DataFlowCall call |
1724- flowFwdOut ( call , node , fromArg , argAp , apf , ap , config ) and
1725- fromArg = false
1723+ exists ( DataFlowCallable c |
1724+ flowFwdOut ( call , node , any ( CallContextNoCall innercc ) , c , argAp , apf , ap , config ) and
1725+ if reducedViableImplInReturn ( c , call ) then cc = TReturn ( c , call ) else cc = TAnyCallContext ( )
1726+ )
17261727 or
17271728 exists ( AccessPath argAp0 |
17281729 flowFwdOutFromArg ( call , node , argAp0 , apf , ap , config ) and
1729- flowFwdIsEntered ( call , fromArg , argAp , argAp0 , config )
1730+ flowFwdIsEntered ( call , cc , argAp , argAp0 , config )
17301731 )
17311732 )
17321733}
17331734
1735+ pragma [ nomagic]
1736+ private predicate flowFwdLocalEntry (
1737+ Node node , CallContext cc , AccessPathOption argAp , AccessPathFront apf , AccessPath ap ,
1738+ LocalCallContext localCC , Configuration config
1739+ ) {
1740+ flowFwd ( node , cc , argAp , apf , ap , config ) and
1741+ localFlowEntry ( node , config ) and
1742+ localCC = getLocalCallContext ( cc , node .getEnclosingCallable ( ) )
1743+ }
1744+
17341745pragma [ nomagic]
17351746private predicate flowFwdStore (
1736- Node node , TypedContent tc , AccessPath ap0 , AccessPathFront apf , boolean fromArg ,
1747+ Node node , TypedContent tc , AccessPath ap0 , AccessPathFront apf , CallContext cc ,
17371748 AccessPathOption argAp , Configuration config
17381749) {
17391750 exists ( Node mid , AccessPathFront apf0 |
1740- flowFwd ( mid , fromArg , argAp , apf0 , ap0 , config ) and
1751+ flowFwd ( mid , cc , argAp , apf0 , ap0 , config ) and
17411752 flowFwdStore0 ( mid , tc , node , apf0 , apf , config )
17421753 )
17431754}
@@ -1764,20 +1775,20 @@ private predicate flowFwdStore0(
17641775
17651776pragma [ nomagic]
17661777private predicate flowFwdRead0 (
1767- Node node1 , TypedContent tc , AccessPathFrontHead apf0 , AccessPath ap0 , Node node2 ,
1768- boolean fromArg , AccessPathOption argAp , Configuration config
1778+ Node node1 , TypedContent tc , AccessPathFrontHead apf0 , AccessPath ap0 , Node node2 , CallContext cc ,
1779+ AccessPathOption argAp , Configuration config
17691780) {
1770- flowFwd ( node1 , fromArg , argAp , apf0 , ap0 , config ) and
1781+ flowFwd ( node1 , cc , argAp , apf0 , ap0 , config ) and
17711782 readCandFwd ( node1 , tc , apf0 , node2 , config )
17721783}
17731784
17741785pragma [ nomagic]
17751786private predicate flowFwdRead (
1776- Node node , AccessPathFrontHead apf0 , AccessPath ap0 , AccessPathFront apf , boolean fromArg ,
1787+ Node node , AccessPathFrontHead apf0 , AccessPath ap0 , AccessPathFront apf , CallContext cc ,
17771788 AccessPathOption argAp , Configuration config
17781789) {
17791790 exists ( Node mid , TypedContent tc |
1780- flowFwdRead0 ( mid , tc , apf0 , ap0 , node , fromArg , argAp , config ) and
1791+ flowFwdRead0 ( mid , tc , apf0 , ap0 , node , cc , argAp , config ) and
17811792 flowCand ( node , _, _, apf , unbind ( config ) ) and
17821793 flowCandConsCand ( tc , apf , unbind ( config ) )
17831794 )
@@ -1795,27 +1806,36 @@ private predicate flowFwdConsCand(
17951806
17961807pragma [ nomagic]
17971808private predicate flowFwdIn (
1798- DataFlowCall call , ParameterNode p , boolean fromArg , AccessPathOption argAp , AccessPathFront apf ,
1799- AccessPath ap , Configuration config
1809+ DataFlowCall call , ParameterNode p , CallContext outercc , CallContext innercc ,
1810+ AccessPathOption argAp , AccessPathFront apf , AccessPath ap , Configuration config
18001811) {
1801- exists ( ArgumentNode arg , boolean allowsFieldFlow |
1802- flowFwd ( arg , fromArg , argAp , apf , ap , config ) and
1812+ exists ( ArgumentNode arg , boolean allowsFieldFlow , DataFlowCallable c |
1813+ flowFwd ( arg , outercc , argAp , apf , ap , config ) and
18031814 flowIntoCallNodeCand2 ( call , arg , p , allowsFieldFlow , config ) and
1804- flowCand ( p , _, _, _, unbind ( config ) )
1815+ c = p .getEnclosingCallable ( ) and
1816+ c = resolveCall ( call , outercc ) and
1817+ flowCand ( p , _, _, _, unbind ( config ) ) and
1818+ if recordDataFlowCallSite ( call , c ) then innercc = TSpecificCall ( call ) else innercc = TSomeCall ( )
18051819 |
18061820 ap instanceof AccessPathNil or allowsFieldFlow = true
18071821 )
18081822}
18091823
18101824pragma [ nomagic]
18111825private predicate flowFwdOut (
1812- DataFlowCall call , Node node , boolean fromArg , AccessPathOption argAp , AccessPathFront apf ,
1813- AccessPath ap , Configuration config
1826+ DataFlowCall call , Node node , CallContext innercc , DataFlowCallable innerc ,
1827+ AccessPathOption argAp , AccessPathFront apf , AccessPath ap , Configuration config
18141828) {
18151829 exists ( ReturnNodeExt ret , boolean allowsFieldFlow |
1816- flowFwd ( ret , fromArg , argAp , apf , ap , config ) and
1830+ flowFwd ( ret , innercc , argAp , apf , ap , config ) and
18171831 flowOutOfCallNodeCand2 ( call , ret , node , allowsFieldFlow , config ) and
1818- flowCand ( node , _, _, _, unbind ( config ) )
1832+ innerc = ret .getEnclosingCallable ( ) and
1833+ flowCand ( node , _, _, _, unbind ( config ) ) and
1834+ (
1835+ resolveReturn ( innercc , innerc , call )
1836+ or
1837+ innercc .( CallContextCall ) .matchesCall ( call )
1838+ )
18191839 |
18201840 ap instanceof AccessPathNil or allowsFieldFlow = true
18211841 )
@@ -1826,18 +1846,18 @@ private predicate flowFwdOutFromArg(
18261846 DataFlowCall call , Node node , AccessPath argAp , AccessPathFront apf , AccessPath ap ,
18271847 Configuration config
18281848) {
1829- flowFwdOut ( call , node , true , TAccessPathSome ( argAp ) , apf , ap , config )
1849+ flowFwdOut ( call , node , any ( CallContextCall ccc ) , _ , TAccessPathSome ( argAp ) , apf , ap , config )
18301850}
18311851
18321852/**
18331853 * Holds if an argument to `call` is reached in the flow covered by `flowFwd`.
18341854 */
18351855pragma [ nomagic]
18361856private predicate flowFwdIsEntered (
1837- DataFlowCall call , boolean fromArg , AccessPathOption argAp , AccessPath ap , Configuration config
1857+ DataFlowCall call , CallContext cc , AccessPathOption argAp , AccessPath ap , Configuration config
18381858) {
18391859 exists ( ParameterNode p , AccessPathFront apf |
1840- flowFwdIn ( call , p , fromArg , argAp , apf , ap , config ) and
1860+ flowFwdIn ( call , p , cc , _ , argAp , apf , ap , config ) and
18411861 flowCand ( p , true , TAccessPathFrontSome ( _) , apf , config )
18421862 )
18431863}
@@ -1920,7 +1940,7 @@ private predicate flow0(
19201940 // flow out of a callable
19211941 flowOut ( _, node , _, _, ap , config ) and
19221942 toReturn = true and
1923- if flowFwd ( node , true , TAccessPathSome ( _) , _, ap , config )
1943+ if flowFwd ( node , any ( CallContextCall ccc ) , TAccessPathSome ( _) , _, ap , config )
19241944 then returnAp = TAccessPathSome ( ap )
19251945 else returnAp = TAccessPathNone ( )
19261946}
@@ -2006,9 +2026,10 @@ private predicate flowIsReturned(
20062026 DataFlowCall call , boolean toReturn , AccessPathOption returnAp , AccessPath ap ,
20072027 Configuration config
20082028) {
2009- exists ( ReturnNodeExt ret |
2029+ exists ( ReturnNodeExt ret , CallContextCall ccc |
20102030 flowOut ( call , ret , toReturn , returnAp , ap , config ) and
2011- flowFwd ( ret , true , TAccessPathSome ( _) , _, ap , config )
2031+ flowFwd ( ret , ccc , TAccessPathSome ( _) , _, ap , config ) and
2032+ ccc .matchesCall ( call )
20122033 )
20132034}
20142035
@@ -2031,7 +2052,7 @@ private newtype TSummaryCtx =
20312052 exists ( ReturnNodeExt ret , Configuration config , AccessPath ap0 |
20322053 parameterFlow ( p , ap , ret .getEnclosingCallable ( ) , config ) and
20332054 flow ( ret , true , TAccessPathSome ( _) , ap0 , config ) and
2034- flowFwd ( ret , true , TAccessPathSome ( ap ) , _, ap0 , config )
2055+ flowFwd ( ret , any ( CallContextCall ccc ) , TAccessPathSome ( ap ) , _, ap0 , config )
20352056 )
20362057 }
20372058
@@ -2352,7 +2373,7 @@ private predicate pathOutOfCallable0(
23522373) {
23532374 pos = getReturnPosition ( mid .getNode ( ) ) and
23542375 innercc = mid .getCallContext ( ) and
2355- not innercc instanceof CallContextCall and
2376+ innercc instanceof CallContextNoCall and
23562377 ap = mid .getAp ( ) and
23572378 config = mid .getConfiguration ( )
23582379}
@@ -2867,7 +2888,7 @@ private module FlowExploration {
28672888 ) {
28682889 pos = getReturnPosition ( mid .getNode ( ) ) and
28692890 innercc = mid .getCallContext ( ) and
2870- not innercc instanceof CallContextCall and
2891+ innercc instanceof CallContextNoCall and
28712892 ap = mid .getAp ( ) and
28722893 config = mid .getConfiguration ( )
28732894 }
0 commit comments