Rust: add "standard path"

This commit is contained in:
Paolo Tranquilli
2024-12-11 17:07:06 +01:00
parent 925fac2a6c
commit c8d668bcee
12 changed files with 113 additions and 25 deletions

View File

@@ -194,7 +194,6 @@ lib/codeql/rust/elements/canonical_paths/TypeImplItemCanonicalPath.qll a482bf323
lib/codeql/rust/elements/canonical_paths/TypeItemCanonicalPath.qll 3cdd980844dac4533bf7fc82c1679af39b151aecbe325a9dbd7a2275ecc3b72b df6232001508086a62ad0e629287d0705a072ba26437f8a55d8aad977e11f554
lib/codeql/rust/elements/canonical_paths/internal/BuiltinTypeCanonicalPathConstructor.qll c33ca6a182eae907bc01a11bbe9e10a705889d6d383cd8804c5380368cf785d4 af1677ff43fcb22dedde3dfa853dc12a197c6e5db7ec6191cfd6c9197e371a05
lib/codeql/rust/elements/canonical_paths/internal/BuiltinTypeCanonicalPathImpl.qll 6dbc6981e280717eb8a7cc2bf06bb91e760cc168e262dcf87db53f610b3a0362 ce81251f033173baabcfa9dd2a6a760169015329daac738760bb4e6689c0fe85
lib/codeql/rust/elements/canonical_paths/internal/CanonicalPathImpl.qll c368afc58a57feb86acde466eb33ed74d17bcd8360219ddf93b0302ea43504ee 42df02e0a15c0555ca1cf830debbc94f647c38c7f6ca8f7640f2cbe8f36d4ac6
lib/codeql/rust/elements/canonical_paths/internal/ConcreteTypeCanonicalPathConstructor.qll 122781ed5b5bfddc0f6c5243d3a77eb969559115c7f612b81291f62b5790b48d 348ee1d8c92b803a1aaf8e3fc5a9061a41cd2a4c6f2f6fa51910659a1edfa00f
lib/codeql/rust/elements/canonical_paths/internal/ConstGenericTypeArgConstructor.qll a2ef92745e712b091367e063662e800b8f84efdf28b02e7116c7c8ab0629e0fc 4a2689f585c0de2f77ca64620bb65986bafab6209fbc383646335040d6155018
lib/codeql/rust/elements/canonical_paths/internal/DerivedTypeCanonicalPathConstructor.qll 1127f0e1eaed5da946a5288271f679ef1984d984a3686cd59d9ec89a8251a234 04419a1231179c8d39637edd443c4ff038e010753f4e6a016ac8c9dbc8f6cccd
@@ -212,7 +211,6 @@ lib/codeql/rust/elements/canonical_paths/internal/TypeImplItemCanonicalPathConst
lib/codeql/rust/elements/canonical_paths/internal/TypeItemCanonicalPathConstructor.qll b23c6d7902c56c758bc121cd5d3c7e351eccb66503131bc2fa4dda60abb9b4ae b097ab6555f06b12f7ae99378dc9bc347a8b7b7b2691d6a636b9392178cb5692
lib/codeql/rust/elements/internal/AbiConstructor.qll 4484538db49d7c1d31c139f0f21879fceb48d00416e24499a1d4b1337b4141ac 460818e397f2a1a8f2e5466d9551698b0e569d4640fcb87de6c4268a519b3da1
lib/codeql/rust/elements/internal/AbiImpl.qll 01439712ecadc9dc8da6f74d2e19cee13c77f8e1e25699055da675b2c88cb02d dcc9395ef8abd1af3805f3e7fcbc2d7ce30affbce654b6f5e559924768db403c
lib/codeql/rust/elements/internal/AddressableImpl.qll e01a6104980960f5708d5a0ada774ba21db9a344e33deeaf3d3239c627268c77 b8bfc711b267df305ac9fe5f6a994f051ddeca7fc95dacd76d1bae2d4fa7adde
lib/codeql/rust/elements/internal/ArgListConstructor.qll a73685c8792ae23a2d628e7357658efb3f6e34006ff6e9661863ef116ec0b015 0bee572a046e8dfc031b1216d729843991519d94ae66280f5e795d20aea07a22
lib/codeql/rust/elements/internal/ArgListImpl.qll 19664651c06b46530f0ae5745ccb3233afc97b9152e053761d641de6e9c62d38 40af167e571f5c255f264b3be7cc7f5ff42ec109661ca03dcee94e92f8facfc6
lib/codeql/rust/elements/internal/ArrayExprInternal.qll 07a219b3d3fba3ff8b18e77686b2f58ab01acd99e0f5d5cad5d91af937e228f5 7528fc0e2064c481f0d6cbff3835950a044e429a2cd00c4d8442d2e132560d37

