Skip to content

Commit 48f887c

Browse files
committed
wip4
1 parent c7d4fc3 commit 48f887c

File tree

5 files changed

+34
-43
lines changed

5 files changed

+34
-43
lines changed

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

Lines changed: 32 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1123,17 +1123,27 @@ private Function getMethodSuccessor(ItemNode item, string name, int arity) {
11231123
arity = result.getParamList().getNumberOfParams()
11241124
}
11251125

1126+
/**
1127+
* Holds if the type path `path` pointing to `type` is either empty, in which
1128+
* case `type` is not `&`, or `path` points to a type being referenced by `&`.
1129+
*/
1130+
bindingset[path, type]
1131+
predicate isRefStrippedRoot(TypePath path, Type type) {
1132+
path.isEmpty() and
1133+
type != TRefType()
1134+
or
1135+
path = TypePath::singleton(TRefTypeParameter()) and
1136+
exists(type)
1137+
}
1138+
11261139
/** Provides logic for resolving method calls. */
11271140
private module MethodCallResolution {
11281141
/**
11291142
* Holds if method `f` with the name `name` and the arity `arity` exists in
11301143
* `i`, and the type of the `self` parameter is `selfType`.
11311144
*
1132-
* TODO
1133-
* `rootType` is the root type of `selfType`, and `selfRootPath` points to
1134-
* `selfRootType` inside `selfType`, where `selfRootType` is either the type
1135-
* being implemented, when `i` is an `impl`, or the trait itself when `i` is
1136-
* a trait.
1145+
* `rootTypePath` points to the type `rootType` inside `selfType`, which is
1146+
* the (possibly `&`-stripped) root type of `selfType`.
11371147
*/
11381148
pragma[nomagic]
11391149
predicate methodInfo(
@@ -1144,12 +1154,7 @@ private module MethodCallResolution {
11441154
f = i.getASuccessor(name) and
11451155
arity = f.getParamList().getNumberOfParams() and
11461156
rootType = selfType.getTypeAt(rootTypePath) and
1147-
(
1148-
rootTypePath.isEmpty() and
1149-
rootType != TRefType()
1150-
or
1151-
rootTypePath = TypePath::singleton(TRefTypeParameter())
1152-
) and
1157+
isRefStrippedRoot(rootTypePath, rootType) and
11531158
selfType.appliesTo(f, pos, i) and
11541159
pos.isSelf() and
11551160
not i.(ImplItemNode).isBlanket()
@@ -1284,6 +1289,14 @@ private module MethodCallResolution {
12841289
derefChainBorrow), i, _)
12851290
}
12861291

1292+
pragma[nomagic]
1293+
private Type getACandidateReceiverRootTypeAtSubstituteTraitBounds(
1294+
TypePath rootTypePath, string derefChainBorrow
1295+
) {
1296+
result = this.getACandidateReceiverTypeAtSubstituteTraitBounds(rootTypePath, derefChainBorrow) and
1297+
isRefStrippedRoot(rootTypePath, result)
1298+
}
1299+
12871300
/**
12881301
* Holds if the candidate receiver type represented by `derefChain` does not
12891302
* have a matching method target.
@@ -1294,13 +1307,7 @@ private module MethodCallResolution {
12941307
derefChainBorrow = derefChain + ";" and
12951308
not derefChain.matches("%.ref") and // no need to try a borrow if the last thing we did was a deref
12961309
rootType =
1297-
this.getACandidateReceiverTypeAtSubstituteTraitBounds(rootTypePath, derefChainBorrow) and
1298-
(
1299-
rootTypePath.isEmpty() and
1300-
rootType != TRefType()
1301-
or
1302-
rootTypePath = TypePath::singleton(TRefTypeParameter())
1303-
)
1310+
this.getACandidateReceiverRootTypeAtSubstituteTraitBounds(rootTypePath, derefChainBorrow)
13041311
|
13051312
forall(ImplOrTraitItemNode i | methodCallCandidate(this, i, _, rootTypePath, rootType) |
13061313
this.isNotCandidate(i, derefChainBorrow)
@@ -1318,8 +1325,7 @@ private module MethodCallResolution {
13181325
derefChainBorrow = derefChain + ";borrow" and
13191326
this.noCandidateReceiverTypeAtNoBorrow(derefChain) and
13201327
rootType =
1321-
this.getACandidateReceiverTypeAtSubstituteTraitBounds(rootTypePath, derefChainBorrow) and
1322-
rootTypePath = TypePath::singleton(TRefTypeParameter())
1328+
this.getACandidateReceiverRootTypeAtSubstituteTraitBounds(rootTypePath, derefChainBorrow)
13231329
|
13241330
forall(ImplOrTraitItemNode i | methodCallCandidate(this, i, _, rootTypePath, rootType) |
13251331
this.isNotCandidate(i, derefChainBorrow)
@@ -1463,12 +1469,7 @@ private module MethodCallResolution {
14631469
private predicate hasNoInherentTarget() {
14641470
exists(TypePath rootTypePath, Type rootType, string name, int arity |
14651471
this.isMethodCall(_, rootTypePath, rootType, name, arity) and
1466-
(
1467-
rootTypePath.isEmpty() and
1468-
rootType != TRefType()
1469-
or
1470-
rootTypePath = TypePath::singleton(TRefTypeParameter())
1471-
) and
1472+
isRefStrippedRoot(rootTypePath, rootType) and
14721473
forall(Impl i |
14731474
methodInfo(_, name, arity, i, _, rootTypePath, rootType) and
14741475
not i.hasTrait()
@@ -2314,18 +2315,13 @@ private Type inferOperationType(AstNode n, TypePath path) {
23142315
)
23152316
}
23162317

2317-
pragma[inline]
2318-
private Type inferRootTypeDeref(AstNode n) {
2319-
result = inferType(n) and
2320-
result != TRefType()
2321-
or
2322-
// for reference types, lookup members in the type being referenced
2323-
result = inferType(n, TypePath::singleton(TRefTypeParameter()))
2324-
}
2325-
23262318
pragma[nomagic]
23272319
private Type getFieldExprLookupType(FieldExpr fe, string name) {
2328-
result = inferRootTypeDeref(fe.getContainer()) and name = fe.getIdentifier().getText()
2320+
exists(TypePath path |
2321+
result = inferType(fe.getContainer(), path) and
2322+
name = fe.getIdentifier().getText() and
2323+
isRefStrippedRoot(path, result)
2324+
)
23292325
}
23302326

23312327
pragma[nomagic]
Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,2 @@
11
multipleCallTargets
2-
| main.rs:322:14:322:33 | ... .cmp(...) |
3-
| main.rs:334:9:334:28 | ... .cmp(...) |
42
| main.rs:362:14:362:30 | ... .lt(...) |

rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@ multipleCallTargets
1111
| test.rs:179:30:179:68 | ...::_print(...) |
1212
| test.rs:188:26:188:105 | ...::_print(...) |
1313
| test.rs:229:22:229:72 | ... .read_to_string(...) |
14-
| test.rs:639:26:639:43 | file1.chain(...) |
15-
| test.rs:647:26:647:40 | file1.take(...) |
1614
| test.rs:697:18:697:38 | ...::_print(...) |
1715
| test.rs:702:18:702:45 | ...::_print(...) |
1816
| test.rs:720:38:720:42 | ...::_print(...) |

rust/ql/test/library-tests/dataflow/sources/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -638,15 +638,15 @@ async fn test_tokio_file() -> std::io::Result<()> {
638638
let file2 = tokio::fs::File::open("another_file.txt").await?; // $ Alert[rust/summary/taint-sources]
639639
let mut reader = file1.chain(file2);
640640
reader.read_to_string(&mut buffer).await?;
641-
sink(&buffer); // $ hasTaintFlow="file.txt" hasTaintFlow="another_file.txt"
641+
sink(&buffer); // $ MISSING: hasTaintFlow="file.txt" hasTaintFlow="another_file.txt" -- we cannot resolve the `chain` and `read_to_string` calls above, which comes from `impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}` in `async_read_ext.rs`
642642
}
643643

644644
{
645645
let mut buffer = String::new();
646646
let file1 = tokio::fs::File::open("file.txt").await?; // $ Alert[rust/summary/taint-sources]
647647
let mut reader = file1.take(100);
648648
reader.read_to_string(&mut buffer).await?;
649-
sink(&buffer); // $ hasTaintFlow="file.txt"
649+
sink(&buffer); // $ MISSING: hasTaintFlow="file.txt" -- we cannot resolve the `take` and `read_to_string` calls above, which comes from `impl<R: AsyncRead + ?Sized> AsyncReadExt for R {}` in `async_read_ext.rs`
650650
}
651651

652652
Ok(())

rust/ql/test/library-tests/type-inference/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ multipleCallTargets
55
| dereference.rs:184:17:184:30 | ... .foo() |
66
| dereference.rs:186:17:186:25 | S.bar(...) |
77
| dereference.rs:187:17:187:29 | S.bar(...) |
8-
| main.rs:1803:13:1803:63 | ... .partial_cmp(...) |
98
| main.rs:2318:9:2318:34 | ...::my_from2(...) |
109
| main.rs:2319:9:2319:33 | ...::my_from2(...) |
1110
| main.rs:2320:9:2320:38 | ...::my_from2(...) |

0 commit comments

Comments
 (0)