mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Python: Remove points-to from Expr
This commit is contained in:
@@ -8,7 +8,8 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from Expr e, string name
|
||||
from ExprWithPointsTo e, string name
|
||||
where e.pointsTo(Value::named(name)) and not name.charAt(_) = "."
|
||||
select e
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from ExceptStmt ex, ClassValue cls
|
||||
where
|
||||
cls.getName() = "MyExceptionClass" and
|
||||
ex.getType().pointsTo(cls)
|
||||
ex.getType().(ExprWithPointsTo).pointsTo(cls)
|
||||
select ex
|
||||
|
||||
@@ -9,10 +9,11 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from IfExp e, ClassObject cls1, ClassObject cls2
|
||||
where
|
||||
e.getBody().refersTo(_, cls1, _) and
|
||||
e.getOrelse().refersTo(_, cls2, _) and
|
||||
e.getBody().(ExprWithPointsTo).refersTo(_, cls1, _) and
|
||||
e.getOrelse().(ExprWithPointsTo).refersTo(_, cls2, _) and
|
||||
cls1 != cls2
|
||||
select e
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from Call new, ClassValue cls
|
||||
where
|
||||
cls.getName() = "MyClass" and
|
||||
new.getFunc().pointsTo(cls)
|
||||
new.getFunc().(ExprWithPointsTo).pointsTo(cls)
|
||||
select new
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from AstNode print
|
||||
where
|
||||
@@ -13,5 +14,5 @@ where
|
||||
print instanceof Print
|
||||
or
|
||||
/* Python 3 or with `from __future__ import print_function` */
|
||||
print.(Call).getFunc().pointsTo(Value::named("print"))
|
||||
print.(Call).getFunc().(ExprWithPointsTo).pointsTo(Value::named("print"))
|
||||
select print
|
||||
|
||||
@@ -8,9 +8,10 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from Raise raise, ClassValue ex
|
||||
where
|
||||
ex.getName() = "AnException" and
|
||||
raise.getException().pointsTo(ex.getASuperType())
|
||||
raise.getException().(ExprWithPointsTo).pointsTo(ex.getASuperType())
|
||||
select raise, "Don't raise instances of 'AnException'"
|
||||
|
||||
@@ -119,3 +119,75 @@ private predicate varHasCompletePointsToSet(SsaVariable var) {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An extension of `Expr` that provides points-to predicates.
|
||||
*/
|
||||
class ExprWithPointsTo extends Expr {
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Gets what this expression might "refer-to". Performs a combination of localized (intra-procedural) points-to
|
||||
* analysis and global module-level analysis. This points-to analysis favours precision over recall. It is highly
|
||||
* precise, but may not provide information for a significant number of flow-nodes.
|
||||
* If the class is unimportant then use `refersTo(value)` or `refersTo(value, origin)` instead.
|
||||
* NOTE: For complex dataflow, involving multiple stages of points-to analysis, it may be more precise to use
|
||||
* `ControlFlowNode.refersTo(...)` instead.
|
||||
*/
|
||||
predicate refersTo(Object obj, ClassObject cls, AstNode origin) {
|
||||
this.refersTo(_, obj, cls, origin)
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Gets what this expression might "refer-to" in the given `context`.
|
||||
*/
|
||||
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
|
||||
this.getAFlowNode()
|
||||
.(ControlFlowNodeWithPointsTo)
|
||||
.refersTo(context, obj, cls, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Holds if this expression might "refer-to" to `value` which is from `origin`
|
||||
* Unlike `this.refersTo(value, _, origin)`, this predicate includes results
|
||||
* where the class cannot be inferred.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate refersTo(Object obj, AstNode origin) {
|
||||
this.getAFlowNode().(ControlFlowNodeWithPointsTo).refersTo(obj, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Equivalent to `this.refersTo(value, _)`
|
||||
*/
|
||||
predicate refersTo(Object obj) { this.refersTo(obj, _) }
|
||||
|
||||
/**
|
||||
* Holds if this expression might "point-to" to `value` which is from `origin`
|
||||
* in the given `context`.
|
||||
*/
|
||||
predicate pointsTo(Context context, Value value, AstNode origin) {
|
||||
this.getAFlowNode()
|
||||
.(ControlFlowNodeWithPointsTo)
|
||||
.pointsTo(context, value, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression might "point-to" to `value` which is from `origin`.
|
||||
*/
|
||||
predicate pointsTo(Value value, AstNode origin) {
|
||||
this.getAFlowNode().(ControlFlowNodeWithPointsTo).pointsTo(value, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression might "point-to" to `value`.
|
||||
*/
|
||||
predicate pointsTo(Value value) { this.pointsTo(value, _) }
|
||||
|
||||
/** Gets a value that this expression might "point-to". */
|
||||
Value pointsTo() { this.pointsTo(result) }
|
||||
|
||||
override string getAQlClass() { none() }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
private import semmle.python.pointsto.PointsTo
|
||||
private import semmle.python.objects.ObjectInternal
|
||||
private import python
|
||||
private import semmle.python.internal.CachedStages
|
||||
|
||||
/** An expression */
|
||||
@@ -53,71 +50,6 @@ class Expr extends Expr_, AstNode {
|
||||
Expr getASubExpression() { none() }
|
||||
|
||||
override AstNode getAChildNode() { result = this.getASubExpression() }
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Gets what this expression might "refer-to". Performs a combination of localized (intra-procedural) points-to
|
||||
* analysis and global module-level analysis. This points-to analysis favours precision over recall. It is highly
|
||||
* precise, but may not provide information for a significant number of flow-nodes.
|
||||
* If the class is unimportant then use `refersTo(value)` or `refersTo(value, origin)` instead.
|
||||
* NOTE: For complex dataflow, involving multiple stages of points-to analysis, it may be more precise to use
|
||||
* `ControlFlowNode.refersTo(...)` instead.
|
||||
*/
|
||||
predicate refersTo(Object obj, ClassObject cls, AstNode origin) {
|
||||
this.refersTo(_, obj, cls, origin)
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Gets what this expression might "refer-to" in the given `context`.
|
||||
*/
|
||||
predicate refersTo(Context context, Object obj, ClassObject cls, AstNode origin) {
|
||||
this.getAFlowNode()
|
||||
.(ControlFlowNodeWithPointsTo)
|
||||
.refersTo(context, obj, cls, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Holds if this expression might "refer-to" to `value` which is from `origin`
|
||||
* Unlike `this.refersTo(value, _, origin)`, this predicate includes results
|
||||
* where the class cannot be inferred.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate refersTo(Object obj, AstNode origin) {
|
||||
this.getAFlowNode().(ControlFlowNodeWithPointsTo).refersTo(obj, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* NOTE: `refersTo` will be deprecated in 2019. Use `pointsTo` instead.
|
||||
* Equivalent to `this.refersTo(value, _)`
|
||||
*/
|
||||
predicate refersTo(Object obj) { this.refersTo(obj, _) }
|
||||
|
||||
/**
|
||||
* Holds if this expression might "point-to" to `value` which is from `origin`
|
||||
* in the given `context`.
|
||||
*/
|
||||
predicate pointsTo(Context context, Value value, AstNode origin) {
|
||||
this.getAFlowNode()
|
||||
.(ControlFlowNodeWithPointsTo)
|
||||
.pointsTo(context, value, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression might "point-to" to `value` which is from `origin`.
|
||||
*/
|
||||
predicate pointsTo(Value value, AstNode origin) {
|
||||
this.getAFlowNode().(ControlFlowNodeWithPointsTo).pointsTo(value, origin.getAFlowNode())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression might "point-to" to `value`.
|
||||
*/
|
||||
predicate pointsTo(Value value) { this.pointsTo(value, _) }
|
||||
|
||||
/** Gets a value that this expression might "point-to". */
|
||||
Value pointsTo() { this.pointsTo(result) }
|
||||
}
|
||||
|
||||
/** An assignment expression, such as `x := y` */
|
||||
|
||||
@@ -124,7 +124,7 @@ class ClassMetrics extends Class {
|
||||
)
|
||||
or
|
||||
exists(Function f, Call c, ClassObject cls | c.getScope() = f and f.getScope() = this |
|
||||
c.getFunc().refersTo(cls) and
|
||||
c.getFunc().(ExprWithPointsTo).refersTo(cls) and
|
||||
cls.getPyClass() = other
|
||||
)
|
||||
)
|
||||
@@ -293,7 +293,7 @@ class ModuleMetrics extends Module {
|
||||
)
|
||||
or
|
||||
exists(Function f, Call c, ClassObject cls | c.getScope() = f and f.getScope() = this |
|
||||
c.getFunc().refersTo(cls) and
|
||||
c.getFunc().(ExprWithPointsTo).refersTo(cls) and
|
||||
cls.getPyClass().getEnclosingModule() = other
|
||||
)
|
||||
)
|
||||
|
||||
@@ -697,7 +697,9 @@ abstract class FunctionValue extends CallableValue {
|
||||
exists(ClassValue cls, string name |
|
||||
cls.declaredAttribute(name) = this and
|
||||
name != "__new__" and
|
||||
exists(Expr expr, AstNode origin | expr.pointsTo(this, origin) | not origin instanceof Lambda)
|
||||
exists(ExprWithPointsTo expr, AstNode origin | expr.pointsTo(this, origin) |
|
||||
not origin instanceof Lambda
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
/** Holds if `notimpl` refers to `NotImplemented` or `NotImplemented()` in the `raise` statement */
|
||||
predicate use_of_not_implemented_in_raise(Raise raise, Expr notimpl) {
|
||||
predicate use_of_not_implemented_in_raise(Raise raise, ExprWithPointsTo notimpl) {
|
||||
notimpl.pointsTo(Value::named("NotImplemented")) and
|
||||
(
|
||||
notimpl = raise.getException() or
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
/** Whether the raise statement 'r' raises 'type' from origin 'orig' */
|
||||
predicate type_or_typeof(Raise r, ClassValue type, AstNode orig) {
|
||||
exists(Expr exception | exception = r.getRaised() |
|
||||
exists(ExprWithPointsTo exception | exception = r.getRaised() |
|
||||
exception.pointsTo(type, orig)
|
||||
or
|
||||
not exists(ClassValue exc_type | exception.pointsTo(exc_type)) and
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
/** INTERNAL - Methods used by queries that test whether functions are invoked correctly. */
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import Testing.Mox
|
||||
|
||||
private int varargs_length_objectapi(Call call) {
|
||||
not exists(call.getStarargs()) and result = 0
|
||||
or
|
||||
exists(TupleObject t | call.getStarargs().refersTo(t) | result = t.getLength())
|
||||
exists(TupleObject t | call.getStarargs().(ExprWithPointsTo).refersTo(t) | result = t.getLength())
|
||||
or
|
||||
result = count(call.getStarargs().(List).getAnElt())
|
||||
}
|
||||
@@ -14,7 +15,7 @@ private int varargs_length_objectapi(Call call) {
|
||||
private int varargs_length(Call call) {
|
||||
not exists(call.getStarargs()) and result = 0
|
||||
or
|
||||
exists(TupleValue t | call.getStarargs().pointsTo(t) | result = t.length())
|
||||
exists(TupleValue t | call.getStarargs().(ExprWithPointsTo).pointsTo(t) | result = t.length())
|
||||
or
|
||||
result = count(call.getStarargs().(List).getAnElt())
|
||||
}
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import semmle.python.strings
|
||||
|
||||
from Expr e, ClassValue t
|
||||
from ExprWithPointsTo e, ClassValue t
|
||||
where
|
||||
exists(BinaryExpr b |
|
||||
b.getOp() instanceof Mod and
|
||||
|
||||
@@ -72,7 +72,7 @@ predicate is_unhashable(ControlFlowNodeWithPointsTo f, ClassValue cls, ControlFl
|
||||
predicate typeerror_is_caught(ControlFlowNode f) {
|
||||
exists(Try try |
|
||||
try.getBody().contains(f.getNode()) and
|
||||
try.getAHandler().getType().pointsTo(ClassValue::typeError())
|
||||
try.getAHandler().getType().(ExprWithPointsTo).pointsTo(ClassValue::typeError())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -76,12 +76,12 @@ private predicate universally_interned_value(Expr e) {
|
||||
}
|
||||
|
||||
/** Holds if the expression `e` points to an interned constant in CPython. */
|
||||
predicate cpython_interned_constant(Expr e) {
|
||||
predicate cpython_interned_constant(ExprWithPointsTo e) {
|
||||
exists(Expr const | e.pointsTo(_, const) | cpython_interned_value(const))
|
||||
}
|
||||
|
||||
/** Holds if the expression `e` points to a value that can be reasonably expected to be interned across all implementations of Python. */
|
||||
predicate universally_interned_constant(Expr e) {
|
||||
predicate universally_interned_constant(ExprWithPointsTo e) {
|
||||
exists(Expr const | e.pointsTo(_, const) | universally_interned_value(const))
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ predicate invalid_portable_is_comparison(Compare comp, Cmpop op, ClassValue cls)
|
||||
)
|
||||
) and
|
||||
// OK to use 'is' when comparing items from a known set of objects
|
||||
not exists(Expr left, Expr right, Value val |
|
||||
not exists(ExprWithPointsTo left, ExprWithPointsTo right, Value val |
|
||||
comp.compares(left, op, right) and
|
||||
exists(ImmutableLiteral il | il = val.(ConstantObjectInternal).getLiteral())
|
||||
|
|
||||
@@ -134,7 +134,7 @@ predicate invalid_portable_is_comparison(Compare comp, Cmpop op, ClassValue cls)
|
||||
)
|
||||
) and
|
||||
// OK to use 'is' when comparing with a member of an enum
|
||||
not exists(Expr left, Expr right, AstNode origin |
|
||||
not exists(ExprWithPointsTo left, ExprWithPointsTo right, AstNode origin |
|
||||
comp.compares(left, op, right) and
|
||||
enum_member(origin)
|
||||
|
|
||||
|
||||
@@ -12,9 +12,10 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import Exceptions.NotImplemented
|
||||
|
||||
from Call c, Value v, ClassValue t, Expr f, AstNode origin
|
||||
from Call c, Value v, ClassValue t, ExprWithPointsTo f, AstNode origin
|
||||
where
|
||||
f = c.getFunc() and
|
||||
f.pointsTo(v, origin) and
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
/* f consists of a single return statement, whose value is a call. The arguments of the call are exactly the parameters of f */
|
||||
predicate simple_wrapper(Lambda l, Expr wrapped) {
|
||||
@@ -39,7 +40,7 @@ predicate simple_wrapper(Lambda l, Expr wrapped) {
|
||||
}
|
||||
|
||||
/* The expression called will refer to the same object if evaluated when the lambda is created or when the lambda is executed. */
|
||||
predicate unnecessary_lambda(Lambda l, Expr e) {
|
||||
predicate unnecessary_lambda(Lambda l, ExprWithPointsTo e) {
|
||||
simple_wrapper(l, e) and
|
||||
(
|
||||
/* plain class */
|
||||
|
||||
@@ -14,20 +14,21 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
import LegacyPointsTo
|
||||
import semmle.python.objects.ObjectInternal
|
||||
import semmle.python.strings
|
||||
|
||||
predicate string_format(BinaryExpr operation, StringLiteral str, Value args, AstNode origin) {
|
||||
operation.getOp() instanceof Mod and
|
||||
exists(Context ctx |
|
||||
operation.getLeft().pointsTo(ctx, _, str) and
|
||||
operation.getRight().pointsTo(ctx, args, origin)
|
||||
operation.getLeft().(ExprWithPointsTo).pointsTo(ctx, _, str) and
|
||||
operation.getRight().(ExprWithPointsTo).pointsTo(ctx, args, origin)
|
||||
)
|
||||
}
|
||||
|
||||
int sequence_length(Value args) {
|
||||
/* Guess length of sequence */
|
||||
exists(Tuple seq | seq.pointsTo(args, _) |
|
||||
exists(Tuple seq | seq.(ExprWithPointsTo).pointsTo(args, _) |
|
||||
result = strictcount(seq.getAnElt()) and
|
||||
not seq.getAnElt() instanceof Starred
|
||||
)
|
||||
|
||||
@@ -12,8 +12,9 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from Return r, Expr rv
|
||||
from Return r, ExprWithPointsTo rv
|
||||
where
|
||||
exists(Function init | init.isInitMethod() and r.getScope() = init) and
|
||||
r.getValue() = rv and
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import Testing.Mox
|
||||
|
||||
predicate is_used(Call c) {
|
||||
@@ -31,10 +32,12 @@ from Call c, FunctionValue func
|
||||
where
|
||||
/* Call result is used, but callee is a procedure */
|
||||
is_used(c) and
|
||||
c.getFunc().pointsTo(func) and
|
||||
c.getFunc().(ExprWithPointsTo).pointsTo(func) and
|
||||
func.getScope().isProcedure() and
|
||||
/* All callees are procedures */
|
||||
forall(FunctionValue callee | c.getFunc().pointsTo(callee) | callee.getScope().isProcedure()) and
|
||||
forall(FunctionValue callee | c.getFunc().(ExprWithPointsTo).pointsTo(callee) |
|
||||
callee.getScope().isProcedure()
|
||||
) and
|
||||
/* Mox return objects have an `AndReturn` method */
|
||||
not useOfMoxInModule(c.getEnclosingModule())
|
||||
select c, "The result of $@ is used even though it is always None.", func, func.getQualifiedName()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
predicate is_import_time(Stmt s) { not s.getScope+() instanceof Function }
|
||||
|
||||
@@ -21,7 +22,7 @@ predicate circular_import(ModuleValue m1, ModuleValue m2) {
|
||||
ModuleValue stmt_imports(ImportingStmt s) {
|
||||
exists(string name | result.importedAs(name) and not name = "__main__" |
|
||||
name = s.getAnImportedModuleName() and
|
||||
s.getASubExpression().pointsTo(result) and
|
||||
s.getASubExpression().(ExprWithPointsTo).pointsTo(result) and
|
||||
not result.isPackage()
|
||||
)
|
||||
}
|
||||
@@ -57,7 +58,7 @@ predicate import_time_transitive_import(ModuleValue base, Stmt imp, ModuleValue
|
||||
* Returns import-time usages of module 'm' in module 'enclosing'
|
||||
*/
|
||||
predicate import_time_module_use(ModuleValue m, ModuleValue enclosing, Expr use, string attr) {
|
||||
exists(Expr mod |
|
||||
exists(ExprWithPointsTo mod |
|
||||
use.getEnclosingModule() = enclosing.getScope() and
|
||||
not use.getScope+() instanceof Function and
|
||||
mod.pointsTo(m) and
|
||||
@@ -90,7 +91,8 @@ predicate is_used_in_annotation(Expr use) {
|
||||
*/
|
||||
predicate is_annotation_with_from_future_import_annotations(Expr use) {
|
||||
exists(ImportMember i | i.getScope() = use.getEnclosingModule() |
|
||||
i.getModule().pointsTo().getName() = "__future__" and i.getName() = "annotations"
|
||||
i.getModule().(ExprWithPointsTo).pointsTo().getName() = "__future__" and
|
||||
i.getName() = "annotations"
|
||||
) and
|
||||
is_used_in_annotation(use)
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
/**
|
||||
* Holds if the module `name` was deprecated in Python version `major`.`minor`,
|
||||
@@ -79,7 +80,7 @@ where
|
||||
name = imp.getName() and
|
||||
deprecated_module(name, instead, _, _) and
|
||||
not exists(Try try, ExceptStmt except | except = try.getAHandler() |
|
||||
except.getType().pointsTo(ClassValue::importError()) and
|
||||
except.getType().(ExprWithPointsTo).pointsTo(ClassValue::importError()) and
|
||||
except.containsInScope(imp)
|
||||
)
|
||||
select imp, deprecation_message(name) + replacement_message(name)
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import Variables.Definition
|
||||
import semmle.python.ApiGraphs
|
||||
|
||||
@@ -94,7 +95,7 @@ private string typehint_annotation_in_module(Module module_scope) {
|
||||
or
|
||||
annotation = any(FunctionExpr f).getReturns().getASubExpression*()
|
||||
|
|
||||
annotation.pointsTo(Value::forString(result)) and
|
||||
annotation.(ExprWithPointsTo).pointsTo(Value::forString(result)) and
|
||||
annotation.getEnclosingModule() = module_scope
|
||||
)
|
||||
}
|
||||
@@ -144,7 +145,7 @@ predicate unused_import(Import imp, Variable name) {
|
||||
not is_pytest_fixture(imp, name) and
|
||||
// Only consider import statements that actually point-to something (possibly an unknown module).
|
||||
// If this is not the case, it's likely that the import statement never gets executed.
|
||||
imp.getAName().getValue().pointsTo(_)
|
||||
imp.getAName().getValue().(ExprWithPointsTo).pointsTo(_)
|
||||
}
|
||||
|
||||
from Stmt s, Variable name
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
private int len(ExprList el) { result = count(el.getAnItem()) }
|
||||
|
||||
@@ -41,7 +42,7 @@ predicate mismatched_tuple_rhs(Assign a, int lcount, int rcount, Location loc) {
|
||||
a.getATarget().(Tuple).getElts() = l or
|
||||
a.getATarget().(List).getElts() = l
|
||||
) and
|
||||
a.getValue().pointsTo(r, origin) and
|
||||
a.getValue().(ExprWithPointsTo).pointsTo(r, origin) and
|
||||
loc = origin.getLocation() and
|
||||
lcount = len(l) and
|
||||
rcount = r.length() and
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
predicate assignment(AssignStmt a, Expr left, Expr right) {
|
||||
a.getATarget() = left and a.getValue() = right
|
||||
@@ -57,7 +58,9 @@ predicate same_name(Name n1, Name n2) {
|
||||
not maybe_defined_in_outer_scope(n2)
|
||||
}
|
||||
|
||||
ClassValue value_type(Attribute a) { a.getObject().pointsTo().getClass() = result }
|
||||
ClassValue value_type(Attribute a) {
|
||||
a.getObject().(ExprWithPointsTo).pointsTo().getClass() = result
|
||||
}
|
||||
|
||||
predicate is_property_access(Attribute a) {
|
||||
value_type(a).lookup(a.getName()) instanceof PropertyValue
|
||||
@@ -87,7 +90,7 @@ predicate pyflakes_commented(AssignStmt assignment) {
|
||||
|
||||
predicate side_effecting_lhs(Attribute lhs) {
|
||||
exists(ClassValue cls, ClassValue decl |
|
||||
lhs.getObject().pointsTo().getClass() = cls and
|
||||
lhs.getObject().(ExprWithPointsTo).pointsTo().getClass() = cls and
|
||||
decl = cls.getASuperType() and
|
||||
not decl.isBuiltin()
|
||||
|
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
predicate understood_attribute(Attribute attr, ClassValue cls, ClassValue attr_cls) {
|
||||
exists(string name | attr.getName() = name |
|
||||
attr.getObject().pointsTo().getClass() = cls and
|
||||
attr.getObject().(ExprWithPointsTo).pointsTo().getClass() = cls and
|
||||
cls.attr(name).getClass() = attr_cls
|
||||
)
|
||||
}
|
||||
@@ -30,7 +31,7 @@ predicate side_effecting_attribute(Attribute attr) {
|
||||
}
|
||||
|
||||
predicate maybe_side_effecting_attribute(Attribute attr) {
|
||||
not understood_attribute(attr, _, _) and not attr.pointsTo(_)
|
||||
not understood_attribute(attr, _, _) and not attr.(ExprWithPointsTo).pointsTo(_)
|
||||
or
|
||||
side_effecting_attribute(attr)
|
||||
}
|
||||
@@ -68,7 +69,7 @@ predicate side_effecting_binary(Expr b) {
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate binary_operator_special_method(
|
||||
BinaryExpr b, Expr sub, ClassValue cls, string method_name
|
||||
BinaryExpr b, ExprWithPointsTo sub, ClassValue cls, string method_name
|
||||
) {
|
||||
method_name = special_method() and
|
||||
sub = b.getLeft() and
|
||||
@@ -77,7 +78,9 @@ private predicate binary_operator_special_method(
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate comparison_special_method(Compare b, Expr sub, ClassValue cls, string method_name) {
|
||||
private predicate comparison_special_method(
|
||||
Compare b, ExprWithPointsTo sub, ClassValue cls, string method_name
|
||||
) {
|
||||
exists(Cmpop op |
|
||||
b.compares(sub, op, _) and
|
||||
method_name = op.getSpecialMethodName()
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
predicate typing_import(ImportingStmt is) {
|
||||
exists(Module m |
|
||||
@@ -33,7 +34,11 @@ predicate unique_yield(Stmt s) {
|
||||
/** Holds if `contextlib.suppress` may be used in the same scope as `s` */
|
||||
predicate suppression_in_scope(Stmt s) {
|
||||
exists(With w |
|
||||
w.getContextExpr().(Call).getFunc().pointsTo(Value::named("contextlib.suppress")) and
|
||||
w.getContextExpr()
|
||||
.(Call)
|
||||
.getFunc()
|
||||
.(ExprWithPointsTo)
|
||||
.pointsTo(Value::named("contextlib.suppress")) and
|
||||
w.getScope() = s.getScope()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,10 +12,11 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
from Call call, ClassValue ex
|
||||
where
|
||||
call.getFunc().pointsTo(ex) and
|
||||
call.getFunc().(ExprWithPointsTo).pointsTo(ex) and
|
||||
ex.getASuperType() = ClassValue::exception() and
|
||||
exists(ExprStmt s | s.getValue() = call)
|
||||
select call, "Instantiating an exception, but not raising it, has no effect."
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import Variables.MonkeyPatched
|
||||
import Loop
|
||||
import semmle.python.pointsto.PointsTo
|
||||
@@ -95,7 +96,7 @@ predicate undefined_use(Name u) {
|
||||
not contains_unknown_import_star(u.getEnclosingModule()) and
|
||||
not use_of_exec(u.getEnclosingModule()) and
|
||||
not exists(u.getVariable().getAStore()) and
|
||||
not u.pointsTo(_) and
|
||||
not u.(ExprWithPointsTo).pointsTo(_) and
|
||||
not probably_defined_in_loop(u)
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import Undefined
|
||||
import semmle.python.pointsto.PointsTo
|
||||
|
||||
@@ -30,7 +31,7 @@ predicate uninitialized_local(NameNode use) {
|
||||
predicate explicitly_guarded(NameNode u) {
|
||||
exists(Try t |
|
||||
t.getBody().contains(u.getNode()) and
|
||||
t.getAHandler().getType().pointsTo(ClassValue::nameError())
|
||||
t.getAHandler().getType().(ExprWithPointsTo).pointsTo(ClassValue::nameError())
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ string os_specific_import(ImportExpr ie) {
|
||||
string get_os() { py_flags_versioned("sys.platform", result, major_version().toString()) }
|
||||
|
||||
predicate ok_to_fail(ImportExpr ie) {
|
||||
alternative_import(ie).refersTo(_)
|
||||
alternative_import(ie).(ExprWithPointsTo).refersTo(_)
|
||||
or
|
||||
os_specific_import(ie) != get_os()
|
||||
}
|
||||
@@ -80,7 +80,7 @@ class VersionGuard extends ConditionBlock {
|
||||
|
||||
from ImportExpr ie
|
||||
where
|
||||
not ie.refersTo(_) and
|
||||
not ie.(ExprWithPointsTo).refersTo(_) and
|
||||
exists(Context c | c.appliesTo(ie.getAFlowNode())) and
|
||||
not ok_to_fail(ie) and
|
||||
not exists(VersionGuard guard | guard.controls(ie.getAFlowNode().getBasicBlock(), _))
|
||||
|
||||
@@ -3,9 +3,10 @@
|
||||
*/
|
||||
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
import analysis.DefinitionTracking
|
||||
|
||||
predicate want_to_have_definition(Expr e) {
|
||||
predicate want_to_have_definition(ExprWithPointsTo e) {
|
||||
/* not builtin object like len, tuple, etc. */
|
||||
not exists(Value builtin | e.pointsTo(builtin) and builtin.isBuiltin()) and
|
||||
(
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
string longname(Expr e) {
|
||||
result = e.(Name).getId()
|
||||
@@ -6,6 +7,6 @@ string longname(Expr e) {
|
||||
exists(Attribute a | a = e | result = longname(a.getObject()) + "." + a.getName())
|
||||
}
|
||||
|
||||
from Expr e, Value v
|
||||
from ExprWithPointsTo e, Value v
|
||||
where e.pointsTo(v) and e.getLocation().getFile().getShortName() = "test.py"
|
||||
select longname(e), v.toString()
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import python
|
||||
private import LegacyPointsTo
|
||||
|
||||
string longname(Expr e) {
|
||||
result = e.(Name).getId()
|
||||
@@ -6,6 +7,6 @@ string longname(Expr e) {
|
||||
exists(Attribute a | a = e | result = longname(a.getObject()) + "." + a.getName())
|
||||
}
|
||||
|
||||
from Expr e, Value v
|
||||
from ExprWithPointsTo e, Value v
|
||||
where e.pointsTo(v) and e.getLocation().getFile().getShortName() = "test.py"
|
||||
select longname(e), v.toString()
|
||||
|
||||
Reference in New Issue
Block a user