Skip to content

Commit 507bbf5

Browse files
committed
Rust: Path resolution improvements
1 parent 1d0e427 commit 507bbf5

File tree

6 files changed

+482
-410
lines changed

6 files changed

+482
-410
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(...) |

0 commit comments

Comments
 (0)