Merge pull request #2374 from tausbn/python-fix-mappingproxytype-fp

Python: Fix non-container FP relating to `MappingProxyType`.
This commit is contained in:
Rasmus Wriedt Larsen
2019-11-19 13:13:26 +01:00
committed by GitHub
3 changed files with 28 additions and 11 deletions

View File

@@ -11,20 +11,24 @@
*/
import python
import semmle.python.pointsto.PointsTo
predicate rhs_in_expr(ControlFlowNode rhs, Compare cmp) {
exists(Cmpop op, int i | cmp.getOp(i) = op and cmp.getComparator(i) = rhs.getNode() |
op instanceof In or op instanceof NotIn
op instanceof In or op instanceof NotIn
)
}
from ControlFlowNode non_seq, Compare cmp, ClassObject cls, ControlFlowNode origin
where rhs_in_expr(non_seq, cmp) and
non_seq.refersTo(_, cls, origin) and
not cls.failedInference() and
not cls.hasAttribute("__contains__") and
not cls.hasAttribute("__iter__") and
not cls.hasAttribute("__getitem__") and
not cls = theNoneType()
select cmp, "This test may raise an Exception as the $@ may be of non-container class $@.", origin, "target", cls, cls.getName()
from ControlFlowNode non_seq, Compare cmp, Value v, ClassValue cls, ControlFlowNode origin
where
rhs_in_expr(non_seq, cmp) and
non_seq.pointsTo(_, v, origin) and
v.getClass() = cls and
not Types::failedInference(cls, _) and
not cls.hasAttribute("__contains__") and
not cls.hasAttribute("__iter__") and
not cls.hasAttribute("__getitem__") and
not cls = ClassValue::nonetype() and
not cls = Value::named("types.MappingProxyType")
select cmp, "This test may raise an Exception as the $@ may be of non-container class $@.", origin,
"target", cls, cls.getName()

View File

@@ -660,4 +660,9 @@ module ClassValue {
result = TBuiltinClassObject(Builtin::special("ModuleType"))
}
/** Get the `ClassValue` for the `NoneType` class. */
ClassValue nonetype() {
result = TBuiltinClassObject(Builtin::special("NoneType"))
}
}

View File

@@ -234,3 +234,11 @@ def func():
except TypeError:
return 1
return 0
# False positive for py/member-test-non-container
# Container wrapped in MappingProxyType
from types import MappingProxyType
def mpt_arg(d=MappingProxyType({})):
return 1 in d