Merge branch 'master' into python-objectapi-to-valueapi-signatureoverriddenmethod

This commit is contained in:
Rebecca Valentine
2020-03-31 23:36:15 -07:00
193 changed files with 14898 additions and 8211 deletions

View File

@@ -2,5 +2,5 @@
import python
from ExceptFlowNode ex, Object obj
where ex.handledException(obj, _, _)
where ex.handledException_objectapi(obj, _, _)
select ex.getLocation().getStartLine(), ex.toString(), obj.toString()

View File

@@ -1 +1 @@
| nonsense.py:1:14:1:14 | Syntax Error | Syntax Error (in Python 2.7). |
| nonsense.py:1:14:1:14 | Syntax Error | Syntax Error (in Python 2). |

View File

@@ -2,5 +2,5 @@
import python
from ExceptFlowNode ex, Object obj
where ex.handledException(obj, _, _)
where ex.handledException_objectapi(obj, _, _)
select ex.getLocation().getStartLine(), ex.toString(), obj.toString()

View File

@@ -0,0 +1,3 @@
| mwe_failure.py:7:1:7:23 | class MyTest | <MISSING BASE TYPE> |
| mwe_failure_2.py:7:1:7:23 | class MyTest | <MISSING BASE TYPE> |
| mwe_success.py:7:1:7:23 | class MyTest | class TestCase |

View File

@@ -0,0 +1,10 @@
import python
// as used in semmle.python.filters.Tests
from ClassValue c, string base
where
c.getScope().getLocation().getFile().getShortName().matches("mwe%.py") and
c.getName() = "MyTest" and
if exists(c.getABaseType()) then base = c.getABaseType().toString() else base = "<MISSING BASE TYPE>"
select c, base

View File

@@ -0,0 +1,10 @@
import subprocess
assert subprocess.call(['run-backup']) == 0
class TestCase:
pass
class MyTest(TestCase):
pass
# found by /home/rasmus/code/ql/python/ql/test/query-tests/Statements/asserts/AssertLiteralConstant.qlref

View File

@@ -0,0 +1,8 @@
import subprocess
assert subprocess.call(['run-backup'])
class TestCase:
pass
class MyTest(TestCase):
pass

View File

@@ -0,0 +1,8 @@
import subprocess
subprocess.call(['run-backup'])
class TestCase:
pass
class MyTest(TestCase):
pass

View File

@@ -0,0 +1 @@
semmle-extractor-options: --lang=3 --max-import-depth=1

View File

@@ -1 +1 @@
| nonsense.py:1:2:1:2 | Syntax Error | Syntax Error (in Python 3.5). |
| nonsense.py:1:2:1:2 | Syntax Error | Syntax Error (in Python 3). |

View File

@@ -1,2 +1,2 @@
| async_iterator.py:26:11:26:34 | For | $@ of class '$@' may be used in for-loop. | async_iterator.py:26:20:26:33 | ControlFlowNode for MissingAiter() | Non-iterator | async_iterator.py:13:1:13:19 | class MissingAiter | MissingAiter |
| statements_test.py:34:5:34:19 | For | $@ of class '$@' may be used in for-loop. | statements_test.py:34:18:34:18 | ControlFlowNode for IntegerLiteral | Non-iterator | file://:0:0:0:0 | builtin-class int | int |
| async_iterator.py:26:11:26:34 | For | $@ of class '$@' may be used in for-loop. | async_iterator.py:26:20:26:33 | ControlFlowNode for MissingAiter() | Non-iterable | async_iterator.py:13:1:13:19 | class MissingAiter | MissingAiter |
| statements_test.py:34:5:34:19 | For | $@ of class '$@' may be used in for-loop. | statements_test.py:34:18:34:18 | ControlFlowNode for IntegerLiteral | Non-iterable | file://:0:0:0:0 | builtin-class int | int |

View File

