Merge branch 'main' into amammad-python-bombs

This commit is contained in:
amammad
2023-12-07 13:50:20 +01:00
9569 changed files with 683674 additions and 332770 deletions

View File

@@ -8,4 +8,4 @@
| 38 | ControlFlowNode for ExceptStmt | builtin-class AttributeError |
| 40 | ControlFlowNode for ExceptStmt | builtin-class IndexError |
| 42 | ControlFlowNode for ExceptStmt | builtin-class KeyError |
| 57 | ControlFlowNode for ExceptStmt | builtin-class IOError |
| 57 | ControlFlowNode for ExceptStmt | builtin-class IOError |

View File

@@ -12,4 +12,4 @@
| 35 | ControlFlowNode for Attribute | builtin-class AttributeError |
| 37 | ControlFlowNode for Raise | builtin-class Exception |
| 53 | ControlFlowNode for Attribute() | builtin-class IOError |
| 54 | ControlFlowNode for Attribute() | builtin-class IOError |
| 54 | ControlFlowNode for Attribute() | builtin-class IOError |

View File

@@ -3,4 +3,4 @@
| 36 | ControlFlowNode for a() |
| 51 | ControlFlowNode for open() |
| 56 | ControlFlowNode for Attribute() |
| 58 | ControlFlowNode for Attribute() |
| 58 | ControlFlowNode for Attribute() |

View File

@@ -0,0 +1 @@
semmle-extractor-options: --lang=2 --max-import-depth=2 -r package

View File

@@ -7,4 +7,4 @@
| 36 | class DerivedFromBuiltin | pop |
| 36 | class DerivedFromBuiltin | remove |
| 36 | class DerivedFromBuiltin | reverse |
| 36 | class DerivedFromBuiltin | sort |
| 36 | class DerivedFromBuiltin | sort |

View File

@@ -12,4 +12,4 @@
| Module package.helper | 2 | ImportExpr | 0 | bottom | absolute | assistant |
| Module package.helper | 3 | ImportExpr | 0 | top | absolute | sys |
| Module package.helper | 10 | ImportExpr | 1 | bottom | relative | package |
| Module test_star | 1 | ImportExpr | -1 | bottom | absolute | test_package |
| Module test_star | 1 | ImportExpr | -1 | bottom | absolute | test_package |

View File

@@ -54,4 +54,4 @@
| Module test_star | p | str b'p' |
| Module test_star | q | str b'q' |
| Module test_star | r | str b'r' |
| Module test_star | sys | Module sys |
| Module test_star | sys | Module sys |

View File

@@ -39,4 +39,4 @@
| Module test_star | p |
| Module test_star | q |
| Module test_star | r |
| Module test_star | sys |
| Module test_star | sys |

View File

@@ -5,4 +5,4 @@
| Module test_package.module2 | test_package.module2 |
| Module test_package.module3 | test_package.module3 |
| Module test_package.module4 | test_package.module4 |
| Module test_star | test_star |
| Module test_star | test_star |

View File

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

View File

@@ -5,5 +5,4 @@
| six.moves.range | builtin-class xrange |
| six.moves.urllib | Package six.moves.urllib |
| six.moves.urllib.parse | Module six.moves.urllib_parse |
| six.moves.urllib.parse.urlsplit | Function urlsplit |
| six.moves.zip | Builtin-function zip |

View File

@@ -4,4 +4,4 @@
| builtin-class type | __dict__ | Property __dict__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __doc__ | Property __doc__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __module__ | Property __module__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |

View File

@@ -8,4 +8,4 @@
| 38 | ControlFlowNode for ExceptStmt | builtin-class AttributeError |
| 40 | ControlFlowNode for ExceptStmt | builtin-class IndexError |
| 42 | ControlFlowNode for ExceptStmt | builtin-class KeyError |
| 57 | ControlFlowNode for ExceptStmt | builtin-class OSError |
| 57 | ControlFlowNode for ExceptStmt | builtin-class OSError |

View File

@@ -12,4 +12,4 @@
| 35 | ControlFlowNode for Attribute | builtin-class AttributeError |
| 37 | ControlFlowNode for Raise | builtin-class Exception |
| 53 | ControlFlowNode for Attribute() | builtin-class OSError |
| 54 | ControlFlowNode for Attribute() | builtin-class OSError |
| 54 | ControlFlowNode for Attribute() | builtin-class OSError |

View File

@@ -3,4 +3,4 @@
| 36 | ControlFlowNode for a() |
| 51 | ControlFlowNode for open() |
| 56 | ControlFlowNode for Attribute() |
| 58 | ControlFlowNode for Attribute() |
| 58 | ControlFlowNode for Attribute() |

View File

@@ -1,2 +1,2 @@
| 28 |
| 42 |
| 42 |

View File

