Merge pull request #2078 from taus-semmle/python-unreachable-suppressed

Python: Teach `py/unreachable-statement` about `contextlib.suppress`.
This commit is contained in:
Rasmus Wriedt Larsen
2019-10-21 15:14:39 +02:00
committed by GitHub
5 changed files with 57 additions and 0 deletions

View File

@@ -12,3 +12,11 @@
| Clear-text logging of sensitive information (`py/clear-text-logging-sensitive-data`) | security, external/cwe/cwe-312 | Finds instances where sensitive information is logged without encryption or hashing. Results are shown on LGTM by default. |
| Clear-text storage of sensitive information (`py/clear-text-storage-sensitive-data`) | security, external/cwe/cwe-312 | Finds instances where sensitive information is stored without encryption or hashing. Results are shown on LGTM by default. |
| Binding a socket to all network interfaces (`py/bind-socket-all-network-interfaces`) | security | Finds instances where a socket is bound to all network interfaces. Results are shown on LGTM by default. |
## Changes to existing queries
| **Query** | **Expected impact** | **Change** |
|----------------------------|------------------------|------------|
| Unreachable code | Fewer false positives | Analysis now accounts for uses of `contextlib.suppress` to suppress exceptions. |

View File

@@ -31,9 +31,18 @@ predicate unique_yield(Stmt s) {
)
}
/** Holds if `contextlib.suppress` may be used in the same scope as `s` */
predicate suppression_in_scope(Stmt s) {
exists(With w |
w.getContextExpr().(Call).getFunc().pointsTo(Value::named("contextlib.suppress")) and
w.getScope() = s.getScope()
)
}
predicate reportable_unreachable(Stmt s) {
s.isUnreachable() and
not typing_import(s) and
not suppression_in_scope(s) and
not exists(Stmt other | other.isUnreachable() |
other.contains(s)
or

View File

@@ -0,0 +1 @@
Statements/UnreachableCode.ql

View File

@@ -0,0 +1,39 @@
from contextlib import suppress
def raises_exception():
raise Exception("This will be suppressed")
def foo():
test = False
with suppress(Exception):
raises_exception()
test = True
if test:
return
print("An exception was raised") # FP: not reached
foo()
def bar(x):
test = False
try:
if x:
raise Exception("Bar")
test = True
except Exception:
pass
if test:
print("Test was set")
return
print("Test was not set")
bar(True)
bar(False)
# False negative
def fn_suppression():
with suppress(Exception):
raise Exception()
return False
return True