Skip to content

Commit cdbca06

Browse files
committed
temp
1 parent c0b5be9 commit cdbca06

7 files changed

Lines changed: 99 additions & 41 deletions

File tree

rust/ql/lib/codeql/rust/internal/typeinference/BlanketImplementation.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ module SatisfiesBlanketConstraint<
9696

9797
Type getTypeAt(TypePath path) {
9898
result = at.getTypeAt(blanketPath.appendInverse(path)) and
99-
not result instanceof UnknownType
99+
not result instanceof PseudoType
100100
}
101101

102102
string toString() { result = at.toString() + " [blanket at " + blanketPath.toString() + "]" }

rust/ql/lib/codeql/rust/internal/typeinference/FunctionType.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ module ArgIsInstantiationOf<ArgSig Arg, IsInstantiationOfInputSig<Arg, AssocFunc
329329
private class ArgSubst extends ArgFinal {
330330
Type getTypeAt(TypePath path) {
331331
result = substituteLookupTraits0(this.getEnclosingItemNode(), super.getTypeAt(path)) and
332-
not result instanceof UnknownType
332+
not result instanceof PseudoType
333333
}
334334
}
335335

rust/ql/lib/codeql/rust/internal/typeinference/Type.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -354,8 +354,6 @@ class PtrConstType extends PtrType {
354354

355355
abstract class PseudoType extends Type {
356356
override TypeParameter getPositionalTypeParameter(int i) { none() }
357-
358-
override Location getLocation() { result instanceof EmptyLocation }
359357
}
360358

361359
/**
@@ -382,6 +380,8 @@ abstract class PseudoType extends Type {
382380
*/
383381
class UnknownType extends PseudoType, TUnknownType {
384382
override string toString() { result = "(unknown type)" }
383+
384+
override Location getLocation() { result instanceof EmptyLocation }
385385
}
386386

387387
class ClosureParameterPseudoType extends PseudoType, TClosureParameterPseudoType {
@@ -392,6 +392,8 @@ class ClosureParameterPseudoType extends PseudoType, TClosureParameterPseudoType
392392
Param getParam() { result = param }
393393

394394
override string toString() { result = "(closure parameter " + param + ")" }
395+
396+
override Location getLocation() { result = param.getLocation() }
395397
}
396398

397399
/** A type parameter. */

rust/ql/lib/codeql/rust/internal/typeinference/TypeInference.qll

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,7 @@ private module Input3 implements InputSig3 {
293293

294294
class AstNode = Rust::AstNode;
295295

296+
// todo: remove
296297
TypeMention getTypeAnnotation(AstNode n) {
297298
exists(Static static |
298299
n = static and
@@ -1847,7 +1848,7 @@ private module AssocFunctionResolution {
18471848
not this.hasReceiver() and
18481849
exists(TypePath strippedTypePath, Type strippedType |
18491850
strippedType = substituteLookupTraits(this, this.getTypeAt(selfPos, strippedTypePath)) and
1850-
not strippedType instanceof UnknownType
1851+
not strippedType instanceof PseudoType
18511852
|
18521853
nonBlanketLikeCandidate(this, _, selfPos, _, _, strippedTypePath, strippedType)
18531854
or
@@ -1943,7 +1944,7 @@ private module AssocFunctionResolution {
19431944
FunctionPosition selfPos, DerefChain derefChain, BorrowKind borrow, TypePath path
19441945
) {
19451946
result = this.getSelfTypeAt(selfPos, derefChain, borrow, path) and
1946-
not result instanceof UnknownType
1947+
not result instanceof PseudoType
19471948
}
19481949

19491950
pragma[nomagic]
@@ -2602,7 +2603,7 @@ private module AssocFunctionResolution {
26022603

26032604
Type getTypeAt(TypePath path) {
26042605
result = substituteLookupTraits(afc, afc.getSelfTypeAtNoBorrow(selfPos, derefChain, path)) and
2605-
not result instanceof UnknownType
2606+
not result instanceof PseudoType
26062607
}
26072608

26082609
string toString() { result = afc + " [" + derefChain.toString() + "]" }

rust/ql/test/query-tests/security/CWE-089/CONSISTENCY/PathResolutionConsistency.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
multipleResolvedTargets
2+
| sqlx.rs:158:13:158:24 | query_args.add(...) |
3+
| sqlx.rs:160:17:160:28 | query_args.add(...) |
14
multiplePathResolutions
25
| mysql.rs:5:37:5:74 | Result::<...> |
36
| mysql.rs:26:20:26:44 | Result::<...> |
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
unexpectedModel
2+
| Unexpected summary found: <test::option::MyOption>::as_deref;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;value;dfc-generated |
3+
| Unexpected summary found: <test::option::MyOption>::as_deref;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)];value;dfc-generated |
4+
| Unexpected summary found: <test::option::MyOption>::as_deref_mut;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;value;dfc-generated |
25
expectedModel
6+
| Expected summary missing: <test::option::MyOption>::as_deref;Argument[self].Reference.Field[test::option::MyOption::MySome(0)];ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;taint;dfc-generated |
7+
| Expected summary missing: <test::option::MyOption>::map;Argument[self].Field[test::option::MyOption::MySome(0)].Reference;ReturnValue.Field[test::option::MyOption::MySome(0)].Reference;taint;dfc-generated |
8+
| Expected summary missing: <test::option::MyOption>::map;Argument[self].Field[test::option::MyOption::MySome(0)];Argument[0].Parameter[0];value;dfc-generated |

shared/typeinference/codeql/typeinference/internal/TypeInference.qll

Lines changed: 80 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -2471,7 +2471,30 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
24712471
TypeMention getReturnType();
24722472
}
24732473

2474-
/** A special pseudo type representing a particular closure parameter. */
2474+
/**
2475+
* A special pseudo type representing a particular closure parameter.
2476+
*
2477+
* This is needed in cases where the type of a closure parameter must be
2478+
* inferred from the inferred _return type_ of the closure. For example,
2479+
* in
2480+
*
2481+
* ```rust
2482+
* let c = |x| x;
2483+
* let r: i32 = c(42);
2484+
* ```
2485+
*
2486+
* by assigning `x` the pseudo type `T_x`, we can
2487+
*
2488+
* 1. bottom-up infer that `c` has type `Fn(_) -> T_x`,
2489+
* 2. this enables us to detect that contextual inference is needed, so we also
2490+
* assign `c` the type `Fn(_) -> UnknownType`,
2491+
* 3. using bottom-up inference allows us to infer that `c(42)` must have
2492+
* `UnknownType`,
2493+
* 4. using contextual inference allows us to infer that `c` has type `Fn(_) -> i32`, and
2494+
* 5. finally since `c` also has type `Fn(_) -> T_x`, we conclude that `x` has type `i32`.
2495+
*
2496+
* . Then, when we propagate type information downwards from the
2497+
*/
24752498
class ClosureParameterPseudoType extends PseudoType;
24762499

24772500
/** Gets the pseudo type corresponding to closure parameter `p`. */
@@ -2554,6 +2577,15 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
25542577
)
25552578
}
25562579

2580+
private predicate closureStep(AstNode n1, TypePath path1, Closure n2, TypePath path2) {
2581+
exists(int index, Parameter p |
2582+
n1 = p.getPattern() and
2583+
p = n2.getParameter(index) and
2584+
path1.isEmpty() and
2585+
path2 = getClosureParameterTypePath(p)
2586+
)
2587+
}
2588+
25572589
/** Provides logic for inferring certain type information. */
25582590
private module Certain {
25592591
predicate stepCertain(AstNode n1, TypePath path1, AstNode n2, TypePath path2) {
@@ -2572,27 +2604,17 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
25722604
or
25732605
n1 = n2.(ParenExpr).getExpr()
25742606
)
2575-
or
2576-
exists(Closure c, int index, Parameter p |
2577-
path1.isEmpty() and
2578-
p = c.getParameter(index)
2579-
|
2580-
n1 = p and
2581-
n2 = c and
2582-
path2 = getClosureParameterTypePath(n1)
2583-
or
2584-
n1 = p.getPattern() and
2585-
n2 = p and
2586-
path2.isEmpty()
2587-
)
25882607
}
25892608

25902609
pragma[nomagic]
25912610
private Type inferTypeFromStepCertain(AstNode n, TypePath path) {
25922611
exists(TypePath path1, AstNode n2, TypePath path2, TypePath suffix |
25932612
result = inferTypeCertain(n2, path2.appendInverse(suffix)) and
2594-
path = path1.append(suffix) and
2613+
path = path1.append(suffix)
2614+
|
25952615
stepCertain(n2, path2, n, path1)
2616+
or
2617+
closureStep(n2, path2, n, path1)
25962618
)
25972619
}
25982620

@@ -2716,8 +2738,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
27162738
private Type inferTypeFromStep(AstNode n, TypePath path) {
27172739
exists(TypePath path1, AstNode n2, TypePath path2, TypePath suffix |
27182740
result = inferType(n2, path2.appendInverse(suffix)) and
2719-
path = path1.append(suffix) and
2741+
path = path1.append(suffix)
2742+
|
27202743
step(n2, path2, n, path1)
2744+
or
2745+
closureStep(n2, path2, n, path1) and
2746+
not result = getClosureParameterPseudoType(n.(Closure).getParameter(_))
27212747
)
27222748
}
27232749

@@ -2752,8 +2778,11 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
27522778
or
27532779
exists(TypePath path1, AstNode n2, TypePath path2, TypePath suffix |
27542780
result = inferType(n2, path2.appendInverse(suffix)) and
2755-
path = path1.append(suffix) and
2781+
path = path1.append(suffix)
2782+
|
27562783
step(n, path1, n2, path2)
2784+
or
2785+
closureStep(n, path1, n2, path2)
27572786
)
27582787
}
27592788

@@ -2765,31 +2794,43 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
27652794
prefix = path.getAPrefix()
27662795
}
27672796