2
rust/ql/.gitattributes generated vendored
View File

@@ -196,7 +196,6 @@
/lib/codeql/rust/elements/canonical_paths/TypeItemCanonicalPath.qll linguist-generated
/lib/codeql/rust/elements/canonical_paths/internal/BuiltinTypeCanonicalPathConstructor.qll linguist-generated
/lib/codeql/rust/elements/canonical_paths/internal/BuiltinTypeCanonicalPathImpl.qll linguist-generated
/lib/codeql/rust/elements/canonical_paths/internal/CanonicalPathImpl.qll linguist-generated
/lib/codeql/rust/elements/canonical_paths/internal/ConcreteTypeCanonicalPathConstructor.qll linguist-generated
/lib/codeql/rust/elements/canonical_paths/internal/ConstGenericTypeArgConstructor.qll linguist-generated
/lib/codeql/rust/elements/canonical_paths/internal/DerivedTypeCanonicalPathConstructor.qll linguist-generated
@@ -214,7 +213,6 @@
/lib/codeql/rust/elements/canonical_paths/internal/TypeItemCanonicalPathConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/AbiConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/AbiImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/AddressableImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/ArgListConstructor.qll linguist-generated
/lib/codeql/rust/elements/internal/ArgListImpl.qll linguist-generated
/lib/codeql/rust/elements/internal/ArrayExprInternal.qll linguist-generated

View File

@@ -29,14 +29,20 @@ module LibraryCallable {
/** Gets a call to this library callable. */
CallExprBase getACall() {
exists(Resolvable r, string crate |
r = CallExprBaseImpl::getCallResolvable(result) and
this = crate + r.getResolvedPath()
exists(
TypeItemCanonicalPath path, ModuleItemCanonicalPath item, Namespace namespace,
string namespace_path
|
crate = r.getResolvedCrateOrigin() + "::_::"
or
not r.hasResolvedCrateOrigin() and
crate = ""
path = CallExprBaseImpl::getCallResolvable(result).getResolvedCanonicalPath() and
item = path.getParent() and
namespace = item.getNamespace() and
namespace_path = namespace.getPath() and
if namespace_path = ""
then this = namespace.getRoot().toString() + "::" + item.getName() + "::" + path.getName()
else
this =
namespace.getRoot().toString() + "::" + namespace_path + "::" + item.getName() + "::" +
path.getName()
)
}
}

View File

@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `CanonicalPath`.
*
@@ -12,8 +11,25 @@ private import codeql.rust.elements.internal.generated.canonical_paths.Canonical
* be referenced directly.
*/
module Impl {
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* The base class for all canonical paths that can be the result of a path resolution.
*/
class CanonicalPath extends Generated::CanonicalPath { }
class CanonicalPath extends Generated::CanonicalPath {
/**
* If this canonical path is of the form `crate::mod1::mod2::Type::name`, then this predicate
* splits it into its components `crate::mod1::mod2`, `Type` and `name`. This applies to
* type, trait and type impl items, not to module items (see `hasStandardPath/2`) nor to
* trait impl items (TODO).
*/
predicate hasStandardPath(string namespace, string type, string name) { none() }
/**
* If this canonical path is of the form `crate::mod1::mod2::name`, then this predicate
* splits it into its components `crate::mod1::mod2` and `name`. This applies to
* module items, but not to type, trait and type impl items (see `hasStandardPath/3`) nor to
* trait impl items (TODO).
*/
predicate hasStandardPath(string namespace, string name) { none() }
}
}

View File

@@ -19,5 +19,9 @@ module Impl {
override string toString() {
result = this.getNamespace().toAbbreviatedString() + "::" + this.getName()
}
override predicate hasStandardPath(string namespace, string name) {
this.getName() = name and namespace = this.getNamespace().getNamespaceString()
}
}
}

