@@ -57,8 +57,8 @@ abstract class Configuration extends string {
5757 /** Holds if data flow through `node` is prohibited. */
5858 predicate isBarrier ( Node node ) { none ( ) }
5959
60- /** Holds if data flow from `node1` to `node2` is prohibited . */
61- predicate isBarrierEdge ( Node node1 , Node node2 ) { none ( ) }
60+ /** DEPRECATED: override `isBarrier` instead . */
61+ deprecated predicate isBarrierEdge ( Node node1 , Node node2 ) { none ( ) }
6262
6363 /**
6464 * Holds if the additional flow step from `node1` to `node2` must be taken
@@ -103,6 +103,22 @@ abstract class Configuration extends string {
103103 deprecated predicate hasFlowBackward ( Node source , Node sink ) { hasFlow ( source , sink ) }
104104}
105105
106+ private predicate inBarrier ( Node node , Configuration config ) {
107+ config .isBarrier ( node ) and
108+ config .isSource ( node )
109+ }
110+
111+ private predicate outBarrier ( Node node , Configuration config ) {
112+ config .isBarrier ( node ) and
113+ config .isSink ( node )
114+ }
115+
116+ private predicate fullBarrier ( Node node , Configuration config ) {
117+ config .isBarrier ( node ) and
118+ not config .isSource ( node ) and
119+ not config .isSink ( node )
120+ }
121+
106122private class AdditionalFlowStepSource extends Node {
107123 AdditionalFlowStepSource ( ) { any ( Configuration c ) .isAdditionalFlowStep ( this , _) }
108124}
@@ -119,22 +135,46 @@ private predicate isAdditionalFlowStep(
119135 * Holds if data can flow in one local step from `node1` to `node2`.
120136 */
121137private predicate localFlowStep ( Node node1 , Node node2 , Configuration config ) {
122- localFlowStep ( node1 , node2 ) and not config .isBarrierEdge ( node1 , node2 )
138+ localFlowStep ( node1 , node2 ) and
139+ not outBarrier ( node1 , config ) and
140+ not inBarrier ( node2 , config ) and
141+ not fullBarrier ( node1 , config ) and
142+ not fullBarrier ( node2 , config )
123143}
124144
125145/**
126146 * Holds if the additional step from `node1` to `node2` does not jump between callables.
127147 */
128148private predicate additionalLocalFlowStep ( Node node1 , Node node2 , Configuration config ) {
129- isAdditionalFlowStep ( node1 , node2 , node2 .getEnclosingCallable ( ) , config )
149+ isAdditionalFlowStep ( node1 , node2 , node2 .getEnclosingCallable ( ) , config ) and
150+ not outBarrier ( node1 , config ) and
151+ not inBarrier ( node2 , config ) and
152+ not fullBarrier ( node1 , config ) and
153+ not fullBarrier ( node2 , config )
154+ }
155+
156+ /**
157+ * Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
158+ */
159+ private predicate jumpStep ( Node node1 , Node node2 , Configuration config ) {
160+ jumpStep ( node1 , node2 ) and
161+ not outBarrier ( node1 , config ) and
162+ not inBarrier ( node2 , config ) and
163+ not fullBarrier ( node1 , config ) and
164+ not fullBarrier ( node2 , config )
130165}
131166
132167/**
133168 * Holds if the additional step from `node1` to `node2` jumps between callables.
134169 */
135170private predicate additionalJumpStep ( Node node1 , Node node2 , Configuration config ) {
136- exists ( DataFlowCallable callable1 | isAdditionalFlowStep ( node1 , node2 , callable1 , config ) |
137- node2 .getEnclosingCallable ( ) != callable1
171+ exists ( DataFlowCallable callable1 |
172+ isAdditionalFlowStep ( node1 , node2 , callable1 , config ) and
173+ node2 .getEnclosingCallable ( ) != callable1 and
174+ not outBarrier ( node1 , config ) and
175+ not inBarrier ( node2 , config ) and
176+ not fullBarrier ( node1 , config ) and
177+ not fullBarrier ( node2 , config )
138178 )
139179}
140180
@@ -154,7 +194,7 @@ private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKind kind) {
154194 * ignoring call contexts.
155195 */
156196private predicate nodeCandFwd1 ( Node node , boolean stored , Configuration config ) {
157- not config . isBarrier ( node ) and
197+ not fullBarrier ( node , config ) and
158198 (
159199 config .isSource ( node ) and stored = false
160200 or
@@ -171,7 +211,7 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
171211 or
172212 exists ( Node mid |
173213 nodeCandFwd1 ( mid , stored , config ) and
174- jumpStep ( mid , node )
214+ jumpStep ( mid , node , config )
175215 )
176216 or
177217 exists ( Node mid |
@@ -185,15 +225,17 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
185225 useFieldFlow ( config ) and
186226 nodeCandFwd1 ( mid , _, config ) and
187227 store ( mid , _, node ) and
188- stored = true
228+ stored = true and
229+ not outBarrier ( mid , config )
189230 )
190231 or
191232 // read
192233 exists ( Node mid , Content f |
193234 nodeCandFwd1 ( mid , true , config ) and
194235 read ( mid , f , node ) and
195236 storeCandFwd1 ( f , unbind ( config ) ) and
196- ( stored = false or stored = true )
237+ ( stored = false or stored = true ) and
238+ not inBarrier ( node , config )
197239 )
198240 or
199241 // flow into a callable
@@ -223,7 +265,7 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
223265 */
224266private predicate storeCandFwd1 ( Content f , Configuration config ) {
225267 exists ( Node mid , Node node |
226- not config . isBarrier ( node ) and
268+ not fullBarrier ( node , config ) and
227269 useFieldFlow ( config ) and
228270 nodeCandFwd1 ( mid , _, config ) and
229271 store ( mid , f , node )
@@ -257,7 +299,7 @@ private predicate nodeCand1(Node node, boolean stored, Configuration config) {
257299 )
258300 or
259301 exists ( Node mid |
260- jumpStep ( node , mid ) and
302+ jumpStep ( node , mid , config ) and
261303 nodeCand1 ( mid , stored , config )
262304 )
263305 or
@@ -318,6 +360,11 @@ private predicate readCand1(Content f, Configuration config) {
318360 )
319361}
320362
363+ private predicate throughFlowNodeCand ( Node node , Configuration config ) {
364+ nodeCand1 ( node , false , config ) and
365+ not config .isBarrier ( node )
366+ }
367+
321368/**
322369 * Holds if there is a path from `p` to `node` in the same callable that is
323370 * part of a path from a source to a sink taking simple call contexts into
@@ -329,7 +376,7 @@ pragma[nomagic]
329376private predicate simpleParameterFlow (
330377 ParameterNode p , Node node , DataFlowType t , Configuration config
331378) {
332- nodeCand1 ( node , false , config ) and
379+ throughFlowNodeCand ( node , config ) and
333380 p = node and
334381 t = getErasedRepr ( node .getType ( ) ) and
335382 exists ( ReturnNode ret , ReturnKind kind |
@@ -338,37 +385,37 @@ private predicate simpleParameterFlow(
338385 not parameterValueFlowsThrough ( p , kind , _)
339386 )
340387 or
341- nodeCand1 ( node , false , unbind ( config ) ) and
388+ throughFlowNodeCand ( node , unbind ( config ) ) and
342389 exists ( Node mid |
343390 simpleParameterFlow ( p , mid , t , config ) and
344391 localFlowStep ( mid , node , config ) and
345392 compatibleTypes ( t , node .getType ( ) )
346393 )
347394 or
348- nodeCand1 ( node , false , unbind ( config ) ) and
395+ throughFlowNodeCand ( node , unbind ( config ) ) and
349396 exists ( Node mid |
350397 simpleParameterFlow ( p , mid , _, config ) and
351398 additionalLocalFlowStep ( mid , node , config ) and
352399 t = getErasedRepr ( node .getType ( ) )
353400 )
354401 or
355- nodeCand1 ( node , false , unbind ( config ) ) and
402+ throughFlowNodeCand ( node , unbind ( config ) ) and
356403 exists ( Node mid |
357404 simpleParameterFlow ( p , mid , t , config ) and
358405 localStoreReadStep ( mid , node ) and
359406 compatibleTypes ( t , node .getType ( ) )
360407 )
361408 or
362409 // value flow through a callable
363- nodeCand1 ( node , false , unbind ( config ) ) and
410+ throughFlowNodeCand ( node , unbind ( config ) ) and
364411 exists ( Node arg |
365412 simpleParameterFlow ( p , arg , t , config ) and
366413 argumentValueFlowsThrough ( arg , node , _) and
367414 compatibleTypes ( t , node .getType ( ) )
368415 )
369416 or
370417 // flow through a callable
371- nodeCand1 ( node , false , unbind ( config ) ) and
418+ throughFlowNodeCand ( node , unbind ( config ) ) and
372419 exists ( Node arg |
373420 simpleParameterFlow ( p , arg , _, config ) and
374421 simpleArgumentFlowsThrough ( arg , node , t , config )
@@ -380,6 +427,7 @@ private predicate simpleArgumentFlowsThrough0(
380427 DataFlowCall call , ArgumentNode arg , ReturnKind kind , DataFlowType t , Configuration config
381428) {
382429 nodeCand1 ( arg , false , unbind ( config ) ) and
430+ not outBarrier ( arg , config ) and
383431 exists ( ParameterNode p , ReturnNode ret |
384432 simpleParameterFlow ( p , ret , t , config ) and
385433 kind = ret .getKind ( ) and
@@ -399,6 +447,7 @@ private predicate simpleArgumentFlowsThrough(
399447) {
400448 exists ( DataFlowCall call , ReturnKind kind |
401449 nodeCand1 ( out , false , unbind ( config ) ) and
450+ not inBarrier ( out , config ) and
402451 simpleArgumentFlowsThrough0 ( call , arg , kind , t , config ) and
403452 out = getAnOutNode ( call , kind )
404453 )
@@ -440,6 +489,8 @@ private predicate additionalLocalFlowStepOrFlowThroughCallable(
440489private predicate flowOutOfCallable ( Node node1 , Node node2 , Configuration config ) {
441490 nodeCand1 ( node1 , _, unbind ( config ) ) and
442491 nodeCand1 ( node2 , _, config ) and
492+ not outBarrier ( node1 , config ) and
493+ not inBarrier ( node2 , config ) and
443494 (
444495 // flow out of an argument
445496 exists ( ParameterNode p |
@@ -462,7 +513,9 @@ private predicate flowOutOfCallable(Node node1, Node node2, Configuration config
462513private predicate flowIntoCallable ( Node node1 , Node node2 , Configuration config ) {
463514 viableParamArg ( _, node2 , node1 ) and
464515 nodeCand1 ( node1 , _, unbind ( config ) ) and
465- nodeCand1 ( node2 , _, config )
516+ nodeCand1 ( node2 , _, config ) and
517+ not outBarrier ( node1 , config ) and
518+ not inBarrier ( node2 , config )
466519}
467520
468521/**
@@ -546,7 +599,7 @@ private predicate nodeCandFwd2(Node node, boolean fromArg, boolean stored, Confi
546599 or
547600 exists ( Node mid |
548601 nodeCandFwd2 ( mid , _, stored , config ) and
549- jumpStep ( mid , node ) and
602+ jumpStep ( mid , node , config ) and
550603 fromArg = false
551604 )
552605 or
@@ -626,7 +679,7 @@ private predicate nodeCand2(Node node, boolean toReturn, boolean stored, Configu
626679 )
627680 or
628681 exists ( Node mid |
629- jumpStep ( node , mid ) and
682+ jumpStep ( node , mid , config ) and
630683 nodeCand2 ( mid , _, stored , config ) and
631684 toReturn = false
632685 )
@@ -714,7 +767,7 @@ private predicate localFlowEntry(Node node, Configuration config) {
714767 nodeCand ( node , config ) and
715768 (
716769 config .isSource ( node ) or
717- jumpStep ( _, node ) or
770+ jumpStep ( _, node , config ) or
718771 additionalJumpStep ( _, node , config ) or
719772 node instanceof ParameterNode or
720773 node instanceof OutNode or
@@ -730,7 +783,7 @@ private predicate localFlowEntry(Node node, Configuration config) {
730783 */
731784private predicate localFlowExit ( Node node , Configuration config ) {
732785 exists ( Node next | nodeCand ( next , config ) |
733- jumpStep ( node , next ) or
786+ jumpStep ( node , next , config ) or
734787 additionalJumpStep ( node , next , config ) or
735788 flowIntoCallable ( node , next , config ) or
736789 flowOutOfCallable ( node , next , config ) or
@@ -882,7 +935,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
882935 or
883936 exists ( Node mid |
884937 flowCandFwd ( mid , _, apf , config ) and
885- jumpStep ( mid , node ) and
938+ jumpStep ( mid , node , config ) and
886939 fromArg = false
887940 )
888941 or
@@ -973,7 +1026,7 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
9731026 )
9741027 or
9751028 exists ( Node mid |
976- jumpStep ( node , mid ) and
1029+ jumpStep ( node , mid , config ) and
9771030 flowCand ( mid , _, apf , config ) and
9781031 toReturn = false
9791032 )
@@ -1154,7 +1207,7 @@ private predicate flowFwd0(
11541207 or
11551208 exists ( Node mid |
11561209 flowFwd ( mid , _, apf , ap , config ) and
1157- jumpStep ( mid , node ) and
1210+ jumpStep ( mid , node , config ) and
11581211 fromArg = false
11591212 )
11601213 or
@@ -1263,7 +1316,7 @@ private predicate flow0(Node node, boolean toReturn, AccessPath ap, Configuratio
12631316 )
12641317 or
12651318 exists ( Node mid |
1266- jumpStep ( node , mid ) and
1319+ jumpStep ( node , mid , config ) and
12671320 flow ( mid , _, ap , config ) and
12681321 toReturn = false
12691322 )
@@ -1518,7 +1571,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPat
15181571 mid .getAp ( ) instanceof AccessPathNil and
15191572 ap = node .( AccessPathNilNode ) .getAp ( )
15201573 or
1521- jumpStep ( mid .getNode ( ) , node ) and
1574+ jumpStep ( mid .getNode ( ) , node , mid . getConfiguration ( ) ) and
15221575 cc instanceof CallContextAny and
15231576 ap = mid .getAp ( )
15241577 or
0 commit comments