mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
282 lines
5.4 KiB
Python
282 lines
5.4 KiB
Python
#encoding: utf-8
|
|
def dup_key():
|
|
return { 1: -1,
|
|
1: -2,
|
|
u'a' : u'A',
|
|
u'a' : u'B'
|
|
}
|
|
|
|
def simple_func(*args, **kwrgs): pass
|
|
#Unnecessary lambdas
|
|
lambda arg0, arg1: simple_func(arg0, arg1)
|
|
lambda arg0, *arg1: simple_func(arg0, *arg1)
|
|
lambda arg0, **arg1: simple_func(arg0, **arg1)
|
|
# these lambdas are_ necessary
|
|
lambda arg0, arg1=1: simple_func(arg0, arg1)
|
|
lambda arg0, arg1: simple_func(arg0, *arg1)
|
|
lambda arg0, arg1: simple_func(arg0, **arg1)
|
|
lambda arg0, *arg1: simple_func(arg0, arg1)
|
|
lambda arg0, **arg1: simple_func(arg0, arg1)
|
|
|
|
#Non-callable called
|
|
class NonCallable(object):
|
|
pass
|
|
|
|
class MaybeCallable(Unknown, object):
|
|
pass
|
|
|
|
def call_non_callable(arg):
|
|
non = NonCallable()
|
|
non(arg)
|
|
()()
|
|
[]()
|
|
dont_know = MaybeCallable()
|
|
dont_know() # Not a violation
|
|
|
|
#Explicit call to __del__
|
|
x.__del__()
|
|
|
|
#Unhashable object
|
|
def func():
|
|
mapping = dict(); unhash = list()
|
|
return mapping[unhash]
|
|
|
|
#Using 'is' when should be using '=='
|
|
s = "Hello " + "World"
|
|
if "Hello World" is s:
|
|
print ("OK")
|
|
|
|
#This is OK in CPython, but may not be portable
|
|
s = str(7)
|
|
if "7" is s:
|
|
print ("OK")
|
|
|
|
#And some data flow
|
|
CONSTANT = 20
|
|
if x is CONSTANT:
|
|
print ("OK")
|
|
|
|
#This is OK
|
|
x = object()
|
|
y = object()
|
|
if x is y:
|
|
print ("Very surprising!")
|
|
|
|
#This is also OK
|
|
if s is None:
|
|
print ("Also surprising")
|
|
|
|
#Portable is comparisons
|
|
def f(arg):
|
|
arg is ()
|
|
arg is 0
|
|
arg is ''
|
|
|
|
#Non-container
|
|
|
|
class XIter(object):
|
|
#Support both 2 and 3 form of next, but omit __iter__ method
|
|
|
|
def __next__(self):
|
|
pass
|
|
|
|
def next(self):
|
|
pass
|
|
|
|
def non_container():
|
|
|
|
seq = XIter()
|
|
if 1 in seq:
|
|
pass
|
|
if 1 not in seq:
|
|
pass
|
|
|
|
#Container inheriting from builtin
|
|
class MyDict(dict):
|
|
pass
|
|
|
|
class MySequence(UnresolvablebaseClass):
|
|
pass
|
|
|
|
def is_container():
|
|
mapping = MyDict()
|
|
if 1 in mapping:
|
|
pass
|
|
seq = MySequence()
|
|
if 1 in seq:
|
|
pass
|
|
seq = None
|
|
if seq is not None and 1 in seq:
|
|
pass
|
|
|
|
#Equals none
|
|
|
|
def x(arg):
|
|
return arg == None
|
|
|
|
class NotMyDict(object):
|
|
|
|
def f(self):
|
|
super(MyDict, self).f()
|
|
|
|
# class defining __del__
|
|
class Test(object):
|
|
def __del__(self):
|
|
pass
|
|
|
|
# subclass
|
|
class SubTest(Test):
|
|
def __del__(self):
|
|
# This is permitted and required.
|
|
Test.__del__(self)
|
|
# This is a violation.
|
|
self.__del__()
|
|
# This is an alternate syntax for the super() call, and hence OK.
|
|
super(SubTest, self).__del__()
|
|
# This is the Python 3 spelling of the same.
|
|
super().__del__()
|
|
|
|
#Some more lambdas
|
|
#Unnecessary lambdas
|
|
lambda arg0: len(arg0)
|
|
lambda arg0: XIter.next(arg0)
|
|
class UL(object):
|
|
|
|
def f(self, x):
|
|
pass
|
|
|
|
def g(self):
|
|
return lambda x: self.f(x)
|
|
|
|
# these lambdas are necessary
|
|
lambda arg0: XIter.next(arg0, arg1)
|
|
lambda arg0: func()(arg0)
|
|
lambda arg0, arg1: arg0.meth(arg0, arg1)
|
|
|
|
#Cannot flag lists as unhashable if the object
|
|
#we are subscripting may be a numpy array
|
|
def func(maybe_numpy):
|
|
unhash = list()
|
|
return maybe_numpy[unhash]
|
|
|
|
#Guarded non-callable called
|
|
def guarded_non_callable(cond):
|
|
if cond:
|
|
val = []
|
|
else:
|
|
val = func
|
|
if hasattr(val, "__call__"):
|
|
x(1)
|
|
|
|
|
|
#ODASA-4056
|
|
def format_string(s, formatter='minimal'):
|
|
"""Format the given string using the given formatter."""
|
|
if not callable(formatter):
|
|
formatter = get_formatter_for_name(formatter)
|
|
if formatter is None:
|
|
output = s
|
|
else:
|
|
output = formatter(s)
|
|
return output
|
|
|
|
#ODASA-4614
|
|
def f(x):
|
|
d = {}
|
|
d['one'] = {}
|
|
d['two'] = 0
|
|
return x[d['two']]
|
|
|
|
#ODASA-4055
|
|
class C:
|
|
|
|
def _internal(arg):
|
|
# arg is not a C
|
|
def wrapper(args):
|
|
return arg(args)
|
|
return wrapper
|
|
|
|
@_internal
|
|
def method(self, *args):
|
|
pass
|
|
|
|
#ODASA-4689
|
|
class StrangeIndex:
|
|
def __getitem__(self,index):
|
|
return 1
|
|
|
|
x = StrangeIndex();
|
|
print(x[{'a': 'b'}])
|
|
|
|
def not_dup_key():
|
|
return { u'a' : 0,
|
|
b'a' : 0,
|
|
u"😄" : 1,
|
|
u"😅" : 2,
|
|
u"😆" : 3
|
|
}
|
|
|
|
# Lookup of unhashable object triggers TypeError, but the
|
|
# exception is caught, so it's not a bug. This used to be
|
|
# a false positive of the HashedButNoHash query.
|
|
def func():
|
|
unhash = list()
|
|
try:
|
|
hash(unhash)
|
|
except TypeError:
|
|
return 1
|
|
return 0
|
|
|
|
def func():
|
|
mapping = dict(); unhash = list()
|
|
try:
|
|
mapping[unhash]
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#### UseofApply.ql
|
|
|
|
# Use of the builtin function `apply` is generally considered bad now that the
|
|
# ability to destructure lists of arguments is possible, but we should not flag
|
|
# cases where the function is merely named `apply` rather than being the actual
|
|
# builtin `apply` function.
|
|
|
|
def useofapply():
|
|
|
|
def foo():
|
|
pass
|
|
|
|
|
|
|
|
# Positive Cases
|
|
|
|
# This use of `apply` is a reference to the builtin function and so SHOULD be
|
|
# caught by the query.
|
|
apply(foo, [1])
|
|
|
|
|
|
|
|
# Negative Cases
|
|
|
|
# This use of `apply` is a reference to the locally defined function inside of
|
|
# `local`, and so SHOULD NOT be caught by the query.
|
|
def local():
|
|
def apply(f):
|
|
pass
|
|
apply(foo)([1])
|