Skip to content

Commit 488a4ed

Browse files
committed
Data flow: Inline getAStoreContent up-front
1 parent b033f10 commit 488a4ed

File tree

2 files changed

+58
-80
lines changed

2 files changed

+58
-80
lines changed

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImpl.qll

Lines changed: 33 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -516,25 +516,12 @@ private predicate clearsContentEx(NodeEx n, Content c) {
516516
}
517517

518518
pragma[nomagic]
519-
private predicate storeSet(
520-
NodeEx node1, ContentSet c, NodeEx node2, DataFlowType contentType, DataFlowType containerType,
521-
Configuration config
522-
) {
523-
storeSet(node1.asNode(), c, node2.asNode(), contentType, containerType) and
524-
stepFilter(node1, node2, config) and
525-
read(_, c.getAStoreContent(), _, config)
526-
}
527-
528-
// inline to reduce fan-out via `getAStoreContent`
529-
pragma[inline]
530519
private predicate store(
531-
NodeEx node1, Content c, NodeEx node2, DataFlowType contentType, DataFlowType containerType,
532-
Configuration config
520+
NodeEx node1, TypedContent tc, NodeEx node2, DataFlowType contentType, Configuration config
533521
) {
534-
exists(ContentSet cs |
535-
storeSet(node1, cs, node2, contentType, containerType, config) and
536-
c = cs.getAStoreContent()
537-
)
522+
store(node1.asNode(), tc, node2.asNode(), contentType) and
523+
read(_, tc.getContent(), _, config) and
524+
stepFilter(node1, node2, config)
538525
}
539526