@@ -0,0 +1,57 @@
| __init__.py | 1 | ControlFlowNode for ImportExpr | Module package.module | ControlFlowNode for ImportExpr |
| __init__.py | 2 | ControlFlowNode for ImportMember | Function module | ControlFlowNode for FunctionExpr |
| __init__.py | 2 | ControlFlowNode for module | Function module | ControlFlowNode for FunctionExpr |
| __init__.py | 4 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| __init__.py | 4 | ControlFlowNode for ImportMember | Module package.module2 | Entry node for Module package.module2 |
| __init__.py | 4 | ControlFlowNode for module3 | Module package.module2 | Entry node for Module package.module2 |
| __init__.py | 5 | ControlFlowNode for IntegerLiteral | int 7 | ControlFlowNode for IntegerLiteral |
| __init__.py | 5 | ControlFlowNode for module2 | int 7 | ControlFlowNode for IntegerLiteral |
| __init__.py | 6 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| __init__.py | 6 | ControlFlowNode for ImportMember | int 7 | ControlFlowNode for IntegerLiteral |
| __init__.py | 6 | ControlFlowNode for module4 | int 7 | ControlFlowNode for IntegerLiteral |
| __init__.py | 7 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| __init__.py | 7 | ControlFlowNode for ImportMember | Module package.module2 | Entry node for Module package.module2 |
| __init__.py | 7 | ControlFlowNode for module5 | Module package.module2 | Entry node for Module package.module2 |
| __init__.py | 8 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| __init__.py | 8 | ControlFlowNode for ImportMember | Module package.moduleX | Entry node for Module package.moduleX |
| __init__.py | 8 | ControlFlowNode for moduleX | Module package.moduleX | Entry node for Module package.moduleX |
| module2.py | 1 | ControlFlowNode for IntegerLiteral | int 0 | ControlFlowNode for IntegerLiteral |
| module2.py | 1 | ControlFlowNode for x | int 0 | ControlFlowNode for IntegerLiteral |
| module.py | 2 | ControlFlowNode for FunctionExpr | Function module | ControlFlowNode for FunctionExpr |
| module.py | 2 | ControlFlowNode for module | Function module | ControlFlowNode for FunctionExpr |
| moduleX.py | 1 | ControlFlowNode for ClassExpr | class Y | ControlFlowNode for ClassExpr |
| moduleX.py | 1 | ControlFlowNode for Y | class Y | ControlFlowNode for ClassExpr |
| moduleX.py | 1 | ControlFlowNode for object | builtin-class object | ControlFlowNode for object |
| test.py | 1 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| test.py | 2 | ControlFlowNode for ImportMember | Function module | ControlFlowNode for FunctionExpr |
| test.py | 2 | ControlFlowNode for module | Function module | ControlFlowNode for FunctionExpr |
| test.py | 4 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| test.py | 5 | ControlFlowNode for ImportMember | Module package.x | Entry node for Module package.x |
| test.py | 5 | ControlFlowNode for x | Module package.x | Entry node for Module package.x |
| test.py | 8 | ControlFlowNode for C | class C | ControlFlowNode for ClassExpr |
| test.py | 8 | ControlFlowNode for ClassExpr | class C | ControlFlowNode for ClassExpr |
| test.py | 8 | ControlFlowNode for object | builtin-class object | ControlFlowNode for object |
| test.py | 10 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| test.py | 10 | ControlFlowNode for ImportMember | int 7 | ControlFlowNode for IntegerLiteral |
| test.py | 10 | ControlFlowNode for module2 | int 7 | ControlFlowNode for IntegerLiteral |
| test.py | 12 | ControlFlowNode for FunctionExpr | Function f | ControlFlowNode for FunctionExpr |
| test.py | 12 | ControlFlowNode for f | Function f | ControlFlowNode for FunctionExpr |
| test.py | 13 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| test.py | 13 | ControlFlowNode for ImportMember | Module package.x | Entry node for Module package.x |
| test.py | 13 | ControlFlowNode for x | Module package.x | Entry node for Module package.x |
| test.py | 15 | ControlFlowNode for ImportExpr | Module package | ControlFlowNode for ImportExpr |
| test.py | 15 | ControlFlowNode for ImportMember | Module package.moduleX | Entry node for Module package.moduleX |
| test.py | 15 | ControlFlowNode for moduleX | Module package.moduleX | Entry node for Module package.moduleX |
| test.py | 16 | ControlFlowNode for Attribute | class Y | ControlFlowNode for ClassExpr |
| test.py | 16 | ControlFlowNode for moduleX | Module package.moduleX | Entry node for Module package.moduleX |
| test.py | 19 | ControlFlowNode for ImportExpr | Module tty | ControlFlowNode for ImportExpr |
| test.py | 19 | ControlFlowNode for tty | Module tty | ControlFlowNode for ImportExpr |
| test.py | 22 | ControlFlowNode for Attribute | Builtin-function exc_info | ControlFlowNode for from sys import * |
| test.py | 22 | ControlFlowNode for x | Module package.x | Entry node for Module package.x |
| test.py | 24 | ControlFlowNode for IntegerLiteral | int 0 | ControlFlowNode for IntegerLiteral |
| test.py | 24 | ControlFlowNode for argv | int 0 | ControlFlowNode for IntegerLiteral |
| test.py | 27 | ControlFlowNode for ImportExpr | Module sys | ControlFlowNode for ImportExpr |
| test.py | 31 | ControlFlowNode for argv | list object | ControlFlowNode for from sys import * |
| test.py | 33 | ControlFlowNode for ImportExpr | Module socket | ControlFlowNode for ImportExpr |
| test.py | 34 | ControlFlowNode for timeout | builtin-class TimeoutError | ControlFlowNode for from _socket import * |
| x.py | 2 | ControlFlowNode for ImportExpr | Module sys | ControlFlowNode for ImportExpr |

View File

@@ -0,0 +1,9 @@
import python
from int line, ControlFlowNode f, Object o, ControlFlowNode orig
where
not f.getLocation().getFile().inStdlib() and
f.refersTo(o, orig) and
line = f.getLocation().getStartLine() and
line != 0
select f.getLocation().getFile().getShortName(), line, f.toString(), o.toString(), orig.toString()

View File