View File

@@ -22,5 +22,17 @@ module Impl {
if this.getPath() = "" then result = root else result = root + "::" + this.getPath()
)
}
/**
* Returns a string representation of this namespace, with the root and path separated by `::`.
*/
cached
string getNamespaceString() {
exists(string root, string path |
root = this.getRoot().toString() and
path = this.getPath() and
if path = "" then result = root else result = root + "::" + path
)
}
}
}

View File

@@ -19,5 +19,9 @@ module Impl {
override string toString() {
result = "<" + this.getParent().toAbbreviatedString() + ">::" + this.getName()
}
override predicate hasStandardPath(string namespace, string type, string name) {
this.getName() = name and this.getParent().hasStandardPath(namespace, type)
}
}
}

View File

@@ -19,5 +19,9 @@ module Impl {
override string toString() {
result = this.getParent().toAbbreviatedString() + "::" + this.getName()
}
override predicate hasStandardPath(string namespace, string type, string name) {
this.getName() = name and this.getParent().hasStandardPath(namespace, type)
}
}
}

View File

@@ -1,4 +1,3 @@
// generated by codegen, remove this comment if you wish to edit this file
/**
* This module provides a hand-modifiable wrapper around the generated class `Addressable`.
*
@@ -12,10 +11,25 @@ private import codeql.rust.elements.internal.generated.Addressable
* be referenced directly.
*/
module Impl {
// the following QLdoc is generated: if you need to edit it, do it in the schema file
/**
* Something that can be addressed by a path.
*
* TODO: This does not yet include all possible cases.
*/
class Addressable extends Generated::Addressable { }
class Addressable extends Generated::Addressable {
/**
* Splits the standard path into its components (see `CanonicalPath::hasStandardPath/3`).
*/
predicate hasStandardPath(string namespace, string type, string name) {
this.getCanonicalPath().hasStandardPath(namespace, type, name)
}
/**
* Splits the standard path into its components (see `CanonicalPath::hasStandardPath/2`).
*/
predicate hasStandardPath(string namespace, string name) {
this.getCanonicalPath().hasStandardPath(namespace, name)
}
}
}

View File

@@ -20,16 +20,9 @@ module Impl {
class Resolvable extends Generated::Resolvable {
/**
* Holds if this resolvable and the item `i` resolves to the same canonical
* path in the same crate
* path
*/
pragma[nomagic]
predicate resolvesAsItem(Item i) {
this.getResolvedPath() = i.getExtendedCanonicalPath() and
(
this.getResolvedCrateOrigin() = i.getCrateOrigin()
or
not this.hasResolvedCrateOrigin() and not i.hasCrateOrigin()
)
}
predicate resolvesAsItem(Item i) { this.getResolvedCanonicalPath() = i.getCanonicalPath() }
}
}

View File

