mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Mostly just adding `private import LegacyPointsTo`. Sometimes getting rid of other imports that are superceded by that module.
63 lines
1.9 KiB
Plaintext
63 lines
1.9 KiB
Plaintext
/**
|
|
* @name Conflicting attributes in base classes
|
|
* @description When a class subclasses multiple base classes and more than one base class defines the same attribute, attribute overriding may result in unexpected behavior by instances of this class.
|
|
* @kind problem
|
|
* @tags quality
|
|
* reliability
|
|
* correctness
|
|
* @problem.severity warning
|
|
* @sub-severity low
|
|
* @precision high
|
|
* @id py/conflicting-attributes
|
|
*/
|
|
|
|
import python
|
|
private import LegacyPointsTo
|
|
|
|
predicate does_nothing(PyFunctionObject f) {
|
|
not exists(Stmt s | s.getScope() = f.getFunction() |
|
|
not s instanceof Pass and not s.(ExprStmt).getValue() = f.getFunction().getDocString()
|
|
)
|
|
}
|
|
|
|
/* If a method performs a super() call then it is OK as the 'overridden' method will get called */
|
|
predicate calls_super(FunctionObject f) {
|
|
exists(Call sup, Call meth, Attribute attr, GlobalVariable v |
|
|
meth.getScope() = f.getFunction() and
|
|
meth.getFunc() = attr and
|
|
attr.getObject() = sup and
|
|
attr.getName() = f.getName() and
|
|
sup.getFunc() = v.getAnAccess() and
|
|
v.getId() = "super"
|
|
)
|
|
}
|
|
|
|
/** Holds if the given name is allowed for some reason */
|
|
predicate allowed(string name) {
|
|
/*
|
|
* The standard library specifically recommends this :(
|
|
* See https://docs.python.org/3/library/socketserver.html#asynchronous-mixins
|
|
*/
|
|
|
|
name = "process_request"
|
|
}
|
|
|
|
from
|
|
ClassObject c, ClassObject b1, ClassObject b2, string name, int i1, int i2, Object o1, Object o2
|
|
where
|
|
c.getBaseType(i1) = b1 and
|
|
c.getBaseType(i2) = b2 and
|
|
i1 < i2 and
|
|
o1 != o2 and
|
|
o1 = b1.lookupAttribute(name) and
|
|
o2 = b2.lookupAttribute(name) and
|
|
not name.matches("\\_\\_%\\_\\_") and
|
|
not calls_super(o1) and
|
|
not does_nothing(o2) and
|
|
not allowed(name) and
|
|
not o1.overrides(o2) and
|
|
not o2.overrides(o1) and
|
|
not c.declaresAttribute(name)
|
|
select c, "Base classes have conflicting values for attribute '" + name + "': $@ and $@.", o1,
|
|
o1.toString(), o2, o2.toString()
|