mirror of
https://github.com/github/codeql.git
synced 2026-04-24 08:15:14 +02:00
Rust: Handle path attributes in path resolution
This commit is contained in:
@@ -34,6 +34,8 @@ class Container = Impl::Container;
|
||||
|
||||
class Folder = Impl::Folder;
|
||||
|
||||
module Folder = Impl::Folder;
|
||||
|
||||
/** A file. */
|
||||
class File extends Container, Impl::File {
|
||||
/** Holds if this file was extracted from ordinary source code. */
|
||||
|
||||
@@ -655,6 +655,11 @@ private predicate fileModule(SourceFile f, string name, Folder folder) {
|
||||
)
|
||||
}
|
||||
|
||||
private Meta getPathAttrMeta(Module m) {
|
||||
result = m.getAnAttr().getMeta() and
|
||||
result.getPath().getText() = "path"
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `m` is a `mod name;` module declaration, where the corresponding
|
||||
* module file needs to be looked up in `lookup` or one of its descandants.
|
||||
@@ -663,12 +668,7 @@ private predicate modImport0(Module m, string name, Folder lookup) {
|
||||
exists(File f, Folder parent, string fileName |
|
||||
f = m.getFile() and
|
||||
not m.hasItemList() and
|
||||
// TODO: handle
|
||||
// ```
|
||||
// #[path = "foo.rs"]
|
||||
// mod bar;
|
||||
// ```
|
||||
not m.getAnAttr().getMeta().getPath().getText() = "path" and
|
||||
not exists(getPathAttrMeta(m)) and
|
||||
name = m.getName().getText() and
|
||||
parent = f.getParentContainer() and
|
||||
fileName = f.getStem()
|
||||
@@ -717,6 +717,16 @@ private predicate modImportNestedLookup(Module m, ModuleItemNode ancestor, Folde
|
||||
)
|
||||
}
|
||||
|
||||
private predicate pathAttrImport(Folder f, Module m, string relativePath) {
|
||||
exists(Meta meta |
|
||||
f = m.getFile().getParentContainer() and
|
||||
meta = getPathAttrMeta(m) and
|
||||
relativePath = meta.getExpr().(LiteralExpr).getTextValue().regexpCapture("\"(.+)\"", 1)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate append(Folder f, string relativePath) { pathAttrImport(f, _, relativePath) }
|
||||
|
||||
/** Holds if `m` is a `mod name;` item importing file `f`. */
|
||||
private predicate fileImport(Module m, SourceFile f) {
|
||||
exists(string name, Folder parent |
|
||||
@@ -730,6 +740,11 @@ private predicate fileImport(Module m, SourceFile f) {
|
||||
// `m` is inside a nested module
|
||||
modImportNestedLookup(m, m, parent)
|
||||
)
|
||||
or
|
||||
exists(Folder folder, string relativePath |
|
||||
pathAttrImport(folder, m, relativePath) and
|
||||
f.getFile() = Folder::Append<append/2>::append(folder, relativePath)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,4 +14,4 @@ pub mod my3;
|
||||
#[path = "renamed.rs"]
|
||||
mod mymod;
|
||||
|
||||
use mymod::f; // $ MISSING: item=I1001
|
||||
use mymod::f; // $ item=I1001
|
||||
|
||||
@@ -308,12 +308,13 @@ resolvePath
|
||||
| my2/mod.rs:10:9:10:33 | ...::nested8 | my2/nested2.rs:22:5:26:5 | mod nested8 |
|
||||
| my2/mod.rs:10:37:10:40 | self | my2/nested2.rs:22:5:26:5 | mod nested8 |
|
||||
| my2/mod.rs:17:5:17:9 | mymod | my2/mod.rs:14:1:15:10 | mod mymod |
|
||||
| my2/mod.rs:17:5:17:12 | ...::f | my2/renamed.rs:1:1:1:13 | fn f |
|
||||
| my2/my3/mod.rs:3:5:3:5 | g | my2/mod.rs:3:1:6:1 | fn g |
|
||||
| my2/my3/mod.rs:4:5:4:5 | h | main.rs:50:1:69:1 | fn h |
|
||||
| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:17:39 | SourceFile |
|
||||
| my2/my3/mod.rs:7:5:7:9 | super | my2/mod.rs:1:1:17:30 | SourceFile |
|
||||
| my2/my3/mod.rs:7:5:7:16 | ...::super | main.rs:1:1:578:2 | SourceFile |
|
||||
| my2/my3/mod.rs:7:5:7:19 | ...::h | main.rs:50:1:69:1 | fn h |
|
||||
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:17:39 | SourceFile |
|
||||
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:17:30 | SourceFile |
|
||||
| my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g |
|
||||
| my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested |
|
||||
| my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g |
|
||||
|
||||
@@ -218,6 +218,53 @@ module Make<InputSig Input> {
|
||||
/** Gets the URL of this file. */
|
||||
override string getURL() { result = "file://" + this.getAbsolutePath() + ":0:0:0:0" }
|
||||
}
|
||||
|
||||
/** Provides logic related to `Folder`s. */
|
||||
module Folder {
|
||||
/** Holds if `relativePath` needs to be appended to `f`. */
|
||||
signature predicate appendSig(Folder f, string relativePath);
|
||||
|
||||
/** Provides the `append` predicate for appending a relative path onto a folder. */
|
||||
module Append<appendSig/2 app> {
|
||||
pragma[nomagic]
|
||||
private string getComponent(string relativePath, int i) {
|
||||
app(_, relativePath) and
|
||||
result = relativePath.replaceAll("\\", "/").regexpFind("[^/]+", i, _)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private Container appendStep(Folder f, string relativePath, int i) {
|
||||
i = -1 and
|
||||
app(f, relativePath) and
|
||||
result = f
|
||||
or
|
||||
exists(Container mid, string comp |
|
||||
mid = appendStep(f, relativePath, i - 1) and
|
||||
comp = getComponent(relativePath, i) and
|
||||
if comp = ".."
|
||||
then result = mid.getParentContainer()
|
||||
else
|
||||
if comp = "."
|
||||
then result = mid
|
||||
else (
|
||||
result = mid.getAChildContainer() and
|
||||
result.getBaseName() = comp
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the file or folder obtained by appending `relativePath` onto `f`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
Container append(Folder f, string relativePath) {
|
||||
exists(int components |
|
||||
components = (-1).maximum(max(int comp | exists(getComponent(relativePath, comp)) | comp)) and
|
||||
result = appendStep(f, relativePath, components)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** A file. */
|
||||
|
||||
Reference in New Issue
Block a user