mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Update tests for calls to init + fixes
This commit is contained in:
@@ -95,13 +95,15 @@ predicate missingCallToSuperclassMethod(Class base, Function shouldCall, string
|
||||
|
||||
predicate missingCallToSuperclassMethodRestricted(Class base, Function shouldCall, string name) {
|
||||
missingCallToSuperclassMethod(base, shouldCall, name) and
|
||||
not exists(Class subBase |
|
||||
subBase = getADirectSubclass+(base) and
|
||||
missingCallToSuperclassMethod(subBase, shouldCall, name)
|
||||
not exists(Class superBase |
|
||||
// Alert only on the highest base class that has the issue
|
||||
superBase = getADirectSuperclass+(base) and
|
||||
missingCallToSuperclassMethod(superBase, shouldCall, name)
|
||||
) and
|
||||
not exists(Function superShouldCall |
|
||||
superShouldCall.getScope() = getADirectSuperclass+(shouldCall.getScope()) and
|
||||
missingCallToSuperclassMethod(base, superShouldCall, name)
|
||||
not exists(Function subShouldCall |
|
||||
// Mention in the alert only the lowest method we're missing the call to
|
||||
subShouldCall.getScope() = getADirectSubclass+(shouldCall.getScope()) and
|
||||
missingCallToSuperclassMethod(base, subShouldCall, name)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
| missing_init.py:12:1:12:13 | class B3 | Class B3 may not be initialized properly as $@ is not called from its $@. | missing_init.py:9:5:9:23 | Function __init__ | method B2.__init__ | missing_init.py:14:5:14:23 | Function __init__ | __init__ method |
|
||||
| missing_init.py:39:1:39:21 | class IUVT | Class IUVT may not be initialized properly as $@ is not called from its $@. | missing_init.py:30:5:30:23 | Function __init__ | method UT.__init__ | missing_init.py:26:5:26:23 | Function __init__ | __init__ method |
|
||||
| missing_init.py:72:1:72:13 | class AB | Class AB may not be initialized properly as $@ is not called from its $@. | missing_init.py:69:5:69:23 | Function __init__ | method AA.__init__ | missing_init.py:75:5:75:23 | Function __init__ | __init__ method |
|
||||
| missing_init.py:14:5:14:23 | Function __init__ | This initialization method does not call $@, which may leave $@ partially initialized. | missing_init.py:9:5:9:23 | Function __init__ | B2.__init__ | missing_init.py:13:1:13:13 | Class B3 | B3 |
|
||||
| missing_init.py:29:5:29:23 | Function __init__ | This initialization method does not call super().__init__, which may cause $@ to be missed during the initialization of $@. | missing_init.py:33:5:33:23 | Function __init__ | UT.__init__ | missing_init.py:42:1:42:21 | Class IUVT | IUVT |
|
||||
| missing_init.py:70:5:70:23 | Function __init__ | This initialization method does not call $@, which may leave $@ partially initialized. | missing_init.py:64:5:64:23 | Function __init__ | AA.__init__ | missing_init.py:67:1:67:13 | Class AB | AB |
|
||||
| missing_init.py:124:9:124:27 | Function __init__ | This initialization method does not call $@, which may leave $@ partially initialized. | missing_init.py:117:5:117:23 | Function __init__ | DA.__init__ | missing_init.py:122:5:122:17 | Class DC | DC |
|
||||
| missing_init.py:134:5:134:23 | Function __init__ | This initialization method does not call $@, which may leave $@ partially initialized. | missing_init.py:117:5:117:23 | Function __init__ | DA.__init__ | missing_init.py:132:1:132:13 | Class DD | DD |
|
||||
|
||||
@@ -2,18 +2,21 @@
|
||||
class B1(object):
|
||||
|
||||
def __init__(self):
|
||||
do_something()
|
||||
print("B1 init")
|
||||
|
||||
class B2(B1):
|
||||
|
||||
def __init__(self):
|
||||
print("B2 init")
|
||||
B1.__init__(self)
|
||||
|
||||
class B3(B2):
|
||||
|
||||
def __init__(self):
|
||||
class B3(B2): # $ Alert
|
||||
def __init__(self):
|
||||
print("B3 init")
|
||||
B1.__init__(self)
|
||||
|
||||
B3()
|
||||
|
||||
#OK if superclass __init__ is builtin as
|
||||
#builtin classes tend to rely on __new__
|
||||
class MyException(Exception):
|
||||
@@ -23,11 +26,11 @@ class MyException(Exception):
|
||||
|
||||
#ODASA-4107
|
||||
class IUT(object):
|
||||
def __init__(self):
|
||||
def __init__(self):
|
||||
print("IUT init")
|
||||
|
||||
class UT(object):
|
||||
def __init__(self):
|
||||
def __init__(self):
|
||||
print("UT init")
|
||||
|
||||
class PU(object):
|
||||
@@ -36,150 +39,151 @@ class PU(object):
|
||||
class UVT(UT, PU):
|
||||
pass
|
||||
|
||||
class IUVT(IUT, UVT):
|
||||
class IUVT(IUT, UVT): # $ Alert
|
||||
pass
|
||||
|
||||
#False positive
|
||||
print("IUVT")
|
||||
IUVT()
|
||||
|
||||
class M1(object):
|
||||
def __init__(self):
|
||||
print("A")
|
||||
print("M1 init")
|
||||
|
||||
class M2(object):
|
||||
pass
|
||||
|
||||
class Mult(M2, M1):
|
||||
def __init__(self):
|
||||
super(Mult, self).__init__() # Calls M1.__init__
|
||||
print("Mult init")
|
||||
super(Mult, self).__init__() # OK - Calls M1.__init__
|
||||
|
||||
class X:
|
||||
def __init__(self):
|
||||
do_something()
|
||||
|
||||
class Y(X):
|
||||
@decorated
|
||||
def __init__(self):
|
||||
X.__init__(self)
|
||||
|
||||
class Z(Y):
|
||||
def __init__(self):
|
||||
Y.__init__(self)
|
||||
Mult()
|
||||
|
||||
class AA(object):
|
||||
|
||||
def __init__(self):
|
||||
do_something()
|
||||
print("AA init")
|
||||
|
||||
class AB(AA):
|
||||
class AB(AA): # $ Alert
|
||||
|
||||
#Don't call super class init
|
||||
def __init__(self):
|
||||
do_something()
|
||||
# Doesn't call super class init
|
||||
def __init__(self):
|
||||
print("AB init")
|
||||
|
||||
class AC(AB):
|
||||
|
||||
def __init__(self):
|
||||
#Missing call to AA.__init__ but not AC's fault.
|
||||
# Doesn't call AA init, but we don't alert here as the issue is with AB.
|
||||
print("AC init")
|
||||
super(AC, self).__init__()
|
||||
|
||||
AC()
|
||||
|
||||
import six
|
||||
import abc
|
||||
|
||||
class BA(object):
|
||||
|
||||
def __init__(self):
|
||||
do_something()
|
||||
print("BA init")
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BB(BA):
|
||||
|
||||
def __init__(self):
|
||||
print("BB init")
|
||||
super(BB,self).__init__()
|
||||
|
||||
BB()
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class CA(object):
|
||||
|
||||
def __init__(self):
|
||||
do_something()
|
||||
print("CA init")
|
||||
|
||||
class CB(BA):
|
||||
class CB(CA):
|
||||
|
||||
def __init__(self):
|
||||
print("CB init")
|
||||
super(CB,self).__init__()
|
||||
|
||||
CB()
|
||||
|
||||
#ODASA-5799
|
||||
class DA(object):
|
||||
|
||||
def __init__(self):
|
||||
do_something()
|
||||
print("DA init")
|
||||
|
||||
class DB(DA):
|
||||
|
||||
class DC(DA):
|
||||
class DC(DA): # $ SPURIOUS: Alert # We only consider direct super calls, so have an FP here
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self):
|
||||
print("DC init")
|
||||
sup = super(DB.DC, self)
|
||||
sup.__init__()
|
||||
|
||||
#Simpler variants
|
||||
class DD(DA):
|
||||
DB.DC()
|
||||
|
||||
def __init__(self):
|
||||
#Simpler variants
|
||||
class DD(DA): # $ SPURIOUS: Alert # We only consider direct super calls, so have an FP here
|
||||
|
||||
def __init__(self):
|
||||
print("DD init")
|
||||
sup = super(DD, self)
|
||||
sup.__init__()
|
||||
|
||||
DD()
|
||||
|
||||
class DE(DA):
|
||||
|
||||
class DF(DA):
|
||||
class DF(DA): # No alert here
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self):
|
||||
print("DF init")
|
||||
sup = super(DE.DF, self).__init__()
|
||||
|
||||
DE.DF()
|
||||
|
||||
class FA(object):
|
||||
|
||||
def __init__(self):
|
||||
pass
|
||||
pass # does nothing, thus is considered a trivial method and ok to not call
|
||||
|
||||
class FB(object):
|
||||
|
||||
def __init__(self):
|
||||
do_something()
|
||||
print("FB init")
|
||||
|
||||
class FC(FA, FB):
|
||||
|
||||
def __init__(self):
|
||||
#OK to skip call to FA.__init__ as that does nothing.
|
||||
# No alert here - ok to skip call to trivial FA init
|
||||
FB.__init__(self)
|
||||
|
||||
#Potential false positives.
|
||||
|
||||
class ConfusingInit(B1):
|
||||
|
||||
def __init__(self):
|
||||
def __init__(self): # We track this correctly and don't alert.
|
||||
super_call = super(ConfusingInit, self).__init__
|
||||
super_call()
|
||||
|
||||
|
||||
# Library class
|
||||
import collections
|
||||
|
||||
class G1(collections.Counter):
|
||||
|
||||
class G1:
|
||||
def __init__(self):
|
||||
collections.Counter.__init__(self)
|
||||
|
||||
class G2(G1):
|
||||
print("G1 init")
|
||||
|
||||
class G2:
|
||||
def __init__(self):
|
||||
super(G2, self).__init__()
|
||||
print("G2 init")
|
||||
|
||||
class G3(collections.Counter):
|
||||
|
||||
def __init__(self):
|
||||
super(G3, self).__init__()
|
||||
|
||||
class G4(G3):
|
||||
|
||||
def __init__(self):
|
||||
G3.__init__(self)
|
||||
class G3(G1, G2):
|
||||
def __init__(self):
|
||||
print("G3 init")
|
||||
for cls in self.__class__.__bases__:
|
||||
cls.__init__(self) # We dont track which classes this could refer to, but assume it calls all required init methods and don't alert.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user