Skip to content

Commit

Permalink
Rust: Use canonical paths for variants in data flow
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Dec 3, 2024
1 parent 0bebfa6 commit 3c767b0
Show file tree
Hide file tree
Showing 6 changed files with 418 additions and 358 deletions.
2 changes: 1 addition & 1 deletion rust/ql/lib/codeql/rust/dataflow/FlowSummary.qll
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ private module Summaries {
UnwrapSummary() { this = "lang:core::_::<crate::option::Option>::unwrap" }

override predicate propagatesFlow(string input, string output, boolean preservesValue) {
input = "Argument[self].Variant[crate::std::option::Option::Some(0)]" and
input = "Argument[self].Variant[crate::option::Option::Some(0)]" and
output = "ReturnValue" and
preservesValue = true
}
Expand Down
40 changes: 19 additions & 21 deletions rust/ql/lib/codeql/rust/dataflow/internal/DataFlowImpl.qll
Original file line number Diff line number Diff line change
Expand Up @@ -788,9 +788,7 @@ module RustDataFlow implements InputSig<Location> {
(
LocalFlow::localFlowStepCommon(nodeFrom, nodeTo)
or
exists(SsaImpl::DefinitionExt def, boolean isUseStep |
SsaFlow::localFlowStep(def, nodeFrom, nodeTo, isUseStep)
|
exists(boolean isUseStep | SsaFlow::localFlowStep(_, nodeFrom, nodeTo, isUseStep) |
isUseStep = false
or
isUseStep = true and
Expand Down Expand Up @@ -825,15 +823,13 @@ module RustDataFlow implements InputSig<Location> {
exists(CrateOriginOption crate, string path |
resolveExtendedCanonicalPath(p.getQualifier(), crate, path) and
v = MkVariantCanonicalPath(crate, path, p.getPart().getNameRef().getText())
or
exists(string name |
not p.hasQualifier() and
resolveExtendedCanonicalPath(p, crate, path + "::" + name) and
v = MkVariantCanonicalPath(crate, path, name)
)
)
or
// TODO: Remove once library types are extracted
not p.hasQualifier() and
v = MkVariantCanonicalPath(_, "crate::std::option::Option", p.getPart().getNameRef().getText())
or
// TODO: Remove once library types are extracted
not p.hasQualifier() and
v = MkVariantCanonicalPath(_, "crate::std::result::Result", p.getPart().getNameRef().getText())
}

/** Holds if `p` destructs an enum variant `v`. */
Expand Down Expand Up @@ -1099,20 +1095,22 @@ private module Cached {
cached
newtype TReturnKind = TNormalReturnKind()

private CrateOriginOption langCoreCrate() { result.asSome() = "lang:core" }

cached
newtype TVariantCanonicalPath =
MkVariantCanonicalPath(CrateOriginOption crate, string path, string name) {
variantHasExtendedCanonicalPath(_, _, crate, path, name)
or
// TODO: Remove once library types are extracted
crate.isNone() and
path = "crate::std::option::Option" and
name = "Some"
or
// TODO: Remove once library types are extracted
crate.isNone() and
path = "crate::std::result::Result" and
name = ["Ok", "Err"]
crate = langCoreCrate() and
(
path = "crate::option::Option" and
name = "Some"
or
path = "crate::result::Result" and
name = ["Ok", "Err"]
)
}

cached
Expand All @@ -1127,11 +1125,11 @@ private module Cached {
pos in [0 .. v.getVariant().getFieldList().(TupleFieldList).getNumberOfFields() - 1]
or
// TODO: Remove once library types are extracted
v = MkVariantCanonicalPath(_, "crate::std::option::Option", "Some") and
v = MkVariantCanonicalPath(langCoreCrate(), "crate::option::Option", "Some") and
pos = 0
or
// TODO: Remove once library types are extracted
v = MkVariantCanonicalPath(_, "crate::std::result::Result", ["Ok", "Err"]) and
v = MkVariantCanonicalPath(langCoreCrate(), "crate::result::Result", ["Ok", "Err"]) and
pos = 0
} or
TVariantFieldContent(VariantCanonicalPath v, string field) {
Expand Down
Loading

0 comments on commit 3c767b0

Please sign in to comment.