@@ -0,0 +1,57 @@
| __init__.py | 1 | ControlFlowNode for ImportExpr | Module package.module | builtin-class module | ControlFlowNode for ImportExpr |
| __init__.py | 2 | ControlFlowNode for ImportMember | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
| __init__.py | 2 | ControlFlowNode for module | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
| __init__.py | 4 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| __init__.py | 4 | ControlFlowNode for ImportMember | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
| __init__.py | 4 | ControlFlowNode for module3 | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
| __init__.py | 5 | ControlFlowNode for IntegerLiteral | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
| __init__.py | 5 | ControlFlowNode for module2 | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
| __init__.py | 6 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| __init__.py | 6 | ControlFlowNode for ImportMember | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
| __init__.py | 6 | ControlFlowNode for module4 | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
| __init__.py | 7 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| __init__.py | 7 | ControlFlowNode for ImportMember | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
| __init__.py | 7 | ControlFlowNode for module5 | Module package.module2 | builtin-class module | Entry node for Module package.module2 |
| __init__.py | 8 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| __init__.py | 8 | ControlFlowNode for ImportMember | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
| __init__.py | 8 | ControlFlowNode for moduleX | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
| module2.py | 1 | ControlFlowNode for IntegerLiteral | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
| module2.py | 1 | ControlFlowNode for x | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
| module.py | 2 | ControlFlowNode for FunctionExpr | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
| module.py | 2 | ControlFlowNode for module | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
| moduleX.py | 1 | ControlFlowNode for ClassExpr | class Y | builtin-class type | ControlFlowNode for ClassExpr |
| moduleX.py | 1 | ControlFlowNode for Y | class Y | builtin-class type | ControlFlowNode for ClassExpr |
| moduleX.py | 1 | ControlFlowNode for object | builtin-class object | builtin-class type | ControlFlowNode for object |
| test.py | 1 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 2 | ControlFlowNode for ImportMember | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
| test.py | 2 | ControlFlowNode for module | Function module | builtin-class function | ControlFlowNode for FunctionExpr |
| test.py | 4 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 5 | ControlFlowNode for ImportMember | Module package.x | builtin-class module | Entry node for Module package.x |
| test.py | 5 | ControlFlowNode for x | Module package.x | builtin-class module | Entry node for Module package.x |
| test.py | 8 | ControlFlowNode for C | class C | builtin-class type | ControlFlowNode for ClassExpr |
| test.py | 8 | ControlFlowNode for ClassExpr | class C | builtin-class type | ControlFlowNode for ClassExpr |
| test.py | 8 | ControlFlowNode for object | builtin-class object | builtin-class type | ControlFlowNode for object |
| test.py | 10 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 10 | ControlFlowNode for ImportMember | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
| test.py | 10 | ControlFlowNode for module2 | int 7 | builtin-class int | ControlFlowNode for IntegerLiteral |
| test.py | 12 | ControlFlowNode for FunctionExpr | Function f | builtin-class function | ControlFlowNode for FunctionExpr |
| test.py | 12 | ControlFlowNode for f | Function f | builtin-class function | ControlFlowNode for FunctionExpr |
| test.py | 13 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 13 | ControlFlowNode for ImportMember | Module package.x | builtin-class module | Entry node for Module package.x |
| test.py | 13 | ControlFlowNode for x | Module package.x | builtin-class module | Entry node for Module package.x |
| test.py | 15 | ControlFlowNode for ImportExpr | Module package | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 15 | ControlFlowNode for ImportMember | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
| test.py | 15 | ControlFlowNode for moduleX | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
| test.py | 16 | ControlFlowNode for Attribute | class Y | builtin-class type | ControlFlowNode for ClassExpr |
| test.py | 16 | ControlFlowNode for moduleX | Module package.moduleX | builtin-class module | Entry node for Module package.moduleX |
| test.py | 19 | ControlFlowNode for ImportExpr | Module tty | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 19 | ControlFlowNode for tty | Module tty | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 22 | ControlFlowNode for Attribute | Builtin-function exc_info | builtin-class builtin_function_or_method | ControlFlowNode for from sys import * |
| test.py | 22 | ControlFlowNode for x | Module package.x | builtin-class module | Entry node for Module package.x |
| test.py | 24 | ControlFlowNode for IntegerLiteral | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
| test.py | 24 | ControlFlowNode for argv | int 0 | builtin-class int | ControlFlowNode for IntegerLiteral |
| test.py | 27 | ControlFlowNode for ImportExpr | Module sys | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 31 | ControlFlowNode for argv | list object | builtin-class list | ControlFlowNode for from sys import * |
| test.py | 33 | ControlFlowNode for ImportExpr | Module socket | builtin-class module | ControlFlowNode for ImportExpr |
| test.py | 34 | ControlFlowNode for timeout | builtin-class TimeoutError | builtin-class type | ControlFlowNode for from _socket import * |
| x.py | 2 | ControlFlowNode for ImportExpr | Module sys | builtin-class module | ControlFlowNode for ImportExpr |

View File

@@ -0,0 +1,10 @@
import python
from int line, ControlFlowNode f, Object o, ClassObject cls, ControlFlowNode orig
where
not f.getLocation().getFile().inStdlib() and
f.refersTo(o, cls, orig) and
line = f.getLocation().getStartLine() and
line != 0
select f.getLocation().getFile().getShortName(), line, f.toString(), o.toString(), cls.toString(),
orig.toString()

View File

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

View File

@@ -0,0 +1,15 @@
from .module \
import module
from . import module2 as module3
module2 = 7
from . import module2 as module4
from . import module3 as module5
from package import moduleX
#We should now have:
#module2 = 7
#module3 = package.module2
#module4 = 7
#module5 = package.module2
#moduleX = package.moduleX

View File

@@ -0,0 +1,3 @@
def module(args):
pass

View File

@@ -0,0 +1 @@
x = 0

View File

@@ -0,0 +1,2 @@
class Y(object):
pass

View File

@@ -0,0 +1,2 @@
from sys import *

View File

@@ -0,0 +1,34 @@
from package \
import module
from package \
import x
#Should work correctly in nested scopes as well.
class C(object):
from package import module2
def f(self):
from package import x
from package import moduleX
moduleX.Y
#A small stdlib module to test version handling.
import tty
#Check imports of builtin-objects using import * with no corresponding variable.
x.exc_info
argv = 0
try:
from sys import *
except:
pass
argv
from socket import *
timeout

View File

@@ -9,4 +9,4 @@
| 3 | class DerivedFromBuiltin | pop | Builtin-method pop |
| 3 | class DerivedFromBuiltin | remove | Builtin-method remove |
| 3 | class DerivedFromBuiltin | reverse | Builtin-method reverse |
| 3 | class DerivedFromBuiltin | sort | Builtin-method sort |
| 3 | class DerivedFromBuiltin | sort | Builtin-method sort |

View File

@@ -9,4 +9,4 @@
| 3 | class DerivedFromBuiltin | pop |
| 3 | class DerivedFromBuiltin | remove |
| 3 | class DerivedFromBuiltin | reverse |
| 3 | class DerivedFromBuiltin | sort |
| 3 | class DerivedFromBuiltin | sort |

View File

@@ -1 +1 @@
| ClassExpr | Meta |
| ClassExpr | Meta |

