Skip to content

Commit 053ac0e

Browse files
committed
Rust: Path resolution improvements
1 parent 377fab2 commit 053ac0e

File tree

5 files changed

+39
-13
lines changed

5 files changed

+39
-13
lines changed

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

Lines changed: 33 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,9 @@ private ItemNode getAChildSuccessor(ItemNode item, string name, SuccessorKind ki
7272
if item instanceof ImplOrTraitItemNode and result instanceof AssocItem
7373
then kind.isExternal()
7474
else
75-
if result instanceof Use
76-
then kind.isInternal()
77-
else kind.isBoth()
75+
if result.isPublic()
76+
then kind.isBoth()
77+
else kind.isInternal()
7878
)
7979
}
8080

@@ -165,6 +165,20 @@ abstract class ItemNode extends Locatable {
165165
/** Gets the visibility of this item, if any. */
166166
abstract Visibility getVisibility();
167167

168+
/**
169+
* Holds if this item is public.
170+
*
171+
* This is the case when this item either has `pub` visibility (but is not
172+
* a `use`; a `use` itself is not visible from the outside), or when this
173+
* item is a variant.
174+
*/
175+
predicate isPublic() {
176+
exists(this.getVisibility()) and
177+
not this instanceof Use
178+
or
179+
this instanceof Variant
180+
}
181+
168182
/** Gets the `i`th type parameter of this item, if any. */
169183
abstract TypeParam getTypeParam(int i);
170184

@@ -1300,7 +1314,8 @@ private predicate useTreeDeclares(UseTree tree, string name) {
13001314
*/
13011315
pragma[nomagic]
13021316
private predicate declaresDirectly(ItemNode item, Namespace ns, string name) {
1303-
exists(ItemNode child, SuccessorKind kind | child = getAChildSuccessor(item, name, kind) |
1317+
exists(ItemNode child, SuccessorKind kind |
1318+
child = getAChildSuccessor(item, name, kind) and
13041319
child.getNamespace() = ns and
13051320
kind.isInternalOrBoth()
13061321
)
@@ -1501,8 +1516,11 @@ private ItemNode resolvePathCandQualified(
15011516
) {
15021517
exists(string name, SuccessorKind kind |
15031518
q = resolvePathCandQualifier(qualifier, path, name) and
1504-
result = getASuccessor(q, name, ns, kind) and
1519+
result = getASuccessor(q, name, ns, kind)
1520+
|
15051521
kind.isExternalOrBoth()
1522+
or
1523+
qualifier.getText() = "super"
15061524
)
15071525
}
15081526

@@ -1646,10 +1664,12 @@ private ItemNode resolveUseTreeListItemQualifier(
16461664

16471665
pragma[nomagic]
16481666
private ItemNode resolveUseTreeListItem(Use use, UseTree tree) {
1649-
tree = use.getUseTree() and
1650-
result = resolvePathCand(tree.getPath())
1651-
or
1652-
result = resolveUseTreeListItem(use, tree, tree.getPath(), _)
1667+
exists(Path path | path = tree.getPath() |
1668+
tree = use.getUseTree() and
1669+
result = resolvePathCand(path)
1670+
or
1671+
result = resolveUseTreeListItem(use, tree, path, _)
1672+
)
16531673
}
16541674

16551675
/** Holds if `use` imports `item` as `name`. */
@@ -1673,7 +1693,10 @@ private predicate useImportEdge(Use use, string name, ItemNode item, SuccessorKi
16731693
item = used and
16741694
(
16751695
not tree.hasRename() and
1676-
name = item.getName()
1696+
exists(string pathName |
1697+
pathName = tree.getPath().getText() and
1698+
if pathName = "self" then name = item.getName() else name = pathName
1699+
)
16771700
or
16781701
exists(Rename rename | rename = tree.getRename() |
16791702
name = rename.getName().getText()

rust/ql/test/library-tests/dataflow/sources/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ multipleCallTargets
1111
| test.rs:179:30:179:68 | ...::_print(...) |
1212
| test.rs:188:26:188:105 | ...::_print(...) |
1313
| test.rs:229:22:229:72 | ... .read_to_string(...) |
14+
| test.rs:664:22:664:43 | file.read(...) |
15+
| test.rs:673:22:673:41 | f1.read(...) |
1416
| test.rs:697:18:697:38 | ...::_print(...) |
1517
| test.rs:702:18:702:45 | ...::_print(...) |
1618
| test.rs:720:38:720:42 | ...::_print(...) |

rust/ql/test/library-tests/dataflow/sources/test.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -662,7 +662,7 @@ async fn test_async_std_file() -> std::io::Result<()> {
662662
{
663663
let mut buffer = [0u8; 100];
664664
let _bytes = file.read(&mut buffer).await?;
665-
sink(&buffer); // $ MISSING: hasTaintFlow="file.txt"
665+
sink(&buffer); // $ hasTaintFlow="file.txt"
666666
}
667667

668668
// --- OpenOptions ---
@@ -671,7 +671,7 @@ async fn test_async_std_file() -> std::io::Result<()> {
671671
let mut f1 = async_std::fs::OpenOptions::new().open("f1.txt").await?; // $ Alert[rust/summary/taint-sources]
672672
let mut buffer = [0u8; 1024];
673673
let _bytes = f1.read(&mut buffer).await?;
674-
sink(&buffer); // $ MISSING: hasTaintFlow="f1.txt"
674+
sink(&buffer); // $ hasTaintFlow="f1.txt"
675675
}
676676

677677
Ok(())

rust/ql/test/library-tests/path-resolution/my2/my3/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ pub fn f() {
77
use super::super::h; // $ item=I25
88
use super::g; // $ item=I9
99

10-
use super::nested6_f; // $ MISSING: item=I116
10+
use super::nested6_f; // $ item=I116

rust/ql/test/library-tests/path-resolution/path-resolution.expected

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -436,6 +436,7 @@ resolvePath
436436
| my2/my3/mod.rs:8:5:8:9 | super | my2/mod.rs:1:1:19:30 | SourceFile |
437437
| my2/my3/mod.rs:8:5:8:12 | ...::g | my2/mod.rs:3:1:6:1 | fn g |
438438
| my2/my3/mod.rs:10:5:10:9 | super | my2/mod.rs:1:1:19:30 | SourceFile |
439+
| my2/my3/mod.rs:10:5:10:20 | ...::nested6_f | my2/nested2.rs:15:9:17:9 | fn f |
439440
| my.rs:3:5:3:10 | nested | my.rs:1:1:1:15 | mod nested |
440441
| my.rs:3:5:3:13 | ...::g | my/nested.rs:19:1:22:1 | fn g |
441442
| my.rs:11:5:11:5 | g | my/nested.rs:19:1:22:1 | fn g |

0 commit comments

Comments
 (0)