@@ -121,12 +121,40 @@ resolvedPaths
| usage.rs:48:5:48:23 | ... .generic_method(...) | <... as ...>::generic_method |
| usage.rs:52:5:52:10 | ... .f(...) | <... as ...>::f |
| usage.rs:53:5:53:15 | ... .f(...) | <... as ...>::f |
| usage.rs:54:5:54:17 | ...::into_vec | <...>::into_vec |
| usage.rs:54:5:54:17 | ...::into_vec | None |
| usage.rs:54:5:54:17 | ...::new | None |
| usage.rs:54:5:54:28 | ... .as_slice(...) | <...>::as_slice |
| usage.rs:54:5:54:32 | ... .f(...) | <... as ...>::f |
| usage.rs:55:5:55:16 | ... .f(...) | <... as ...>::f |
| usage.rs:56:5:56:20 | ... .f(...) | <... as ...>::f |
standardPaths
| anonymous.rs:3:1:32:1 | fn canonicals | test::anonymous::canonicals |
| anonymous.rs:15:9:15:22 | fn g | test::regular::Struct::g |
| anonymous.rs:34:1:36:1 | fn other | test::anonymous::other |
| regular.rs:1:1:2:18 | struct Struct | test::regular::Struct |
| regular.rs:4:1:6:1 | trait Trait | test::regular::Trait |
| regular.rs:5:5:5:16 | fn f | test::regular::Trait::f |
| regular.rs:13:5:13:22 | fn g | test::regular::Struct::g |
| regular.rs:16:1:18:1 | trait TraitWithBlanketImpl | test::regular::TraitWithBlanketImpl |
| regular.rs:17:5:17:16 | fn h | test::regular::TraitWithBlanketImpl::h |
| regular.rs:24:1:24:16 | fn free | test::regular::free |
| regular.rs:26:1:30:1 | enum MyEnum | test::regular::MyEnum |
| regular.rs:27:5:27:12 | Variant1 | test::regular::MyEnum::Variant1 |
| regular.rs:28:5:28:19 | Variant2 | test::regular::MyEnum::Variant2 |
| regular.rs:29:5:29:25 | Variant3 | test::regular::MyEnum::Variant3 |
| regular.rs:32:1:34:1 | trait GenericTrait | test::regular::GenericTrait |
| regular.rs:33:5:33:35 | fn generic_method | test::regular::GenericTrait::generic_method |
| regular.rs:36:1:39:1 | struct GenericStruct | test::regular::GenericStruct |
| regular.rs:41:1:41:50 | struct GenericTupleStruct | test::regular::GenericTupleStruct |
| regular.rs:44:1:47:1 | enum GenericEnum | test::regular::GenericEnum |
| regular.rs:45:5:45:8 | T | test::regular::GenericEnum::T |
| regular.rs:46:5:46:8 | U | test::regular::GenericEnum::U |
| usage.rs:3:1:9:1 | fn usage | test::usage::usage |
| usage.rs:11:1:17:1 | fn enum_qualified_usage | test::usage::enum_qualified_usage |
| usage.rs:19:1:26:1 | fn enum_unqualified_usage | test::usage::enum_unqualified_usage |
| usage.rs:28:1:34:1 | fn enum_match | test::usage::enum_match |
| usage.rs:36:1:49:1 | fn generic_usage | test::usage::generic_usage |
| usage.rs:51:1:57:1 | fn use_trait | test::usage::use_trait |
resolve
| usage.rs:4:13:4:21 | Struct {...} | regular.rs:1:1:2:18 | struct Struct |
| usage.rs:5:5:5:9 | ... .f(...) | regular.rs:9:5:9:18 | fn f |

View File

@@ -19,6 +19,17 @@ query predicate resolvedPaths(Resolvable i, string answer) {
)
}
query predicate standardPaths(Addressable i, string answer) {
toBeTested(i) and
exists(string namespace, string name |
i.hasStandardPath(namespace, name) and answer = namespace + "::" + name
or
exists(string type |
i.hasStandardPath(namespace, type, name) and answer = namespace + "::" + type + "::" + name
)
)
}
query predicate resolve(Resolvable i, Addressable j) {
toBeTested(i) and
toBeTested(j) and