540527
pragma[nomagic]
@@ -602,7 +589,7 @@ private module Stage1 {
602589
exists(NodeEx mid |
603590
useFieldFlow(config) and
604591
fwdFlow(mid, cc, config) and
605-
storeSet(mid, _, node, _, _, config)
592+
store(mid, _, node, _, config)
606593
)
607594
or
608595
// read
@@ -644,11 +631,12 @@ private module Stage1 {
644631
*/
645632
pragma[nomagic]
646633
private predicate fwdFlowConsCand(Content c, Configuration config) {
647-
exists(NodeEx mid, NodeEx node |
634+
exists(NodeEx mid, NodeEx node, TypedContent tc |
648635
not fullBarrier(node, config) and
649636
useFieldFlow(config) and
650637
fwdFlow(mid, _, config) and
651-
store(mid, c, node, _, _, config)
638+
store(mid, tc, node, _, config) and
639+
c = tc.getContent()
652640
)
653641
}
654642

@@ -748,9 +736,9 @@ private module Stage1 {
748736
)
749737
or
750738
// store
751-
exists(ContentSet c |
752-
revFlowStoreSet(c, node, toReturn, config) and
753-
revFlowConsCandSet(c, config)
739+
exists(Content c |
740+
revFlowStore(c, node, toReturn, config) and
741+
revFlowConsCand(c, config)
754742
)
755743
or
756744
// read
@@ -791,18 +779,12 @@ private module Stage1 {
791779
}
792780

793781
pragma[nomagic]
794-
private predicate revFlowConsCandSet(ContentSet c, Configuration config) {
795-
revFlowConsCand(c.getAStoreContent(), config)
796-
}
797-
798-
pragma[nomagic]
799-
private predicate revFlowStoreSet(
800-
ContentSet c, NodeEx node, boolean toReturn, Configuration config
801-
) {
802-
exists(NodeEx mid |
782+
private predicate revFlowStore(Content c, NodeEx node, boolean toReturn, Configuration config) {
783+
exists(NodeEx mid, TypedContent tc |
803784
revFlow(mid, toReturn, pragma[only_bind_into](config)) and
804-
fwdFlowConsCandSet(c, _, pragma[only_bind_into](config)) and
805-
storeSet(node, c, mid, _, _, config)
785+
fwdFlowConsCandSet(_, c, pragma[only_bind_into](config)) and
786+
store(node, tc, mid, _, config) and
787+
c = tc.getContent()
806788
)
807789
}
808790

@@ -812,11 +794,8 @@ private module Stage1 {
812794
*/
813795
pragma[nomagic]
814796
private predicate revFlowIsReadAndStored(Content c, Configuration conf) {
815-
revFlowConsCand(c, pragma[only_bind_into](conf)) and
816-
exists(ContentSet cs |
817-
revFlowStoreSet(cs, _, _, pragma[only_bind_into](conf)) and
818-
c = cs.getAStoreContent()
819-
)
797+
revFlowConsCand(c, conf) and
798+
revFlowStore(c, _, _, conf)
820799
}
821800

822801
pragma[nomagic]
@@ -901,11 +880,11 @@ private module Stage1 {
901880
NodeEx node1, Ap ap1, TypedContent tc, NodeEx node2, DataFlowType contentType,
902881
Configuration config
903882
) {
904-
exists(Content c, DataFlowType containerType |
905-
revFlowIsReadAndStored(pragma[only_bind_into](c), pragma[only_bind_into](config)) and
906-
store(node1, c, node2, contentType, containerType, config) and
883+
exists(Content c |
884+
revFlowIsReadAndStored(c, pragma[only_bind_into](config)) and
907885
revFlow(node2, pragma[only_bind_into](config)) and
908-
tc = MkTypedContent(c, containerType) and
886+
store(node1, tc, node2, contentType, config) and
887+
c = tc.getContent() and
909888
exists(ap1)
910889
)
911890
}
@@ -1978,7 +1957,7 @@ private module Stage3 {
19781957
private predicate flowIntoCall = flowIntoCallNodeCand2/5;
19791958

19801959
pragma[nomagic]
1981-
predicate clearSet(NodeEx node, ContentSet c, Configuration config) {
1960+
private predicate clearSet(NodeEx node, ContentSet c, Configuration config) {
19821961
PrevStage::revFlow(node, config) and
19831962
clearsContentCached(node.asNode(), c)
19841963
}
@@ -4270,7 +4249,7 @@ private module Subpaths {
42704249
result.isHidden() and
42714250
exists(NodeEx n1, NodeEx n2 | n1 = n.getNodeEx() and n2 = result.getNodeEx() |
42724251
localFlowBigStep(n1, _, n2, _, _, _, _, _) or
4273-
storeSet(n1, _, n2, _, _, _) or
4252+
store(n1, _, n2, _, _) or
42744253
readSet(n1, _, n2, _)
42754254
)
42764255
}
@@ -4921,11 +4900,10 @@ private module FlowExploration {
49214900
PartialPathNodeFwd mid, PartialAccessPath ap1, TypedContent tc, NodeEx node,
49224901
PartialAccessPath ap2
49234902
) {
4924-
exists(NodeEx midNode, Content c, DataFlowType contentType, DataFlowType containerType |
4903+
exists(NodeEx midNode, DataFlowType contentType |
49254904
midNode = mid.getNodeEx() and
49264905
ap1 = mid.getAp() and
4927-
store(midNode, c, node, contentType, containerType, mid.getConfiguration()) and
4928-
tc = MkTypedContent(c, containerType) and
4906+
store(midNode, tc, node, contentType, mid.getConfiguration()) and
49294907
ap2.getHead() = tc and
49304908
ap2.len() = unbindInt(ap1.len() + 1) and
49314909
compatibleTypes(ap1.getType(), contentType)
@@ -4947,11 +4925,10 @@ private module FlowExploration {
49474925
PartialPathNodeFwd mid, PartialAccessPath ap, TypedContent tc, NodeEx node, CallContext cc,
49484926
Configuration config
49494927
) {
4950-
exists(NodeEx midNode, Content c |
4928+
exists(NodeEx midNode |
49514929
midNode = mid.getNodeEx() and
49524930
ap = mid.getAp() and
4953-
read(midNode, c, node, pragma[only_bind_into](config)) and
4954-
tc.getContent() = c and
4931+
read(midNode, tc.getContent(), node, pragma[only_bind_into](config)) and
49554932
ap.getHead() = tc and
49564933
pragma[only_bind_into](config) = mid.getConfiguration() and
49574934
cc = mid.getCallContext()
@@ -5202,12 +5179,13 @@ private module FlowExploration {
52025179
private predicate revPartialPathStoreStep(
52035180
PartialPathNodeRev mid, RevPartialAccessPath ap, Content c, NodeEx node, Configuration config
52045181
) {
5205-
exists(NodeEx midNode, DataFlowType contentType, DataFlowType containerType, TypedContent tc |
5182+
exists(NodeEx midNode, TypedContent tc |
52065183
midNode = mid.getNodeEx() and
52075184
ap = mid.getAp() and
5208-
store(node, c, midNode, contentType, containerType, config) and
5209-
tc = MkTypedContent(c, containerType) and
5210-
config = mid.getConfiguration()
5185+
store(node, tc, midNode, _, config) and
5186+
ap.getHead() = c and
5187+
config = mid.getConfiguration() and
5188+
tc.getContent() = c
52115189
)
52125190
}
52135191

ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplCommon.qll

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -786,31 +786,37 @@ private module Cached {
786786
cached
787787
predicate readSet(Node node1, ContentSet c, Node node2) { readStep(node1, c, node2) }
788788

789+
private predicate store(
790+
Node node1, Content c, Node node2, DataFlowType contentType, DataFlowType containerType
791+
) {
792+
exists(ContentSet cs | c = cs.getAStoreContent() |
793+
storeStep(node1, cs, node2) and
794+
contentType = getNodeDataFlowType(node1) and
795+
containerType = getNodeDataFlowType(node2)
796+
or
797+
exists(Node n1, Node n2 |
798+
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
799+
n2 = node2.(PostUpdateNode).getPreUpdateNode()
800+
|
801+
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, cs, contentType), n1)
802+
or
803+
readSet(n2, cs, n1) and
804+
contentType = getNodeDataFlowType(n1) and
805+
containerType = getNodeDataFlowType(n2)
806+
)
807+
)
808+
}
809+
789810
/**
790811
* Holds if data can flow from `node1` to `node2` via a direct assignment to
791-
* `c`.
812+
* `f`.
792813
*
793814
* This includes reverse steps through reads when the result of the read has
794815
* been stored into, in order to handle cases like `x.f1.f2 = y`.
795816
*/
796817
cached
797-
predicate storeSet(
798-
Node node1, ContentSet c, Node node2, DataFlowType contentType, DataFlowType containerType
799-
) {
800-
storeStep(node1, c, node2) and
801-
contentType = getNodeDataFlowType(node1) and
802-
containerType = getNodeDataFlowType(node2)
803-
or
804-
exists(Node n1, Node n2 |
805-
n1 = node1.(PostUpdateNode).getPreUpdateNode() and
806-
n2 = node2.(PostUpdateNode).getPreUpdateNode()
807-
|
808-
argumentValueFlowsThrough(n2, TReadStepTypesSome(containerType, c, contentType), n1)
809-
or
810-
readSet(n2, c, n1) and
811-
contentType = getNodeDataFlowType(n1) and
812-
containerType = getNodeDataFlowType(n2)
813-
)
818+
predicate store(Node node1, TypedContent tc, Node node2, DataFlowType contentType) {
819+
store(node1, tc.getContent(), node2, contentType, tc.getContainerType())
814820
}
815821

816822
/**
@@ -900,13 +906,7 @@ private module Cached {
900906
TDataFlowCallSome(DataFlowCall call)
901907

902908
cached
903-
newtype TTypedContent =
904-
MkTypedContent(Content c, DataFlowType t) {
905-
exists(ContentSet cs |
906-
storeSet(_, cs, _, _, t) and
907-
c = cs.getAStoreContent()
908-
)
909-
}
909+
newtype TTypedContent = MkTypedContent(Content c, DataFlowType t) { store(_, c, _, _, t) }
910910

911911
cached
912912
newtype TAccessPathFront =

0 commit comments

Comments
 (0)