@@ -1,6 +1,6 @@
| 16 | classmethod() | 17 | Function c1 |
| 23 | classmethod() | 20 | Function c2 |
| 24 | classmethod() | 20 | Function c2 |
| 26 | staticmethod() | 27 | Function s1 |
| 33 | staticmethod() | 30 | Function s2 |
| 34 | staticmethod() | 30 | Function s2 |
| 104 | classmethod() | 105 | Function c1 |
| 111 | classmethod() | 108 | Function c2 |
| 112 | classmethod() | 108 | Function c2 |
| 114 | staticmethod() | 115 | Function s1 |
| 121 | staticmethod() | 118 | Function s2 |
| 122 | staticmethod() | 118 | Function s2 |

View File

@@ -1 +1,8 @@
| 6 | Property f | 7 | Function f | 11 | Function f |
| test.py:6:5:6:16 | Function WithDecorator.x | getter | test.py:5:6:5:13 | property x |
| test.py:11:5:11:23 | Function WithDecorator.x | setter | test.py:5:6:5:13 | property x |
| test.py:15:5:15:16 | Function WithDecorator.x | deleter | test.py:5:6:5:13 | property x |
| test.py:21:5:21:16 | Function WithDecoratorOnlyGetter.x | getter | test.py:20:6:20:13 | property x |
| test.py:28:5:28:19 | Function WithoutDecorator.getx | getter | test.py:37:9:37:59 | property getx |
| test.py:31:5:31:26 | Function WithoutDecorator.setx | setter | test.py:37:9:37:59 | property getx |
| test.py:34:5:34:19 | Function WithoutDecorator.delx | deleter | test.py:37:9:37:59 | property getx |
| test.py:41:5:41:19 | Function WithoutDecoratorOnlyGetter.getx | getter | test.py:44:9:44:22 | property getx |

View File

@@ -1,13 +1,11 @@
import python
import semmle.python.types.Descriptors
int lineof(Object o) {
result = o.getOrigin().getLocation().getStartLine()
}
from PropertyObject p, FunctionObject getter, FunctionObject setter
from PropertyValue p, string method_name, FunctionValue method
where
getter = p.getGetter() and setter = p.getSetter()
select lineof(p), p.toString(), lineof(getter), getter.toString(), lineof(setter), setter.toString()
method_name = "getter" and method = p.getGetter()
or
method_name = "setter" and method = p.getSetter()
or
method_name = "deleter" and method = p.getDeleter()
select method, method_name, p

View File

@@ -1,15 +1,103 @@
class C(object):
class WithDecorator(object):
def __init__(self):
self._x = None
@property
def f(self):
return self._f
def x(self):
"""I'm the 'x' property."""
return self._x
@f.setter
def f(self):
return self._f
@x.setter
def x(self, value):
self._x = value
@x.deleter
def x(self):
del self._x
class WithDecoratorOnlyGetter(object):
@property
def x(self):
return 42
class WithoutDecorator(object):
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
class WithoutDecoratorOnlyGetter(object):
def getx(self):
return 42
x = property(getx)
class WithoutDecoratorOnlyGetterKWArg(object):
def getx(self):
return 42
x = property(fget=getx)
class WithoutDecoratorOnlySetter(object):
def setx(self, value):
self._x = value
x = property(fset=setx) # TODO: Not handled
class WithDecoratorOnlySetter(object):
x = property()
@x.setter
def x(self, value):
print('{} setting value to {}'.format(self.__class__, value))
class FunkyButValid(object):
def delx(self):
print("deleting x")
x = property(fdel=delx)
@x.setter
def y(self, value):
print('setting value to {}'.format(value))
@y.getter
def z(self):
return 42
wat = FunkyButValid()
try:
wat.x
except AttributeError as e:
print("x can't be read")
del wat.x
try:
wat.y
except AttributeError as e:
print("y can't be read")
wat.y = 1234
del wat.y
print(wat.z)
wat.z = 10
del wat.z
class D(object):

View File

@@ -1,5 +1,5 @@
import python
from ExceptFlowNode ex, Object t
where ex.handledException(t, _, _)
where ex.handledException_objectapi(t, _, _)
select ex.getLocation().getStartLine(), ex.toString(), t.toString()

View File

