Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 03ef9d0

Browse files
committed
Dataflow: Refactor call contexts.
1 parent dc2b2cc commit 03ef9d0

1 file changed

Lines changed: 97 additions & 46 deletions

File tree

java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll

Lines changed: 97 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)