View File

@@ -1,2 +1,2 @@
| class HasMeta | class Meta |
| class Meta | builtin-class type |
| class Meta | builtin-class type |

View File

@@ -1,5 +1,14 @@
| module | hash_bang/module.py:0:0:0:0 | Module module |
| module | name_main/module.py:0:0:0:0 | Module module |
| namespace_package | hash_bang/namespace_package:0:0:0:0 | Package namespace_package |
| namespace_package | name_main/namespace_package:0:0:0:0 | Package namespace_package |
| namespace_package | no_py_extension/namespace_package:0:0:0:0 | Package namespace_package |
| namespace_package.namespace_package_main | hash_bang/namespace_package/namespace_package_main.py:0:0:0:0 | Module namespace_package.namespace_package_main |
| namespace_package.namespace_package_main | name_main/namespace_package/namespace_package_main.py:0:0:0:0 | Module namespace_package.namespace_package_main |
| namespace_package.namespace_package_main | no_py_extension/namespace_package/namespace_package_main.py:0:0:0:0 | Module namespace_package.namespace_package_main |
| namespace_package.namespace_package_module | hash_bang/namespace_package/namespace_package_module.py:0:0:0:0 | Module namespace_package.namespace_package_module |
| namespace_package.namespace_package_module | name_main/namespace_package/namespace_package_module.py:0:0:0:0 | Module namespace_package.namespace_package_module |
| namespace_package.namespace_package_module | no_py_extension/namespace_package/namespace_package_module.py:0:0:0:0 | Module namespace_package.namespace_package_module |
| package | hash_bang/package:0:0:0:0 | Package package |
| package | name_main/package:0:0:0:0 | Package package |
| package | no_py_extension/package:0:0:0:0 | Package package |

View File

@@ -57,4 +57,4 @@
| Module test_star | p | str u'p' |
| Module test_star | q | str u'q' |
| Module test_star | r | str u'r' |
| Module test_star | sys | Module sys |
| Module test_star | sys | Module sys |

View File

@@ -41,4 +41,4 @@
| Module test_star | p |
| Module test_star | q |
| Module test_star | r |
| Module test_star | sys |
| Module test_star | sys |

View File

@@ -6,4 +6,4 @@
| Module test_package.module3 | test_package.module3 |
| Module test_package.module4 | test_package.module4 |
| Module test_package.module5 | test_package.module5 |
| Module test_star | test_star |
| Module test_star | test_star |

View File

@@ -0,0 +1,6 @@
| file://:0:0:0:0 | Module sys | isUsedAsModule |
| file://:0:0:0:0 | Module sys.monitoring | 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: --lang=3 -F script

View File

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

View File

@@ -5,5 +5,4 @@
| six.moves.range | builtin-class range |
| six.moves.urllib | Package six.moves.urllib |
| six.moves.urllib.parse | Module six.moves.urllib_parse |
| six.moves.urllib.parse.urlsplit | Function urlsplit |
| six.moves.zip | builtin-class zip |

View File

@@ -1,44 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
import semmle.python.security.Exceptions
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}
class ExceptionInfoSource extends TaintSource {
ExceptionInfoSource() { this.(NameNode).getId() = "TAINTED_EXCEPTION_INFO" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExceptionInfo }
override string toString() { result = "Exception info source" }
}
class ExternalFileObjectSource extends TaintSource {
ExternalFileObjectSource() { this.(NameNode).getId() = "TAINTED_FILE" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalFileObject }
override string toString() { result = "Tainted file source" }
}

View File

@@ -1 +0,0 @@
| test.py:4 | ok | fstring | Fstring | externally controlled string |

View File

@@ -1,33 +0,0 @@
import python
import semmle.python.security.TaintTracking
import semmle.python.web.HttpRequest
import semmle.python.security.strings.Untrusted
import Taint
from
Call call, Expr arg, boolean expected_taint, boolean has_taint, string test_res,
string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
(
call.getFunc().(Name).getId() = "ensure_tainted" and
expected_taint = true
or
call.getFunc().(Name).getId() = "ensure_not_tainted" and
expected_taint = false
) and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "<NO TAINT>" and
has_taint = false
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
) and
has_taint = true
) and
if expected_taint = has_taint then test_res = "ok " else test_res = "fail"
// if expected_taint = has_taint then test_res = "✓" else test_res = "✕"
select arg.getLocation().toString(), test_res, call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,5 +0,0 @@
def fstring():
tainted_string = TAINTED_STRING
ensure_tainted(
f"foo {tainted_string} bar"
)

View File

@@ -1,27 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import semmle.python.security.strings.Untrusted
class SimpleSource extends TaintSource {
SimpleSource() { this.(NameNode).getId() = "TAINTED_STRING" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringKind }
override string toString() { result = "taint source" }
}
class ListSource extends TaintSource {
ListSource() { this.(NameNode).getId() = "TAINTED_LIST" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringSequenceKind }
override string toString() { result = "list taint source" }
}
class DictSource extends TaintSource {
DictSource() { this.(NameNode).getId() = "TAINTED_DICT" }
override predicate isSourceOf(TaintKind kind) { kind instanceof ExternalStringDictKind }
override string toString() { result = "dict taint source" }
}

View File

@@ -1,9 +0,0 @@
| test.py:11 | extended_unpacking | first | externally controlled string |
| test.py:11 | extended_unpacking | last | externally controlled string |
| test.py:11 | extended_unpacking | rest | [externally controlled string] |
| test.py:16 | also_allowed | a | [externally controlled string] |
| test.py:24 | also_allowed | b | NO TAINT |
| test.py:24 | also_allowed | c | NO TAINT |
| test.py:31 | nested | x | externally controlled string |
| test.py:31 | nested | xs | [externally controlled string] |
| test.py:31 | nested | ys | [externally controlled string] |

View File

