Skip to content

Commit 2adc78b

Browse files
committed
Rust: Canonical paths for blanket implementations
1 parent 5a69ef0 commit 2adc78b

4 files changed

Lines changed: 236 additions & 179 deletions

File tree

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -874,7 +874,12 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
874874
*/
875875
predicate isBlanketImplementation() { exists(this.getBlanketImplementationTypeParam()) }
876876

877-
override predicate hasCanonicalPath(Crate c) { this.resolveSelfTy().hasCanonicalPathPrefix(c) }
877+
override predicate hasCanonicalPath(Crate c) {
878+
this.resolveSelfTy().hasCanonicalPathPrefix(c)
879+
or
880+
this.isBlanketImplementation() and
881+
c.getASourceFile().getFile() = this.getFile()
882+
}
878883

879884
/**
880885
* Holds if `(c1, c2)` forms a pair of crates for the type and trait
@@ -920,7 +925,12 @@ final class ImplItemNode extends ImplOrTraitItemNode instanceof Impl {
920925
result = "<"
921926
or
922927
i = 1 and
923-
result = this.getSelfCanonicalPath(c)
928+
(
929+
result = this.getSelfCanonicalPath(c)
930+
or
931+
this.isBlanketImplementation() and
932+
result = "_"
933+
)
924934
or
925935
if exists(this.getTraitPath())
926936
then

rust/ql/test/library-tests/dataflow/models/main.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,27 @@ impl Ord for MyStruct2 {
460460
}
461461
}
462462

463+
trait MyTrait2 {
464+
fn flow_through2(i: i64) -> i64;
465+
}
466+
467+
trait MyTrait3 {
468+
fn flow_through3(i: i64) -> i64;
469+
}
470+
471+
impl<T> MyTrait2 for T {
472+
fn flow_through2(i: i64) -> i64 {
473+
0
474+
}
475+
}
476+
477+
impl<T> MyTrait3 for T
478+
{
479+
fn flow_through3(i: i64) -> i64 {
480+
0
481+
}
482+
}
483+
463484
fn test_trait_model<T: Ord>(x: T) {
464485
let x1 = source(20).max(0);
465486
sink(x1); // $ hasValueFlow=20
@@ -488,6 +509,12 @@ fn test_trait_model<T: Ord>(x: T) {
488509

489510
let x7 = (source(28) as i32) < 1;
490511
sink(x7);
512+
513+
let x8 = <()>::flow_through2(source(29));
514+
sink(x8); // $ hasValueFlow=29
515+
516+
let x9 = <()>::flow_through3(source(30));
517+
sink(x9); // $ hasValueFlow=30
491518
}
492519

493520
mod external_file;

0 commit comments

Comments
 (0)