Skip to content

Commit c1959ca

Browse files
committed
Rust: Make SummarizedCallable extend Function instead of string
1 parent ee3f59b commit c1959ca

30 files changed

+796
-893
lines changed

rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,42 +2,17 @@
22

33
private import rust
44
private import internal.FlowSummaryImpl as Impl
5-
private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl
65

76
// import all instances below
87
private module Summaries {
98
private import codeql.rust.Frameworks
109
private import codeql.rust.dataflow.internal.ModelsAsData
1110
}
1211

13-
/** Provides the `Range` class used to define the extent of `LibraryCallable`. */
14-
module LibraryCallable {
15-
/** A callable defined in library code, identified by a unique string. */
16-
abstract class Range extends string {
17-
bindingset[this]
18-
Range() { any() }
19-
20-
/** Gets a call to this library callable. */
21-
CallExprBase getACall() {
22-
exists(Resolvable r, string crate |
23-
r = CallExprBaseImpl::getCallResolvable(result) and
24-
this = crate + r.getResolvedPath()
25-
|
26-
crate = r.getResolvedCrateOrigin() + "::_::"
27-
or
28-
not r.hasResolvedCrateOrigin() and
29-
crate = ""
30-
)
31-
}
32-
}
33-
}
34-
35-
final class LibraryCallable = LibraryCallable::Range;
36-
3712
/** Provides the `Range` class used to define the extent of `SummarizedCallable`. */
3813
module SummarizedCallable {
3914
/** A callable with a flow summary, identified by a unique string. */
40-
abstract class Range extends LibraryCallable::Range, Impl::Public::SummarizedCallable {
15+
abstract class Range extends Impl::Public::SummarizedCallable {
4116
bindingset[this]
4217
Range() { any() }
4318

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

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,10 +45,12 @@ final class DataFlowCallable extends TDataFlowCallable {
4545
/**
4646
* Gets the underlying library callable, if any.
4747
*/
48-
LibraryCallable asLibraryCallable() { this = TLibraryCallable(result) }
48+
SummarizedCallable asSummarizedCallable() { this = TSummarizedCallable(result) }
4949

5050
/** Gets a textual representation of this callable. */
51-
string toString() { result = [this.asCfgScope().toString(), this.asLibraryCallable().toString()] }
51+
string toString() {
52+
result = [this.asCfgScope().toString(), this.asSummarizedCallable().toString()]
53+
}
5254

5355
/** Gets the location of this callable. */
5456
Location getLocation() { result = this.asCfgScope().getLocation() }
@@ -65,12 +67,9 @@ final class DataFlowCall extends TDataFlowCall {
6567
}
6668

6769
DataFlowCallable getEnclosingCallable() {
68-
result = TCfgScope(this.asCallCfgNode().getExpr().getEnclosingCfgScope())
70+
result.asCfgScope() = this.asCallCfgNode().getExpr().getEnclosingCfgScope()
6971
or
70-
exists(FlowSummaryImpl::Public::SummarizedCallable c |
71-
this.isSummaryCall(c, _) and
72-
result = TLibraryCallable(c)
73-
)
72+
this.isSummaryCall(result.asSummarizedCallable(), _)
7473
}
7574

7675
string toString() {
@@ -401,9 +400,11 @@ module RustDataFlow implements InputSig<Location> {
401400

402401
/** Gets a viable implementation of the target of the given `Call`. */
403402
DataFlowCallable viableCallable(DataFlowCall call) {
404-
result.asCfgScope() = call.asCallCfgNode().getCall().getStaticTarget()
405-
or
406-
result.asLibraryCallable().getACall() = call.asCallCfgNode().getCall()
403+
exists(Callable target | target = call.asCallCfgNode().getCall().getStaticTarget() |
404+
target = result.asCfgScope()
405+
or
406+
target = result.asSummarizedCallable()
407+
)
407408
}
408409

409410
/**
@@ -757,7 +758,7 @@ module RustDataFlow implements InputSig<Location> {
757758
predicate allowParameterReturnInSelf(ParameterNode p) {
758759
exists(DataFlowCallable c, ParameterPosition pos |
759760
p.isParameterOf(c, pos) and
760-
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(c.asLibraryCallable(), pos)
761+
FlowSummaryImpl::Private::summaryAllowParameterReturnInSelf(c.asSummarizedCallable(), pos)
761762
)
762763
or
763764
VariableCapture::Flow::heuristicAllowInstanceParameterReturnInSelf(p.(ClosureParameterNode)
@@ -968,7 +969,7 @@ private module Cached {
968969
cached
969970
newtype TDataFlowCallable =
970971
TCfgScope(CfgScope scope) or
971-
TLibraryCallable(LibraryCallable c)
972+
TSummarizedCallable(SummarizedCallable c)
972973

973974
/** This is the local flow predicate that is exposed. */
974975
cached

rust/ql/lib/codeql/rust/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ module Input implements InputSig<Location, RustDataFlow> {
1313
private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl
1414
private import codeql.rust.frameworks.stdlib.Stdlib
1515

16-
class SummarizedCallableBase = string;
16+
class SummarizedCallableBase = Function;
1717

1818
abstract private class SourceSinkBase extends AstNode {
1919
/** Gets the associated call. */
@@ -138,7 +138,7 @@ private import Make<Location, RustDataFlow, Input> as Impl
138138

139139
private module StepsInput implements Impl::Private::StepsInputSig {
140140
DataFlowCall getACall(Public::SummarizedCallable sc) {
141-
result.asCallCfgNode().getCall() = sc.(LibraryCallable).getACall()
141+
result.asCallCfgNode().getCall().getStaticTarget() = sc
142142
}
143143

144144
RustDataFlow::Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponent sc) {

rust/ql/lib/codeql/rust/dataflow/internal/ModelsAsData.qll

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ private import rust
4747
private import codeql.rust.dataflow.FlowSummary
4848
private import codeql.rust.dataflow.FlowSource
4949
private import codeql.rust.dataflow.FlowSink
50+
private import codeql.rust.elements.internal.CallExprBaseImpl::Impl as CallExprBaseImpl
5051

5152
/**
5253
* Holds if in a call to the function with canonical path `path`, defined in the
@@ -120,7 +121,12 @@ private class SummarizedCallableFromModel extends SummarizedCallable::Range {
120121

121122
SummarizedCallableFromModel() {
122123
summaryModel(crate, path, _, _, _, _, _) and
123-
this = crate + "::_::" + path
124+
exists(CallExprBase call, Resolvable r |
125+
call.getStaticTarget() = this and
126+
r = CallExprBaseImpl::getCallResolvable(call) and
127+
r.getResolvedPath() = path and
128+
r.getResolvedCrateOrigin() = crate
129+
)
124130
}
125131

126132
override predicate propagatesFlow(

rust/ql/lib/codeql/rust/dataflow/internal/Node.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ abstract class NodePublic extends TNode {
4444

4545
abstract class Node extends NodePublic {
4646
/** Gets the enclosing callable. */
47-
DataFlowCallable getEnclosingCallable() { result = TCfgScope(this.getCfgScope()) }
47+
DataFlowCallable getEnclosingCallable() { result.asCfgScope() = this.getCfgScope() }
4848

4949
/** Do not call: use `getEnclosingCallable()` instead. */
5050
abstract CfgScope getCfgScope();
@@ -102,9 +102,9 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
102102
}
103103

104104
override DataFlowCallable getEnclosingCallable() {
105-
result.asLibraryCallable() = this.getSummarizedCallable()
106-
or
107105
result.asCfgScope() = this.getCfgScope()
106+
or
107+
result.asSummarizedCallable() = this.getSummarizedCallable()
108108
}
109109

110110
override Location getLocation() {
@@ -195,7 +195,7 @@ final class SummaryParameterNode extends ParameterNode, FlowSummaryNode {
195195
}
196196

197197
override predicate isParameterOf(DataFlowCallable c, ParameterPosition pos) {
198-
this.getSummarizedCallable() = c.asLibraryCallable() and pos = pos_
198+
this.getSummarizedCallable() = c.asSummarizedCallable() and pos = pos_
199199
}
200200
}
201201

rust/ql/lib/codeql/rust/frameworks/stdlib/Clone.qll

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,9 @@ private import codeql.rust.dataflow.FlowSummary
66
/** A `clone` method. */
77
final class CloneCallable extends SummarizedCallable::Range {
88
CloneCallable() {
9-
// NOTE: The function target may not exist in the database, so we base this
10-
// on method calls.
11-
exists(MethodCallExpr c |
12-
c.getIdentifier().getText() = "clone" and
13-
c.getArgList().getNumberOfArgs() = 0 and
14-
this = c.getResolvedCrateOrigin() + "::_::" + c.getResolvedPath()
15-
)
9+
this.getParamList().hasSelfParam() and
10+
this.getParamList().getNumberOfParams() = 0 and
11+
this.getName().getText() = "clone"
1612
}
1713

1814
final override predicate propagatesFlow(

rust/ql/lib/codeql/rust/internal/PathResolution.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1536,8 +1536,8 @@ private module Debug {
15361536
private Locatable getRelevantLocatable() {
15371537
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
15381538
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
1539-
filepath.matches("%/test.rs") and
1540-
startline = 74
1539+
filepath.matches("%/main.rs") and
1540+
startline = 52
15411541
)
15421542
}
15431543

rust/ql/lib/codeql/rust/internal/TypeInference.qll

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,6 +1166,7 @@ final class MethodCall extends Call {
11661166
* Holds if a method for `type` with the name `name` and the arity `arity`
11671167
* exists in `impl`.
11681168
*/
1169+
pragma[nomagic]
11691170
private predicate methodCandidate(Type type, string name, int arity, Impl impl) {
11701171
type = impl.getSelfTy().(TypeMention).resolveType() and
11711172
exists(Function f |
@@ -1453,8 +1454,8 @@ private module Debug {
14531454
private Locatable getRelevantLocatable() {
14541455
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn |
14551456
result.getLocation().hasLocationInfo(filepath, startline, startcolumn, endline, endcolumn) and
1456-
filepath.matches("%/main.rs") and
1457-
startline = 1718
1457+
filepath.matches("%/sqlx.rs") and
1458+
startline = [56 .. 60]
14581459
)
14591460
}
14601461

rust/ql/test/library-tests/dataflow/global/viableCallable.expected

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,10 @@
7575
| main.rs:279:17:279:25 | source(...) | main.rs:1:1:3:1 | fn source |
7676
| main.rs:280:9:280:15 | sink(...) | main.rs:5:1:7:1 | fn sink |
7777
| main.rs:283:5:283:17 | sink(...) | main.rs:5:1:7:1 | fn sink |
78-
| main.rs:287:13:287:55 | ...::block_on(...) | file://:0:0:0:0 | repo:https://github.com/rust-lang/futures-rs:futures-executor::_::crate::local_pool::block_on |
78+
| main.rs:287:13:287:55 | ...::block_on(...) | file://:0:0:0:0 | fn block_on |
7979
| main.rs:287:41:287:54 | async_source(...) | main.rs:268:1:272:1 | fn async_source |
8080
| main.rs:288:5:288:11 | sink(...) | main.rs:5:1:7:1 | fn sink |
81-
| main.rs:290:5:290:62 | ...::block_on(...) | file://:0:0:0:0 | repo:https://github.com/rust-lang/futures-rs:futures-executor::_::crate::local_pool::block_on |
81+
| main.rs:290:5:290:62 | ...::block_on(...) | file://:0:0:0:0 | fn block_on |
8282
| main.rs:290:33:290:61 | test_async_await_async_part(...) | main.rs:274:1:284:1 | fn test_async_await_async_part |
8383
| main.rs:294:5:294:22 | data_out_of_call(...) | main.rs:16:1:19:1 | fn data_out_of_call |
8484
| main.rs:295:5:295:35 | data_out_of_call_side_effect1(...) | main.rs:35:1:40:1 | fn data_out_of_call_side_effect1 |

0 commit comments

Comments
 (0)