Skip to content

Commit

Permalink
Merge pull request #18070 from hvitved/rust/canonical-path-dataflow
Browse files Browse the repository at this point in the history
Rust: Use extended canonical paths to resolve calls in data flow
  • Loading branch information
hvitved authored Nov 25, 2024
2 parents 4b0b038 + 143d7e2 commit e6161a5
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 6 deletions.
54 changes: 48 additions & 6 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -399,13 +399,55 @@ module RustDataFlow implements InputSig<Location> {

final class ReturnKind = ReturnKindAlias;

private import codeql.util.Option

private class CrateOrigin extends string {
CrateOrigin() {
this = [any(Item i).getCrateOrigin(), any(Resolvable r).getResolvedCrateOrigin()]
}
}

private class CrateOriginOption = Option<CrateOrigin>::Option;

pragma[nomagic]
private predicate hasExtendedCanonicalPath(
DataFlowCallable c, CrateOriginOption crate, string path
) {
exists(Item i |
i = c.asCfgScope() and
path = i.getExtendedCanonicalPath()
|
crate.asSome() = i.getCrateOrigin()
or
crate.isNone() and
not i.hasCrateOrigin()
)
}

pragma[nomagic]
private predicate resolvesExtendedCanonicalPath(
DataFlowCall c, CrateOriginOption crate, string path
) {
exists(Resolvable r |
path = r.getResolvedPath() and
(
r = c.asMethodCallExprCfgNode().getExpr()
or
r = c.asCallExprCfgNode().getExpr().(PathExprCfgNode).getPath()
)
|
crate.asSome() = r.getResolvedCrateOrigin()
or
crate.isNone() and
not r.hasResolvedCrateOrigin()
)
}

/** Gets a viable implementation of the target of the given `Call`. */
DataFlowCallable viableCallable(DataFlowCall c) {
exists(Function f, string name | result.asCfgScope() = f and name = f.getName().toString() |
if f.getParamList().hasSelfParam()
then name = c.asMethodCallExprCfgNode().getNameRef().getText()
else
name = c.asCallExprCfgNode().getExpr().getExpr().(PathExpr).getPath().getPart().toString()
DataFlowCallable viableCallable(DataFlowCall call) {
exists(string path, CrateOriginOption crate |
hasExtendedCanonicalPath(result, crate, path) and
resolvesExtendedCanonicalPath(call, crate, path)
)
}

Expand Down
1 change: 1 addition & 0 deletions shared/util/codeql/util/Option.qll
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

/** A type with `toString`. */
private signature class TypeWithToString {
bindingset[this]
string toString();
}

Expand Down

0 comments on commit e6161a5

Please sign in to comment.