mirror of
https://github.com/github/codeql.git
synced 2026-04-28 10:15:14 +02:00
Merge pull request #15484 from hvitved/csharp/qualified-delegate-extraction-fix
C#: Fix extraction of qualified delegate calls
This commit is contained in:
@@ -20,6 +20,10 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
public static Expression Create(ExpressionNodeInfo info) => new Invocation(info).TryPopulate();
|
||||
|
||||
private bool IsEventDelegateCall() => Kind == ExprKind.DELEGATE_INVOCATION && Context.GetModel(Syntax.Expression).GetSymbolInfo(Syntax.Expression).Symbol?.Kind == SymbolKind.Event;
|
||||
|
||||
private bool IsExplicitDelegateInvokeCall() => Kind == ExprKind.DELEGATE_INVOCATION && Context.GetModel(Syntax.Expression).GetSymbolInfo(Syntax.Expression).Symbol is IMethodSymbol m && m.MethodKind == MethodKind.DelegateInvoke;
|
||||
|
||||
protected override void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
if (IsNameof(Syntax))
|
||||
@@ -33,7 +37,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
var target = TargetSymbol;
|
||||
switch (Syntax.Expression)
|
||||
{
|
||||
case MemberAccessExpressionSyntax memberAccess:
|
||||
case MemberAccessExpressionSyntax memberAccess when Kind == ExprKind.METHOD_INVOCATION || IsEventDelegateCall() || IsExplicitDelegateInvokeCall():
|
||||
memberName = memberAccess.Name.Identifier.Text;
|
||||
if (Syntax.Expression.Kind() == SyntaxKind.SimpleMemberAccessExpression)
|
||||
// Qualified method call; `x.M()`
|
||||
@@ -48,7 +52,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
Create(Context, FindConditionalQualifier(memberBinding), this, child++);
|
||||
MakeConditional(trapFile);
|
||||
break;
|
||||
case SimpleNameSyntax simpleName when (Kind == ExprKind.METHOD_INVOCATION):
|
||||
case SimpleNameSyntax simpleName when Kind == ExprKind.METHOD_INVOCATION:
|
||||
// Unqualified method call; `M()`
|
||||
memberName = simpleName.Identifier.Text;
|
||||
if (target is not null && !target.IsStatic)
|
||||
|
||||
12
csharp/ql/test/library-tests/delegates/Delegates4.expected
Normal file
12
csharp/ql/test/library-tests/delegates/Delegates4.expected
Normal file
@@ -0,0 +1,12 @@
|
||||
| delegates.cs:72:13:72:20 | delegate call | delegates.cs:72:13:72:15 | access to local variable cd1 |
|
||||
| delegates.cs:74:13:74:23 | delegate call | delegates.cs:74:13:74:15 | access to local variable cd7 |
|
||||
| delegates.cs:79:22:79:26 | delegate call | delegates.cs:79:22:79:23 | access to local variable pi |
|
||||
| delegates.cs:79:30:79:35 | delegate call | delegates.cs:79:30:79:31 | access to local variable ps |
|
||||
| delegates.cs:95:13:95:25 | delegate call | delegates.cs:95:13:95:22 | access to field Field |
|
||||
| delegates.cs:96:13:96:28 | delegate call | delegates.cs:96:13:96:25 | access to property Property |
|
||||
| delegates.cs:97:13:97:20 | delegate call | delegates.cs:97:13:97:17 | access to field Field |
|
||||
| delegates.cs:98:13:98:23 | delegate call | delegates.cs:98:13:98:20 | access to property Property |
|
||||
| delegates.cs:99:13:99:28 | function pointer call | delegates.cs:99:13:99:25 | access to field FieldPtr |
|
||||
| delegates.cs:100:13:100:31 | function pointer call | delegates.cs:100:13:100:28 | access to property PropertyPtr |
|
||||
| delegates.cs:101:13:101:23 | function pointer call | delegates.cs:101:13:101:20 | access to field FieldPtr |
|
||||
| delegates.cs:102:13:102:26 | function pointer call | delegates.cs:102:13:102:23 | access to property PropertyPtr |
|
||||
4
csharp/ql/test/library-tests/delegates/Delegates4.ql
Normal file
4
csharp/ql/test/library-tests/delegates/Delegates4.ql
Normal file
@@ -0,0 +1,4 @@
|
||||
import csharp
|
||||
|
||||
from DelegateLikeCall dc
|
||||
select dc, dc.getExpr()
|
||||
@@ -249,3 +249,61 @@ delegates.cs:
|
||||
# 81| 16: [LocalVariableDeclStmt] ... ...;
|
||||
# 81| 0: [LocalVariableDeclExpr] ContextCallback d
|
||||
# 81| 0: [TypeMention] ContextCallback
|
||||
# 86| 10: [Class] E
|
||||
# 88| 5: [Field] Field
|
||||
# 88| -1: [TypeMention] Action<int>
|
||||
# 88| 1: [TypeMention] int
|
||||
# 89| 6: [Property] Property
|
||||
# 89| -1: [TypeMention] Action<int>
|
||||
# 89| 1: [TypeMention] int
|
||||
# 89| 3: [Getter] get_Property
|
||||
# 89| 4: [Setter] set_Property
|
||||
#-----| 2: (Parameters)
|
||||
# 89| 0: [Parameter] value
|
||||
# 90| 7: [Field] FieldPtr
|
||||
# 90| -1: [TypeMention] delegate* default<Int32,Void>
|
||||
# 91| 8: [Property] PropertyPtr
|
||||
# 91| -1: [TypeMention] delegate* default<Int32,Void>
|
||||
# 91| 3: [Getter] get_PropertyPtr
|
||||
# 91| 4: [Setter] set_PropertyPtr
|
||||
#-----| 2: (Parameters)
|
||||
# 91| 0: [Parameter] value
|
||||
# 93| 9: [Method] M
|
||||
# 93| -1: [TypeMention] Void
|
||||
# 94| 4: [BlockStmt] {...}
|
||||
# 95| 0: [ExprStmt] ...;
|
||||
# 95| 0: [DelegateCall] delegate call
|
||||
# 95| -1: [FieldAccess] access to field Field
|
||||
# 95| -1: [ThisAccess] this access
|
||||
# 95| 0: [IntLiteral] 0
|
||||
# 96| 1: [ExprStmt] ...;
|
||||
# 96| 0: [DelegateCall] delegate call
|
||||
# 96| -1: [PropertyCall] access to property Property
|
||||
# 96| -1: [ThisAccess] this access
|
||||
# 96| 0: [IntLiteral] 0
|
||||
# 97| 2: [ExprStmt] ...;
|
||||
# 97| 0: [DelegateCall] delegate call
|
||||
# 97| -1: [FieldAccess] access to field Field
|
||||
# 97| 0: [IntLiteral] 0
|
||||
# 98| 3: [ExprStmt] ...;
|
||||
# 98| 0: [DelegateCall] delegate call
|
||||
# 98| -1: [PropertyCall] access to property Property
|
||||
# 98| 0: [IntLiteral] 0
|
||||
# 99| 4: [ExprStmt] ...;
|
||||
# 99| 0: [FunctionPointerCall] function pointer call
|
||||
# 99| -1: [FieldAccess] access to field FieldPtr
|
||||
# 99| -1: [ThisAccess] this access
|
||||
# 99| 0: [IntLiteral] 0
|
||||
# 100| 5: [ExprStmt] ...;
|
||||
# 100| 0: [FunctionPointerCall] function pointer call
|
||||
# 100| -1: [PropertyCall] access to property PropertyPtr
|
||||
# 100| -1: [ThisAccess] this access
|
||||
# 100| 0: [IntLiteral] 0
|
||||
# 101| 6: [ExprStmt] ...;
|
||||
# 101| 0: [FunctionPointerCall] function pointer call
|
||||
# 101| -1: [FieldAccess] access to field FieldPtr
|
||||
# 101| 0: [IntLiteral] 0
|
||||
# 102| 7: [ExprStmt] ...;
|
||||
# 102| 0: [FunctionPointerCall] function pointer call
|
||||
# 102| -1: [PropertyCall] access to property PropertyPtr
|
||||
# 102| 0: [IntLiteral] 0
|
||||
|
||||
@@ -83,4 +83,23 @@ namespace Delegates
|
||||
|
||||
}
|
||||
|
||||
unsafe class E
|
||||
{
|
||||
Action<int> Field;
|
||||
Action<int> Property { get; set; }
|
||||
delegate*<int, void> FieldPtr;
|
||||
delegate*<int, void> PropertyPtr { get; set; }
|
||||
|
||||
unsafe void M()
|
||||
{
|
||||
this.Field(0);
|
||||
this.Property(0);
|
||||
Field(0);
|
||||
Property(0);
|
||||
this.FieldPtr(0);
|
||||
this.PropertyPtr(0);
|
||||
FieldPtr(0);
|
||||
PropertyPtr(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user