mirror of
https://github.com/github/codeql.git
synced 2025-12-20 10:46:30 +01:00
Merge pull request #4077 from yoff/MagicMethods
Python: Add support for magic methods
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
private import python
|
||||
private import DataFlowPublic
|
||||
import semmle.python.SpecialMethods
|
||||
|
||||
//--------
|
||||
// Data flow graph
|
||||
@@ -164,17 +165,67 @@ class DataFlowClassValue extends DataFlowCallable, TClassValue {
|
||||
override string getName() { result = c.getName() }
|
||||
}
|
||||
|
||||
/** Represents a call to a callable */
|
||||
class DataFlowCall extends CallNode {
|
||||
DataFlowCallable callable;
|
||||
newtype TDataFlowCall =
|
||||
TCallNode(CallNode call) or
|
||||
TSpecialCall(SpecialMethodCallNode special)
|
||||
|
||||
DataFlowCall() { this = callable.getACall() }
|
||||
abstract class DataFlowCall extends TDataFlowCall {
|
||||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Get the callable to which this call goes. */
|
||||
DataFlowCallable getCallable() { result = callable }
|
||||
abstract DataFlowCallable getCallable();
|
||||
|
||||
/** Get the specified argument to this call. */
|
||||
abstract ControlFlowNode getArg(int n);
|
||||
|
||||
/** Get the control flow node representing this call. */
|
||||
abstract ControlFlowNode getNode();
|
||||
|
||||
/** Gets the enclosing callable of this call. */
|
||||
DataFlowCallable getEnclosingCallable() { result.getScope() = this.getNode().getScope() }
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
}
|
||||
|
||||
/** Represents a call to a callable. */
|
||||
class CallNodeCall extends DataFlowCall, TCallNode {
|
||||
CallNode call;
|
||||
DataFlowCallable callable;
|
||||
|
||||
CallNodeCall() {
|
||||
this = TCallNode(call) and
|
||||
call = callable.getACall()
|
||||
}
|
||||
|
||||
override string toString() { result = call.toString() }
|
||||
|
||||
override ControlFlowNode getArg(int n) { result = call.getArg(n) }
|
||||
|
||||
override ControlFlowNode getNode() { result = call }
|
||||
|
||||
override DataFlowCallable getCallable() { result = callable }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getNode().getScope() }
|
||||
}
|
||||
|
||||
/** Represents a call to a special method. */
|
||||
class SpecialCall extends DataFlowCall, TSpecialCall {
|
||||
SpecialMethodCallNode special;
|
||||
|
||||
SpecialCall() { this = TSpecialCall(special) }
|
||||
|
||||
override string toString() { result = special.toString() }
|
||||
|
||||
override ControlFlowNode getArg(int n) { result = special.(SpecialMethod::Potential).getArg(n) }
|
||||
|
||||
override ControlFlowNode getNode() { result = special }
|
||||
|
||||
override DataFlowCallable getCallable() {
|
||||
result = TCallableValue(special.getResolvedSpecialMethod())
|
||||
}
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() {
|
||||
result.getScope() = special.getNode().getScope()
|
||||
}
|
||||
}
|
||||
|
||||
/** A data flow node that represents a call argument. */
|
||||
@@ -227,7 +278,7 @@ class OutNode extends CfgNode {
|
||||
* `kind`.
|
||||
*/
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
call = result.getNode() and
|
||||
call.getNode() = result.getNode() and
|
||||
kind = TNormalReturnKind()
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user