@@ -1,19 +0,0 @@
import python
import semmle.python.dataflow.TaintTracking
import Taint
from Call call, Expr arg, string taint_string
where
call.getLocation().getFile().getShortName() = "test.py" and
call.getFunc().(Name).getId() = "test" and
arg = call.getAnArg() and
(
not exists(TaintedNode tainted | tainted.getAstNode() = arg) and
taint_string = "NO TAINT"
or
exists(TaintedNode tainted | tainted.getAstNode() = arg |
taint_string = tainted.getTaintKind().toString()
)
)
select arg.getLocation().toString(), call.getScope().(Function).getName(), arg.toString(),
taint_string

View File

@@ -1,31 +0,0 @@
# Extended Iterable Unpacking -- PEP 3132
# https://www.python.org/dev/peps/pep-3132/
def test(*args):
pass
def extended_unpacking():
first, *rest, last = TAINTED_LIST
test(first, rest, last)
def also_allowed():
*a, = TAINTED_LIST
test(a)
# for b, *c in [(1, 2, 3), (4, 5, 6, 7)]:
# print(c)
# i=0; c=[2,3]
# i=1; c=[5,6,7]
for b, *c in [TAINTED_LIST, TAINTED_LIST]:
test(b, c) # TODO: mark `c` as [taint]
def nested():
l = TAINTED_LIST
ll = [l,l]
[[x, *xs], ys] = ll
test(x, xs, ys)

View File

@@ -21,4 +21,4 @@
| 112 | multi_return | builtin-class int |
| 118 | do_something | builtin-class int |
| 123 | with_flow | builtin-class int |
| 128 | return_default | builtin-class tuple |
| 128 | return_default | builtin-class tuple |

View File

@@ -1,9 +1,12 @@
| builtin-class object | __class__ | Property __class__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __abstractmethods__ | Property __abstractmethods__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __annotations__ | Property __annotations__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __bases__ | Property __bases__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __dict__ | Property __dict__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __doc__ | Property __doc__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __module__ | Property __module__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __mro__ | Property __mro__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __name__ | Property __name__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __qualname__ | Property __qualname__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __text_signature__ | Property __text_signature__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __text_signature__ | Property __text_signature__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |
| builtin-class type | __type_params__ | Property __type_params__ | method-wrapper __get__ | method-wrapper __set__ | method-wrapper __delete__ |

View File

@@ -0,0 +1 @@
| 51 |

View File

@@ -0,0 +1 @@
Summary/LinesOfCode.ql

View File

@@ -0,0 +1 @@
| 11 |

View File

@@ -0,0 +1 @@
Summary/LinesOfUserCode.ql

View File

@@ -0,0 +1,7 @@
#!/usr/bin/env python
# although this is actually Python code, it is not included by the extractor by default.
print("this is also code")
print("but just dummy code")

View File

@@ -0,0 +1,26 @@
"""
module level docstring
is not included
"""
# this line is not code
# `tty` was chosen for stability over python versions (so we don't get diffrent results
# on different computers, that has different versions of Python).
#
# According to https://github.com/python/cpython/tree/master/Lib (at 2021-04-23) `tty`
# was last changed in 2001, so chances of this being changed in the future are slim.
import tty
s = """
all these lines are code
"""
print(s)
def func():
"""
this string is a doc-string. Although the module-level docstring is not considered
code, this one apparently is ¯\_(ツ)_/¯
"""
pass

View File

@@ -0,0 +1,5 @@
#!/bin/bash
# Although this is valid python code, it should not be counted as such.
print("foo")

View File

@@ -1,46 +1,6 @@
// TODO: this should be promoted to be a REAL consistency query by being placed in
// `python/ql/consistency-queries`. For for now it resides here.
import python
import semmle.python.dataflow.new.DataFlow::DataFlow
import semmle.python.dataflow.new.internal.DataFlowPrivate
import semmle.python.dataflow.new.internal.DataFlowImplConsistency::Consistency
// TODO: this should be promoted to be a REAL consistency query by being placed in
// `python/ql/consistency-queries`. For for now it resides here.
private class MyConsistencyConfiguration extends ConsistencyConfiguration {
override predicate argHasPostUpdateExclude(ArgumentNode n) {
exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isStarArgs(_))
or
exists(ArgumentPosition apos | n.argumentOf(_, apos) and apos.isDictSplat())
}
override predicate reverseReadExclude(Node n) {
// since `self`/`cls` parameters can be marked as implicit argument to `super()`,
// they will have PostUpdateNodes. We have a read-step from the synthetic `**kwargs`
// parameter, but dataflow-consistency queries should _not_ complain about there not
// being a post-update node for the synthetic `**kwargs` parameter.
n instanceof SynthDictSplatParameterNode
}
override predicate uniqueParameterNodePositionExclude(
DataFlowCallable c, ParameterPosition pos, Node p
) {
// For normal parameters that can both be passed as positional arguments or keyword
// arguments, we currently have parameter positions for both cases..
//
// TODO: Figure out how bad breaking this consistency check is
exists(Function func, Parameter param |
c.getScope() = func and
p = parameterNode(param) and
c.getParameter(pos) = p and
param = func.getArg(_) and
param = func.getArgByName(_)
)
}
override predicate uniqueCallEnclosingCallableExclude(DataFlowCall call) {
not exists(call.getLocation().getFile().getRelativePath())
}
override predicate identityLocalStepExclude(Node n) {
not exists(n.getLocation().getFile().getRelativePath())
}
}

View File

