mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
Python points-to: Fix up neverReturns() and return value of __import__().
This commit is contained in:
@@ -52,6 +52,7 @@ abstract class CallableObjectInternal extends ObjectInternal {
|
||||
|
||||
override int length() { none() }
|
||||
|
||||
abstract predicate neverReturns();
|
||||
}
|
||||
|
||||
|
||||
@@ -146,6 +147,10 @@ class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFuncti
|
||||
result.getNode() = this.getScope().getArgByName(name)
|
||||
}
|
||||
|
||||
|
||||
override predicate neverReturns() {
|
||||
InterProceduralPointsTo::neverReturns(this.getScope())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -220,9 +225,11 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
|
||||
or
|
||||
func = Builtin::builtin("intern") and result = Builtin::special("str")
|
||||
or
|
||||
func = Builtin::builtin("__import__") and result = Builtin::special("ModuleType")
|
||||
or
|
||||
/* Fix a few minor inaccuracies in the CPython analysis */
|
||||
ext_rettype(func, result) and not (
|
||||
func = Builtin::builtin("__import__") and result = Builtin::special("NoneType")
|
||||
func = Builtin::builtin("__import__")
|
||||
or
|
||||
func = Builtin::builtin("compile") and result = Builtin::special("NoneType")
|
||||
or
|
||||
@@ -251,6 +258,10 @@ class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunc
|
||||
none()
|
||||
}
|
||||
|
||||
override predicate neverReturns() {
|
||||
this = Module::named("sys").attr("exit")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -334,6 +345,8 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
|
||||
none()
|
||||
}
|
||||
|
||||
override predicate neverReturns() { none() }
|
||||
|
||||
}
|
||||
|
||||
class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
|
||||
@@ -405,6 +418,10 @@ class BoundMethodObjectInternal extends CallableObjectInternal, TBoundMethod {
|
||||
result = this.getFunction().getParameterByName(name)
|
||||
}
|
||||
|
||||
override predicate neverReturns() {
|
||||
this.getFunction().neverReturns()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -103,8 +103,7 @@ class CallableValue extends Value {
|
||||
}
|
||||
|
||||
predicate neverReturns() {
|
||||
// TO DO..
|
||||
none()
|
||||
this.(CallableObjectInternal).neverReturns()
|
||||
}
|
||||
|
||||
Function getScope() {
|
||||
|
||||
@@ -1022,6 +1022,23 @@ module InterProceduralPointsTo {
|
||||
BaseFlow::reaches_exit(evar)
|
||||
}
|
||||
|
||||
/** INTERNAL -- Use `FunctionObject.neverReturns()` instead.
|
||||
* Whether function `func` never returns. Slightly conservative approximation, this predicate may be false
|
||||
* for a function that can never return. */
|
||||
cached predicate neverReturns(Function f) {
|
||||
/* A Python function never returns if it has no normal exits that are not dominated by a
|
||||
* call to a function which itself never returns.
|
||||
*/
|
||||
forall(BasicBlock exit |
|
||||
exit = f.getANormalExit().getBasicBlock() |
|
||||
exists(FunctionObject callee, BasicBlock call |
|
||||
callee.getACall().getBasicBlock() = call and
|
||||
callee.neverReturns() and
|
||||
call.dominates(exit)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/** Gets the `value, origin` that `f` would refer to if it has not been assigned some other value */
|
||||
|
||||
@@ -1268,7 +1268,7 @@ library module TaintFlowImplementation {
|
||||
|
|
||||
test.getSense() = true and not exists(kind.getClass())
|
||||
or
|
||||
test.getSense() = true and kind.getClass().getASuperType() = cls
|
||||
test.getSense() = true and kind.getType().getASuperType() = cls
|
||||
or
|
||||
test.getSense() = false and not kind.getType().getASuperType() = cls
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user