@@ -0,0 +1,5 @@
| file://:0:0:0:0 | Module sys | isUsedAsModule |
| imported.py:0:0:0:0 | Module imported | isUsedAsModule |
| main.py:0:0:0:0 | Module main | isUsedAsScript |
| myscript.py:0:0:0:0 | Script myscript | isUsedAsScript |
| script:0:0:0:0 | Script script | isUsedAsScript |

View File

@@ -0,0 +1,16 @@
import python
from ModuleValue mv, string usage
where
// builtin module has different name in Python 2 and 3
not mv = Module::builtinModule() and
(
mv.isUsedAsModule() and usage = "isUsedAsModule"
or
mv.isUsedAsScript() and usage = "isUsedAsScript"
or
not mv.isUsedAsModule() and
not mv.isUsedAsScript() and
usage = "<UNKNOWN>"
)
select mv, usage

View File

@@ -0,0 +1,6 @@
def func():
pass
if __name__ == "__main__":
print("I could have done something interesting...")
print("but I didn't")

View File

@@ -0,0 +1,5 @@
import imported
if __name__ == "__main__":
imported.func()
print('Done')

View File

@@ -0,0 +1,3 @@
#!/usr/bin/env python
print("I'm actually a script you see ;)")

View File

@@ -0,0 +1 @@
semmle-extractor-options: -F script

View File

@@ -0,0 +1,3 @@
#!/usr/bin/env python
print('Under construction :)')

View File

@@ -1 +1 @@
| str_fmt_test.py:5:26:5:26 | x | Right hand side of a % operator must be a mapping, not class $@. | file://:Compiled Code:0:0:0:0 | builtin-class list | list |
| str_fmt_test.py:5:26:5:26 | x | Right hand side of a % operator must be a mapping, not class $@. | file://:0:0:0:0 | builtin-class list | list |

View File

@@ -1,3 +1,3 @@
| functions_test.py:99:5:99:40 | Function __getslice__ | __getslice__ method has been deprecated since Python 2.0 |
| functions_test.py:102:5:102:47 | Function __setslice__ | __setslice__ method has been deprecated since Python 2.0 |
| functions_test.py:105:5:105:40 | Function __delslice__ | __delslice__ method has been deprecated since Python 2.0 |
| functions_test.py:99:5:99:40 | Function DeprecatedSliceMethods.__getslice__ | __getslice__ method has been deprecated since Python 2.0 |
| functions_test.py:102:5:102:47 | Function DeprecatedSliceMethods.__setslice__ | __setslice__ method has been deprecated since Python 2.0 |
| functions_test.py:105:5:105:40 | Function DeprecatedSliceMethods.__delslice__ | __delslice__ method has been deprecated since Python 2.0 |

View File

@@ -0,0 +1 @@
semmle-extractor-options: --max-import-depth=0

View File

@@ -1,2 +1,3 @@
| assert.py:5:5:5:20 | Assert | This 'assert' statement contains $@ which may have side effects. | assert.py:5:13:5:19 | Yield | an expression |
| assert.py:8:5:8:22 | Assert | This 'assert' statement contains $@ which may have side effects. | assert.py:8:12:8:22 | Attribute() | an expression |
| side_effect.py:5:1:5:43 | Assert | This 'assert' statement contains $@ which may have side effects. | side_effect.py:5:8:5:38 | Attribute() | an expression |

View File

@@ -103,4 +103,4 @@ def error_assert_in_intermediate_branch(x):
elif yks(x):
pass
else:
pass
pass

View File

@@ -0,0 +1,5 @@
# For now, this test lives in its own file, since including them in the top of assert.py
# messes up the results of the refers-to/points-to analysis
# see /home/rasmus/code/ql/python/ql/test/library-tests/PointsTo/regressions/subprocess-assert/mwe_failure.py
import subprocess
assert subprocess.call(['run-backup']) == 0

View File