@@ -1,58 +1,117 @@
import python
import semmle.python.dataflow.new.DataFlow
import semmle.python.dataflow.new.TaintTracking
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowQueryTest extends InlineExpectationsTest {
DataFlowQueryTest() { this = "DataFlowQueryTest" }
signature module QueryTestSig {
predicate isSink(DataFlow::Node sink);
override string getARelevantTag() { result = "result" }
predicate flowTo(DataFlow::Node sink);
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Configuration cfg, DataFlow::Node sink | cfg.hasFlowTo(sink) |
location = sink.getLocation() and
tag = "result" and
value = "BAD" and
element = sink.toString()
)
module MakeQueryTest<QueryTestSig Impl> {
module DataFlowQueryTest implements TestSig {
string getARelevantTag() { result = "result" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node sink | Impl::flowTo(sink) |
location = sink.getLocation() and
tag = "result" and
value = "BAD" and
element = sink.toString()
)
}
// We allow annotating any sink with `result=OK` to signal
// safe sinks.
// Sometimes a line contains both an alert and a safe sink.
// In this situation, the annotation form `OK(safe sink)`
// can be useful.
predicate hasOptionalResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node sink | Impl::isSink(sink) |
location = sink.getLocation() and
tag = "result" and
value in ["OK", "OK(" + prettyNode(sink) + ")"] and
element = sink.toString()
)
}
}
// We allow annotating any sink with `result=OK` to signal
// safe sinks.
// Sometimes a line contains both an alert and a safe sink.
// In this situation, the annotation form `OK(safe sink)`
// can be useful.
override predicate hasOptionalResult(Location location, string element, string tag, string value) {
exists(DataFlow::Configuration cfg, DataFlow::Node sink |
cfg.isSink(sink) or cfg.isSink(sink, _)
|
import MakeTest<DataFlowQueryTest>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: result=BAD` or `result=OK` annotation" and
exists(DataFlow::Node sink |
exists(sink.getLocation().getFile().getRelativePath()) and
Impl::isSink(sink) and
location = sink.getLocation() and
tag = "result" and
value in ["OK", "OK(" + prettyNode(sink) + ")"] and
element = sink.toString()
element = prettyExpr(sink.asExpr()) and
not Impl::flowTo(sink) and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "result" and
missingResult.getValue() = "BAD" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
) and
not exists(GoodTestExpectation okResult |
okResult.getTag() = "result" and
okResult.getValue() in ["OK", "OK(" + prettyNode(sink) + ")"] and
okResult.getLocation().getFile() = location.getFile() and
okResult.getLocation().getStartLine() = location.getStartLine()
)
)
}
}
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: result=BAD` or `result=OK` annotation" and
exists(DataFlow::Node sink |
exists(sink.getLocation().getFile().getRelativePath()) and
exists(DataFlow::Configuration cfg | cfg.isSink(sink) or cfg.isSink(sink, _)) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not exists(DataFlow::Configuration cfg | cfg.hasFlowTo(sink)) and
not exists(FalseNegativeExpectation missingResult |
missingResult.getTag() = "result" and
missingResult.getValue() = "BAD" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()
) and
not exists(GoodExpectation okResult |
okResult.getTag() = "result" and
okResult.getValue() in ["OK", "OK(" + prettyNode(sink) + ")"] and
okResult.getLocation().getFile() = location.getFile() and
okResult.getLocation().getStartLine() = location.getStartLine()
)
)
module FromDataFlowConfig<DataFlow::ConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) }
predicate flowTo(DataFlow::Node sink) { DataFlow::Global<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
module FromDataFlowStateConfig<DataFlow::StateConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) or C::isSink(sink, _) }
predicate flowTo(DataFlow::Node sink) { DataFlow::GlobalWithState<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
module FromTaintTrackingConfig<DataFlow::ConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) }
predicate flowTo(DataFlow::Node sink) { TaintTracking::Global<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
module FromTaintTrackingStateConfig<DataFlow::StateConfigSig C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { C::isSink(sink) or C::isSink(sink, _) }
predicate flowTo(DataFlow::Node sink) { TaintTracking::GlobalWithState<C>::flowTo(sink) }
}
import MakeQueryTest<Impl>
}
signature class LegacyConfiguration extends DataFlow::Configuration;
module FromLegacyConfiguration<LegacyConfiguration C> {
module Impl implements QueryTestSig {
predicate isSink(DataFlow::Node sink) { any(C c).isSink(sink) or any(C c).isSink(sink, _) }
predicate flowTo(DataFlow::Node sink) { any(C c).hasFlowTo(sink) }
}
import MakeQueryTest<Impl>
}

View File

@@ -3,22 +3,21 @@ import semmle.python.dataflow.new.DataFlow
import TestUtilities.InlineExpectationsTest
private import semmle.python.dataflow.new.internal.PrintNode
abstract class FlowTest extends InlineExpectationsTest {
bindingset[this]
FlowTest() { any() }
signature module FlowTestSig {
string flowTag();
abstract string flowTag();
predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode);
}
abstract predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode);
module MakeTestSig<FlowTestSig Impl> implements TestSig {
string getARelevantTag() { result = Impl::flowTag() }
override string getARelevantTag() { result = this.flowTag() }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node fromNode, DataFlow::Node toNode | this.relevantFlow(fromNode, toNode) |
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node fromNode, DataFlow::Node toNode | Impl::relevantFlow(fromNode, toNode) |
location = toNode.getLocation() and
tag = this.flowTag() and
tag = Impl::flowTag() and
value =
"\"" + prettyNode(fromNode).replaceAll("\"", "'") + this.lineStr(fromNode, toNode) + " -> " +
"\"" + prettyNode(fromNode).replaceAll("\"", "'") + lineStr(fromNode, toNode) + " -> " +
prettyNode(toNode).replaceAll("\"", "'") + "\"" and
element = toNode.toString()
)

View File

@@ -2,12 +2,12 @@ import python
import semmle.python.dataflow.new.DataFlow
import FlowTest
class LocalFlowStepTest extends FlowTest {
LocalFlowStepTest() { this = "LocalFlowStepTest" }
module LocalFlowStepTest implements FlowTestSig {
string flowTag() { result = "step" }
override string flowTag() { result = "step" }
override predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode) {
predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode) {
DataFlow::localFlowStep(fromNode, toNode)
}
}
import MakeTest<MakeTestSig<LocalFlowStepTest>>

View File

