Skip to content

Commit 5c5046a

Browse files
committed
C#: Add dispatch logic for calling extensions accessors as methods.
1 parent bb4a55b commit 5c5046a

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ private module Internal {
8787
newtype TDispatchCall =
8888
TDispatchMethodCall(MethodCall mc) {
8989
not isReflectionCall(mc, _, _, _, _) and
90-
not mc.isLateBound()
90+
not mc.isLateBound() and
91+
not isExtensionAccessorCall(mc)
9192
} or
9293
TDispatchAccessorCall(AccessorCall ac) or
9394
TDispatchOperatorCall(OperatorCall oc) { not oc.isLateBound() } or
@@ -110,7 +111,8 @@ private module Internal {
110111
c instanceof ConstructorInitializer
111112
or
112113
c instanceof LocalFunctionCall
113-
}
114+
} or
115+
TDispatchExtensionAccessorCall(MethodCall mc) { isExtensionAccessorCall(mc) }
114116

115117
cached
116118
Expr getCall(DispatchCall dc) { result = dc.(DispatchCallImpl).getCall() }
@@ -142,6 +144,8 @@ private module Internal {
142144

143145
import Cached
144146

147+
private predicate isExtensionAccessorCall(MethodCall mc) { exists(mc.getTargetAccessor()) }
148+
145149
/**
146150
* Holds if `mc` is a reflection call to a method named `name`, where
147151
* `object` is the object on which to invoke the method (`null` if a
@@ -819,6 +823,33 @@ private module Internal {
819823
override Method getAStaticTarget() { result = this.getCall().getTarget() }
820824
}
821825

826+
/**
827+
* A call to an extension accessor method.
828+
*/
829+
private class DispatchExtensionAccessorCall extends DispatchCallImpl,
830+
TDispatchExtensionAccessorCall
831+
{
832+
override MethodCall getCall() { this = TDispatchExtensionAccessorCall(result) }
833+
834+
private Expr getArgumentForParameter(Parameter p) {
835+
this.getCall().getTargetAccessor().getAParameter() = p and
836+
result = this.getCall().getArgument(p.getPosition())
837+
}
838+
839+
override Expr getArgument(int i) {
840+
exists(MethodCall call, Parameter p | call = this.getCall() |
841+
p = call.getTargetAccessor().getParameter(i) and
842+
result = this.getArgumentForParameter(p)
843+
)
844+
}
845+
846+
override Expr getQualifier() { result = this.getCall().getQualifier() }
847+
848+
override Accessor getAStaticTarget() { result = this.getCall().getTargetAccessor() }
849+
850+
override RuntimeCallable getADynamicTarget() { result = this.getAStaticTarget() }
851+
}
852+
822853
/**
823854
* An ordinary operator call.
824855
*

0 commit comments

Comments
 (0)