2768-
private Type inferClosureType(AstNode n, TypePath path) {
2797+
pragma[nomagic]
2798+
private predicate hasClosureParameterPseudoType(AstNode n, Parameter p, TypePath path) {
2799+
inferType0(n, path) = getClosureParameterPseudoType(p)
2800+
}
2801+
2802+
/**
2803+
* If the type of a parameter occurs in the inferred return type of the closure,
2804+
* allow for contextual inference based on the inferred return type to propagate
2805+
* type information into the parameter
2806+
*/
2807+
private Type inferClosureParameterType(AstNode n, TypePath path) {
27692808
exists(Closure c, Parameter p | p = c.getParameter(_) |
2770-
n = p.getPattern() and
2771-
path.isEmpty() and
2772-
result = getClosureParameterPseudoType(p)
2773-
or
2774-
exists(TypePath ret | inferType(c, ret) = getClosureParameterPseudoType(p) |
2809+
not exists(p.getType()) and
2810+
(
2811+
n = p.getPattern() and
2812+
path.isEmpty() and
2813+
result = getClosureParameterPseudoType(p)
2814+
or
27752815
n = c and
2776-
path = ret and
2816+
path = getClosureParameterTypePath(p) and
27772817
result instanceof UnknownType
27782818
or
2779-
inferType(c, ret.appendInverse(path)) = result and
27802819
n = p.getPattern() and
2820+
result = inferType(c, getClosureParameterTypePath(p).appendInverse(path)) and
27812821
not result instanceof UnknownType
27822822
)
27832823
or
2824+
hasClosureParameterPseudoType(c, p, path) and
2825+
n = c and
2826+
result instanceof UnknownType
2827+
or
27842828
exists(AstNode n0, TypePath prefix |
2785-
inferType(n0, prefix) = getClosureParameterPseudoType(p) and
2786-
result = inferTypeCertain(n0, prefix.appendInverse(path)) and
2787-
n = p.getPattern()
2829+
hasClosureParameterPseudoType(n0, p, prefix) and
2830+
result = inferType(n0, prefix.appendInverse(path)) and
2831+
n = p.getPattern() and
2832+
not result instanceof UnknownType
27882833
)
2789-
// or
2790-
// n = p.getPattern() and
2791-
// result = inferType(p, path) and
2792-
// not result instanceof UnknownType
27932834
)
27942835
}
27952836

@@ -2815,7 +2856,7 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
28152856
or
28162857
result = inferConstructionReturnType(n, path)
28172858
or
2818-
result = inferClosureType(n, path)
2859+
result = inferClosureParameterType(n, path)
28192860
or
28202861
// contextual typing: only propagate type information from surrounding context
28212862
// into a node which has an explicitly unknown type
@@ -2842,7 +2883,12 @@ module Make1<LocationSig Location, InputSig1<Location> Input1> {
28422883
|
28432884
not Certain::certainTypeConflict(n, prefix, path, result)
28442885
or
2845-
result instanceof PseudoType and not result instanceof UnknownType // todo
2886+
// propagate closure parameter pseudo types even when there is certain information,
2887+
// but prevent propagation outside of the closure
2888+
exists(Parameter p |
2889+
result = getClosureParameterPseudoType(p) and
2890+
not p = n.(Closure).getParameter(_)
2891+
)
28462892
)
28472893
or
28482894
// If `n` has an explicitly unknown type at `prefix` and at the same time a certain

0 commit comments

Comments
 (0)