mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Exclude setters and update tests
This commit is contained in:
@@ -12,22 +12,23 @@
|
||||
* @id py/attribute-shadows-method
|
||||
*/
|
||||
|
||||
/*
|
||||
* Determine if a class defines a method that is shadowed by an attribute
|
||||
* defined in a super-class
|
||||
*/
|
||||
|
||||
import python
|
||||
import semmle.python.ApiGraphs
|
||||
import semmle.python.dataflow.new.internal.DataFlowDispatch
|
||||
|
||||
predicate isSettableProperty(Function prop) {
|
||||
isProperty(prop) and
|
||||
exists(Function setter, DataFlow::AttrRead setterRead, FunctionExpr propExpr |
|
||||
setterRead.asExpr() = setter.getADecorator() and
|
||||
setterRead.getAttributeName() = "setter" and
|
||||
propExpr.getInnerScope() = prop and
|
||||
DataFlow::exprNode(propExpr).(DataFlow::LocalSourceNode).flowsTo(setterRead.getObject())
|
||||
exists(Function setter |
|
||||
setter.getScope() = prop.getScope() and
|
||||
setter.getName() = prop.getName() and
|
||||
isSetter(setter)
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSetter(Function f) {
|
||||
exists(DataFlow::AttrRead attr |
|
||||
f.getADecorator() = attr.asExpr() and
|
||||
attr.getAttributeName() = "setter"
|
||||
)
|
||||
}
|
||||
|
||||
@@ -52,7 +53,8 @@ predicate shadowedBySuperclass(
|
||||
superShadowed.getName() = shadowed.getName()
|
||||
) and
|
||||
// Allow properties if they have setters, as the write in the superclass will call the setter.
|
||||
not isSettableProperty(shadowed)
|
||||
not isSettableProperty(shadowed) and
|
||||
not isSetter(shadowed)
|
||||
}
|
||||
|
||||
from Class cls, Class superclass, DataFlow::AttrWrite write, Function shadowed, string extra
|
||||
@@ -61,8 +63,8 @@ where
|
||||
(
|
||||
if isProperty(shadowed)
|
||||
then
|
||||
not isSettableProperty(shadowed) and
|
||||
extra = " (read-only property may cause an error if written to.)"
|
||||
// it's not a setter, so it's a read-only property
|
||||
extra = " (read-only property may cause an error if written to in the superclass.)"
|
||||
else extra = ""
|
||||
)
|
||||
select shadowed, "This method is shadowed by $@ in superclass $@." + extra, write,
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
| subclass_shadowing.py:10:5:10:21 | FunctionExpr | Method shadow is shadowed by an $@ in super class 'Base'. | subclass_shadowing.py:6:9:6:23 | AssignStmt | attribute |
|
||||
| subclass_shadowing.py:11:5:11:21 | Function shadow | This method is shadowed by $@ in superclass $@. | subclass_shadowing.py:7:9:7:19 | ControlFlowNode for Attribute | attribute shadow | subclass_shadowing.py:4:1:4:11 | Class Base | Base |
|
||||
| subclass_shadowing.py:41:5:41:18 | Function foo | This method is shadowed by $@ in superclass $@. (read-only property may cause an error if written to.) | subclass_shadowing.py:35:9:35:16 | ControlFlowNode for Attribute | attribute foo | subclass_shadowing.py:33:1:33:12 | Class Base3 | Base3 |
|
||||
|
||||
Reference in New Issue
Block a user