Compare commits

...

2 Commits

Author SHA1 Message Date
Taus
5e34778d72 Python: Exclude "self-inheritance" results
It's not possible for a class to actually inherit from itself, so if
this happens, something has gone wrong with our analysis. We therefore
explicitly exclude these results so they don't result in false
positives.
2026-04-09 21:12:17 +00:00
Taus
adbc4a7777 Python: Port InconsistentMRO.ql
For this one we actually lose a test result. However, this is kind of to
be expected since we no longer have the "precise" MRO that the points-to
analysis computes.

Honestly, I'm on the fence about even keeping this query at all. It
seems like it might be superfluous in a world with good Python type
checking.
2026-04-08 12:18:52 +00:00
3 changed files with 17 additions and 10 deletions

View File

@@ -12,19 +12,27 @@
*/
import python
private import LegacyPointsTo
private import semmle.python.dataflow.new.internal.DataFlowDispatch
ClassObject left_base(ClassObject type, ClassObject base) {
exists(int i | i > 0 and type.getBaseType(i) = base and result = type.getBaseType(i - 1))
/**
* Gets the `i`th base class of `cls`, if it can be resolved to a user-defined class.
*/
Class getBaseType(Class cls, int i) {
cls.getBase(i) = classTracker(result).asExpr() and
result != cls
}
predicate invalid_mro(ClassObject t, ClassObject left, ClassObject right) {
t.isNewStyle() and
Class left_base(Class type, Class base) {
exists(int i | i > 0 and getBaseType(type, i) = base and result = getBaseType(type, i - 1))
}
predicate invalid_mro(Class t, Class left, Class right) {
DuckTyping::isNewStyle(t) and
left = left_base(t, right) and
left = right.getAnImproperSuperType()
left = getADirectSuperclass*(right)
}
from ClassObject t, ClassObject left, ClassObject right
from Class t, Class left, Class right
where invalid_mro(t, left, right)
select t,
"Construction of class " + t.getName() +

View File

@@ -1 +1 @@
| inconsistent_mro.py:9:1:9:14 | class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | class X | X | inconsistent_mro.py:6:1:6:11 | class Y | Y |
| inconsistent_mro.py:9:1:9:14 | Class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | Class X | X | inconsistent_mro.py:6:1:6:11 | Class Y | Y |

View File

@@ -1,2 +1 @@
| inconsistent_mro.py:9:1:9:14 | class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | class X | X | inconsistent_mro.py:6:1:6:11 | class Y | Y |
| inconsistent_mro.py:16:1:16:19 | class N | Construction of class N can fail due to invalid method resolution order(MRO) for bases $@ and $@. | file://:Compiled Code:0:0:0:0 | builtin-class object | object | inconsistent_mro.py:12:1:12:8 | class O | O |
| inconsistent_mro.py:9:1:9:14 | Class Z | Construction of class Z can fail due to invalid method resolution order(MRO) for bases $@ and $@. | inconsistent_mro.py:3:1:3:16 | Class X | X | inconsistent_mro.py:6:1:6:11 | Class Y | Y |