@@ -1,4 +1,4 @@
| statements_test.py:19:5:19:18 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 2. | statements_test.py:19:15:19:18 | statements_test.py:19 | tuple |
| statements_test.py:163:5:163:23 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 5. | statements_test.py:163:13:163:23 | statements_test.py:163 | list |
| statements_test.py:172:5:172:48 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 5. | statements_test.py:167:16:167:24 | statements_test.py:167 | tuple |
| statements_test.py:172:5:172:48 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 6. | statements_test.py:169:16:169:26 | statements_test.py:169 | tuple |
| statements_test.py:169:5:169:23 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 5. | statements_test.py:169:13:169:23 | statements_test.py:169 | list |
| statements_test.py:178:5:178:48 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 5. | statements_test.py:173:16:173:24 | statements_test.py:173 | tuple |
| statements_test.py:178:5:178:48 | AssignStmt | Left hand side of assignment contains 3 variables, but right hand side is a $@ of length 6. | statements_test.py:175:16:175:26 | statements_test.py:175 | tuple |

View File

@@ -1 +1 @@
| test.py:50:1:50:23 | For | $@ of class '$@' may be used in for-loop. | test.py:50:10:50:22 | ControlFlowNode for NonIterator() | Non-iterator | test.py:45:1:45:26 | class NonIterator | NonIterator |
| test.py:50:1:50:23 | For | $@ of class '$@' may be used in for-loop. | test.py:50:10:50:22 | ControlFlowNode for NonIterator() | Non-iterable | test.py:45:1:45:26 | class NonIterator | NonIterator |

View File

@@ -1,3 +1,3 @@
| statements_test.py:54:5:54:9 | AssignStmt | This assignment assigns a variable to itself. |
| statements_test.py:57:9:57:19 | AssignStmt | This assignment assigns a variable to itself. |
| statements_test.py:117:9:117:23 | AssignStmt | This assignment assigns a variable to itself. |
| statements_test.py:119:9:119:23 | AssignStmt | This assignment assigns a variable to itself. |

View File

@@ -1 +1 @@
| statements_test.py:181:5:181:9 | Delete | Unnecessary deletion of local variable $@ in function $@. | statements_test.py:181:9:181:9 | statements_test.py:181 | x | statements_test.py:179:1:179:31 | statements_test.py:179 | error_unnecessary_delete |
| statements_test.py:187:5:187:9 | Delete | Unnecessary deletion of local variable $@ in function $@. | statements_test.py:187:9:187:9 | statements_test.py:187 | x | statements_test.py:185:1:185:31 | statements_test.py:185 | error_unnecessary_delete |

View File

@@ -1,2 +1,2 @@
| statements_test.py:63:1:63:19 | For | This 'for' statement has a redundant 'else' as no 'break' is present in the body. |
| statements_test.py:68:1:68:13 | While | This 'while' statement has a redundant 'else' as no 'break' is present in the body. |
| statements_test.py:65:1:65:19 | For | This 'for' statement has a redundant 'else' as no 'break' is present in the body. |
| statements_test.py:70:1:70:13 | While | This 'while' statement has a redundant 'else' as no 'break' is present in the body. |

View File

@@ -56,27 +56,29 @@ class Redundant(object):
def __init__(self, args):
args = args # violation
#Non redundant assignment
len = len
if sys.version_info < (3,):
bytes = str
else:
bytes = bytes # Should not be flagged
#Pointless else clauses
for x in range(10):
func(x)
else:
do_something()
while x < 10:
func(x)
else:
do_something()
#OK else clauses:
for x in range(10):
if func(x):
break
else:
do_something()
while x < 10:
if func(x):
break
@@ -95,24 +97,24 @@ else:
#Not a redundant assignment if a property.
class WithProp(object):
@property
def x(self):
return self._x
@prop.setter
def set_x(self, x):
side_effect(x)
self._x = x
def meth(self):
self.x = self.x
def maybe_property(x):
x.y = x.y
class WithoutProp(object):
def meth(self):
self.x = self.x
@@ -143,8 +145,12 @@ for e in EnumDerived:
class SideEffectingAttr(object):
def __init__(self):
self.foo = 'foo'
def __setattr__(self, name, val):
print("hello!")
super().__setattr__(name, val)
s = SideEffectingAttr()
s.foo = s.foo