@@ -3,25 +3,23 @@ import semmle.python.dataflow.new.DataFlow
private import semmle.python.dataflow.new.internal.DataFlowPrivate
import FlowTest
class MaximalFlowTest extends FlowTest {
MaximalFlowTest() { this = "MaximalFlowTest" }
module MaximalFlowTest implements FlowTestSig {
string flowTag() { result = "flow" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
source != sink and
exists(MaximalFlowsConfig cfg | cfg.hasFlow(source, sink))
MaximalFlows::flow(source, sink)
}
}
import MakeTest<MakeTestSig<MaximalFlowTest>>
/**
* A configuration to find all "maximal" flows.
* To be used on small programs.
*/
class MaximalFlowsConfig extends DataFlow::Configuration {
MaximalFlowsConfig() { this = "MaximalFlowsConfig" }
override predicate isSource(DataFlow::Node node) {
module MaximalFlowsConfig implements DataFlow::ConfigSig {
predicate isSource(DataFlow::Node node) {
exists(node.getLocation().getFile().getRelativePath()) and
not node.asCfgNode() instanceof CallNode and
not node.asCfgNode().getNode() instanceof Return and
@@ -32,7 +30,7 @@ class MaximalFlowsConfig extends DataFlow::Configuration {
not DataFlow::localFlowStep(_, node)
}
override predicate isSink(DataFlow::Node node) {
predicate isSink(DataFlow::Node node) {
exists(node.getLocation().getFile().getRelativePath()) and
not any(CallNode c).getArg(_) = node.asCfgNode() and
not node instanceof DataFlow::ArgumentNode and
@@ -40,3 +38,5 @@ class MaximalFlowsConfig extends DataFlow::Configuration {
not DataFlow::localFlowStep(node, _)
}
}
module MaximalFlows = DataFlow::Global<MaximalFlowsConfig>;

View File

@@ -3,20 +3,20 @@ import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testConfig
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
module DataFlowTest implements FlowTestSig {
string flowTag() { result = "flow" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
TestFlow::flow(source, sink)
}
}
import MakeTest<MakeTestSig<DataFlowTest>>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: flow` annotation" and
exists(DataFlow::Node sink |
any(TestConfiguration config).isSink(sink) and
TestConfig::isSink(sink) and
// note: we only care about `SINK` and not `SINK_F`, so we have to reconstruct manually.
exists(DataFlow::CallCfgNode call |
call.getFunction().asCfgNode().(NameNode).getId() = "SINK" and
@@ -24,8 +24,8 @@ query predicate missingAnnotationOnSink(Location location, string error, string
) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not any(TestConfiguration config).hasFlow(_, sink) and
not exists(FalseNegativeExpectation missingResult |
not TestFlow::flowTo(sink) and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "flow" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()

View File

@@ -3,16 +3,16 @@ import experimental.dataflow.TestUtil.FlowTest
import experimental.dataflow.testTaintConfig
private import semmle.python.dataflow.new.internal.PrintNode
class DataFlowTest extends FlowTest {
DataFlowTest() { this = "DataFlowTest" }
module DataFlowTest implements FlowTestSig {
string flowTag() { result = "flow" }
override string flowTag() { result = "flow" }
override predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
exists(TestConfiguration cfg | cfg.hasFlow(source, sink))
predicate relevantFlow(DataFlow::Node source, DataFlow::Node sink) {
TestFlow::flow(source, sink)
}
}
import MakeTest<MakeTestSig<DataFlowTest>>
query predicate missingAnnotationOnSink(Location location, string error, string element) {
error = "ERROR, you should add `# $ MISSING: flow` annotation" and
exists(DataFlow::Node sink |
@@ -23,8 +23,8 @@ query predicate missingAnnotationOnSink(Location location, string error, string
) and
location = sink.getLocation() and
element = prettyExpr(sink.asExpr()) and
not any(TestConfiguration config).hasFlow(_, sink) and
not exists(FalseNegativeExpectation missingResult |
not TestFlow::flowTo(sink) and
not exists(FalseNegativeTestExpectation missingResult |
missingResult.getTag() = "flow" and
missingResult.getLocation().getFile() = location.getFile() and
missingResult.getLocation().getStartLine() = location.getStartLine()

View File

@@ -10,22 +10,25 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
* the functions tested sink their arguments sequentially, that is
* `SINK1(arg1)`, etc.
*/
abstract class RoutingTest extends InlineExpectationsTest {
bindingset[this]
RoutingTest() { any() }
signature module RoutingTestSig {
class Argument;
abstract string flowTag();
string flowTag(Argument arg);
abstract predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode);
predicate relevantFlow(DataFlow::Node fromNode, DataFlow::Node toNode, Argument arg);
}
override string getARelevantTag() { result in ["func", this.flowTag()] }
module MakeTestSig<RoutingTestSig Impl> implements TestSig {
string getARelevantTag() { result in ["func", Impl::flowTag(_)] }
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node fromNode, DataFlow::Node toNode | this.relevantFlow(fromNode, toNode) |
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(DataFlow::Node fromNode, DataFlow::Node toNode, Impl::Argument arg |
Impl::relevantFlow(fromNode, toNode, arg)
|
location = fromNode.getLocation() and
element = fromNode.toString() and
(
tag = this.flowTag() and
tag = Impl::flowTag(arg) and
if "\"" + tag + "\"" = fromValue(fromNode) then value = "" else value = fromValue(fromNode)
or
// only have result for `func` tag if the function where `arg<n>` is used, is

View File

@@ -4,11 +4,11 @@ private import semmle.python.dataflow.new.internal.DataFlowPrivate as DataFlowPr
private import semmle.python.ApiGraphs
import TestUtilities.InlineExpectationsTest
class UnresolvedCallExpectations extends InlineExpectationsTest {
UnresolvedCallExpectations() { this = "UnresolvedCallExpectations" }
override string getARelevantTag() { result = "unresolved_call" }
signature module UnresolvedCallExpectationsSig {
predicate unresolvedCall(CallNode call);
}
module DefaultUnresolvedCallExpectations implements UnresolvedCallExpectationsSig {
predicate unresolvedCall(CallNode call) {
not exists(DataFlowPrivate::DataFlowCall dfc |
exists(dfc.getCallable()) and dfc.getNode() = call
@@ -16,14 +16,22 @@ class UnresolvedCallExpectations extends InlineExpectationsTest {
not DataFlowPrivate::resolveClassCall(call, _) and
not call = API::builtin(_).getACall().asCfgNode()
}
override predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CallNode call | this.unresolvedCall(call) |
location = call.getLocation() and
tag = "unresolved_call" and
value = prettyExpr(call.getNode()) and
element = call.toString()
)
}
}
module MakeUnresolvedCallExpectations<UnresolvedCallExpectationsSig Impl> {
private module UnresolvedCallExpectations implements TestSig {
string getARelevantTag() { result = "unresolved_call" }
predicate hasActualResult(Location location, string element, string tag, string value) {
exists(location.getFile().getRelativePath()) and
exists(CallNode call | Impl::unresolvedCall(call) |
location = call.getLocation() and
tag = "unresolved_call" and
value = prettyExpr(call.getNode()) and
element = call.toString()
)
}
}
import MakeTest<UnresolvedCallExpectations>
}

View File

@@ -4,7 +4,6 @@ uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
@@ -24,3 +23,5 @@ uniqueParameterNodeAtPosition
uniqueParameterNodePosition
uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall

View File

@@ -1,6 +1,5 @@
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id |
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:1:5:1:17 | GSSA Variable obfuscated_id |
| test.py:1:1:1:21 | ControlFlowNode for FunctionExpr | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id |
| test.py:1:5:1:17 | GSSA Variable obfuscated_id | test.py:7:5:7:17 | ControlFlowNode for obfuscated_id |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:1:19:1:19 | SSA variable x |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:1:19:1:19 | SSA variable x |
@@ -14,18 +13,6 @@
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:2:7:2:7 | ControlFlowNode for x |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:2:7:2:7 | ControlFlowNode for x |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:2:7:2:7 | ControlFlowNode for x |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | SSA variable x | test.py:2:3:2:3 | SSA variable y |
| test.py:1:19:1:19 | SSA variable x | test.py:2:3:2:3 | SSA variable y |
| test.py:1:19:1:19 | SSA variable x | test.py:2:3:2:3 | SSA variable y |
@@ -34,18 +21,6 @@
| test.py:1:19:1:19 | SSA variable x | test.py:2:7:2:7 | ControlFlowNode for x |
| test.py:1:19:1:19 | SSA variable x | test.py:2:7:2:7 | ControlFlowNode for x |
| test.py:1:19:1:19 | SSA variable x | test.py:2:7:2:7 | ControlFlowNode for x |
| test.py:1:19:1:19 | SSA variable x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | SSA variable x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | SSA variable x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | SSA variable x | test.py:3:3:3:3 | SSA variable z |
| test.py:1:19:1:19 | SSA variable x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | SSA variable x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | SSA variable x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | SSA variable x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:1:19:1:19 | SSA variable x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | SSA variable x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | SSA variable x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:1:19:1:19 | SSA variable x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:3:2:3 | SSA variable y | test.py:3:3:3:3 | SSA variable z |
| test.py:2:3:2:3 | SSA variable y | test.py:3:3:3:3 | SSA variable z |
| test.py:2:3:2:3 | SSA variable y | test.py:3:3:3:3 | SSA variable z |
@@ -54,26 +29,10 @@
| test.py:2:3:2:3 | SSA variable y | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:3:2:3 | SSA variable y | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:3:2:3 | SSA variable y | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:3:2:3 | SSA variable y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:3:2:3 | SSA variable y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:3:2:3 | SSA variable y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:3:2:3 | SSA variable y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:2:3:2:3 | SSA variable y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:2:3:2:3 | SSA variable y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:2:3:2:3 | SSA variable y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:2:3:2:3 | SSA variable y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:3:3:3 | SSA variable z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:3:7:3:7 | ControlFlowNode for y |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:2:7:2:7 | ControlFlowNode for x | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:3:3:3:3 | SSA variable z | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:3:3:3:3 | SSA variable z | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:3:3:3:3 | SSA variable z | test.py:4:10:4:10 | ControlFlowNode for z |
@@ -82,18 +41,12 @@
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:3:3:3:3 | SSA variable z |
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:3:3:3:3 | SSA variable z |
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:3:3:3:3 | SSA variable z |
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:3:7:3:7 | ControlFlowNode for y | test.py:4:10:4:10 | ControlFlowNode for z |
| test.py:4:10:4:10 | ControlFlowNode for z | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
| test.py:4:10:4:10 | ControlFlowNode for z | test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() |
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
| test.py:6:1:6:1 | GSSA Variable a | test.py:7:19:7:19 | ControlFlowNode for a |
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:6:1:6:1 | GSSA Variable a |
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a |
| test.py:6:5:6:6 | ControlFlowNode for IntegerLiteral | test.py:7:19:7:19 | ControlFlowNode for a |
| test.py:7:5:7:20 | ControlFlowNode for obfuscated_id() | test.py:7:1:7:1 | GSSA Variable b |
| test.py:7:19:7:19 | ControlFlowNode for a | test.py:1:19:1:19 | ControlFlowNode for x |
| test.py:7:19:7:19 | ControlFlowNode for a | test.py:1:19:1:19 | ControlFlowNode for x |

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -0,0 +1,2 @@
testFailures
failures

View File

@@ -4,7 +4,6 @@ uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
@@ -24,3 +23,5 @@ uniqueParameterNodeAtPosition
uniqueParameterNodePosition
uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall

View File

@@ -1,2 +1,2 @@
failures
testFailures
failures

View File

@@ -1,14 +1,9 @@
uniqueEnclosingCallable
uniqueCallEnclosingCallable
| new_cls_param.py:14:6:14:16 | classmethod() | Call should have one enclosing callable but has 0. |
| test.py:21:6:21:17 | staticmethod() | Call should have one enclosing callable but has 0. |
| test.py:25:6:25:16 | classmethod() | Call should have one enclosing callable but has 0. |
| test.py:29:6:29:16 | classmethod() | Call should have one enclosing callable but has 0. |
uniqueType
uniqueNodeLocation
missingLocation
uniqueNodeToString
missingToString
parameterCallable
localFlowIsLocal
readStepIsLocal
@@ -28,3 +23,5 @@ uniqueParameterNodeAtPosition
uniqueParameterNodePosition
uniqueContentApprox
identityLocalStep
missingArgumentCall
multipleArgumentCall

Some files were not shown because too many files have changed in this diff Show More