mirror of
https://github.com/github/codeql.git
synced 2026-04-30 03:05:15 +02:00
Python: Autoformat everything using qlformat.
Will need subsequent PRs fixing up test failures (due to deprecated methods moving around), but other than that everything should be straight-forward.
This commit is contained in:
@@ -17,13 +17,13 @@ import python
|
||||
predicate doesnt_reraise(ExceptStmt ex) { ex.getAFlowNode().getBasicBlock().reachesExit() }
|
||||
|
||||
predicate catches_base_exception(ExceptStmt ex) {
|
||||
ex.getType().pointsTo(ClassValue::baseException())
|
||||
or
|
||||
not exists(ex.getType())
|
||||
ex.getType().pointsTo(ClassValue::baseException())
|
||||
or
|
||||
not exists(ex.getType())
|
||||
}
|
||||
|
||||
from ExceptStmt ex
|
||||
where
|
||||
catches_base_exception(ex) and
|
||||
doesnt_reraise(ex)
|
||||
catches_base_exception(ex) and
|
||||
doesnt_reraise(ex)
|
||||
select ex, "Except block directly handles BaseException."
|
||||
|
||||
@@ -14,88 +14,88 @@
|
||||
import python
|
||||
|
||||
predicate empty_except(ExceptStmt ex) {
|
||||
not exists(Stmt s | s = ex.getAStmt() and not s instanceof Pass)
|
||||
not exists(Stmt s | s = ex.getAStmt() and not s instanceof Pass)
|
||||
}
|
||||
|
||||
predicate no_else(ExceptStmt ex) { not exists(ex.getTry().getOrelse()) }
|
||||
|
||||
predicate no_comment(ExceptStmt ex) {
|
||||
not exists(Comment c |
|
||||
c.getLocation().getFile() = ex.getLocation().getFile() and
|
||||
c.getLocation().getStartLine() >= ex.getLocation().getStartLine() and
|
||||
c.getLocation().getEndLine() <= ex.getBody().getLastItem().getLocation().getEndLine()
|
||||
)
|
||||
not exists(Comment c |
|
||||
c.getLocation().getFile() = ex.getLocation().getFile() and
|
||||
c.getLocation().getStartLine() >= ex.getLocation().getStartLine() and
|
||||
c.getLocation().getEndLine() <= ex.getBody().getLastItem().getLocation().getEndLine()
|
||||
)
|
||||
}
|
||||
|
||||
predicate non_local_control_flow(ExceptStmt ex) {
|
||||
ex.getType().pointsTo(ClassValue::stopIteration())
|
||||
ex.getType().pointsTo(ClassValue::stopIteration())
|
||||
}
|
||||
|
||||
predicate try_has_normal_exit(Try try) {
|
||||
exists(ControlFlowNode pred, ControlFlowNode succ |
|
||||
/* Exists a non-exception predecessor, successor pair */
|
||||
pred.getASuccessor() = succ and
|
||||
not pred.getAnExceptionalSuccessor() = succ
|
||||
|
|
||||
/* Successor is either a normal flow node or a fall-through exit */
|
||||
not exists(Scope s | s.getReturnNode() = succ) and
|
||||
/* Predecessor is in try body and successor is not */
|
||||
pred.getNode().getParentNode*() = try.getAStmt() and
|
||||
not succ.getNode().getParentNode*() = try.getAStmt()
|
||||
)
|
||||
exists(ControlFlowNode pred, ControlFlowNode succ |
|
||||
/* Exists a non-exception predecessor, successor pair */
|
||||
pred.getASuccessor() = succ and
|
||||
not pred.getAnExceptionalSuccessor() = succ
|
||||
|
|
||||
/* Successor is either a normal flow node or a fall-through exit */
|
||||
not exists(Scope s | s.getReturnNode() = succ) and
|
||||
/* Predecessor is in try body and successor is not */
|
||||
pred.getNode().getParentNode*() = try.getAStmt() and
|
||||
not succ.getNode().getParentNode*() = try.getAStmt()
|
||||
)
|
||||
}
|
||||
|
||||
predicate attribute_access(Stmt s) {
|
||||
s.(ExprStmt).getValue() instanceof Attribute
|
||||
or
|
||||
exists(string name | s.(ExprStmt).getValue().(Call).getFunc().(Name).getId() = name |
|
||||
name = "getattr" or name = "setattr" or name = "delattr"
|
||||
)
|
||||
or
|
||||
s.(Delete).getATarget() instanceof Attribute
|
||||
s.(ExprStmt).getValue() instanceof Attribute
|
||||
or
|
||||
exists(string name | s.(ExprStmt).getValue().(Call).getFunc().(Name).getId() = name |
|
||||
name = "getattr" or name = "setattr" or name = "delattr"
|
||||
)
|
||||
or
|
||||
s.(Delete).getATarget() instanceof Attribute
|
||||
}
|
||||
|
||||
predicate subscript(Stmt s) {
|
||||
s.(ExprStmt).getValue() instanceof Subscript
|
||||
or
|
||||
s.(Delete).getATarget() instanceof Subscript
|
||||
s.(ExprStmt).getValue() instanceof Subscript
|
||||
or
|
||||
s.(Delete).getATarget() instanceof Subscript
|
||||
}
|
||||
|
||||
predicate encode_decode(Call ex, ClassValue type) {
|
||||
exists(string name | ex.getFunc().(Attribute).getName() = name |
|
||||
name = "encode" and type = ClassValue::unicodeEncodeError()
|
||||
or
|
||||
name = "decode" and type = ClassValue::unicodeDecodeError()
|
||||
)
|
||||
exists(string name | ex.getFunc().(Attribute).getName() = name |
|
||||
name = "encode" and type = ClassValue::unicodeEncodeError()
|
||||
or
|
||||
name = "decode" and type = ClassValue::unicodeDecodeError()
|
||||
)
|
||||
}
|
||||
|
||||
predicate small_handler(ExceptStmt ex, Stmt s, ClassValue type) {
|
||||
not exists(ex.getTry().getStmt(1)) and
|
||||
s = ex.getTry().getStmt(0) and
|
||||
ex.getType().pointsTo(type)
|
||||
not exists(ex.getTry().getStmt(1)) and
|
||||
s = ex.getTry().getStmt(0) and
|
||||
ex.getType().pointsTo(type)
|
||||
}
|
||||
|
||||
predicate focussed_handler(ExceptStmt ex) {
|
||||
exists(Stmt s, ClassValue type | small_handler(ex, s, type) |
|
||||
subscript(s) and type.getASuperType() = ClassValue::lookupError()
|
||||
or
|
||||
attribute_access(s) and type = ClassValue::attributeError()
|
||||
or
|
||||
s.(ExprStmt).getValue() instanceof Name and type = ClassValue::nameError()
|
||||
or
|
||||
encode_decode(s.(ExprStmt).getValue(), type)
|
||||
)
|
||||
exists(Stmt s, ClassValue type | small_handler(ex, s, type) |
|
||||
subscript(s) and type.getASuperType() = ClassValue::lookupError()
|
||||
or
|
||||
attribute_access(s) and type = ClassValue::attributeError()
|
||||
or
|
||||
s.(ExprStmt).getValue() instanceof Name and type = ClassValue::nameError()
|
||||
or
|
||||
encode_decode(s.(ExprStmt).getValue(), type)
|
||||
)
|
||||
}
|
||||
|
||||
Try try_return() { not exists(result.getStmt(1)) and result.getStmt(0) instanceof Return }
|
||||
|
||||
from ExceptStmt ex
|
||||
where
|
||||
empty_except(ex) and
|
||||
no_else(ex) and
|
||||
no_comment(ex) and
|
||||
not non_local_control_flow(ex) and
|
||||
not ex.getTry() = try_return() and
|
||||
try_has_normal_exit(ex.getTry()) and
|
||||
not focussed_handler(ex)
|
||||
empty_except(ex) and
|
||||
no_else(ex) and
|
||||
no_comment(ex) and
|
||||
not non_local_control_flow(ex) and
|
||||
not ex.getTry() = try_return() and
|
||||
try_has_normal_exit(ex.getTry()) and
|
||||
not focussed_handler(ex)
|
||||
select ex, "'except' clause does nothing but pass and there is no explanatory comment."
|
||||
|
||||
@@ -15,16 +15,16 @@ import python
|
||||
|
||||
from ExceptFlowNode ex, Value t, ClassValue c, ControlFlowNode origin, string what
|
||||
where
|
||||
ex.handledException(t, c, origin) and
|
||||
(
|
||||
exists(ClassValue x | x = t |
|
||||
not x.isLegalExceptionType() and
|
||||
not x.failedInference(_) and
|
||||
what = "class '" + x.getName() + "'"
|
||||
)
|
||||
or
|
||||
not t instanceof ClassValue and
|
||||
what = "instance of '" + c.getName() + "'"
|
||||
ex.handledException(t, c, origin) and
|
||||
(
|
||||
exists(ClassValue x | x = t |
|
||||
not x.isLegalExceptionType() and
|
||||
not x.failedInference(_) and
|
||||
what = "class '" + x.getName() + "'"
|
||||
)
|
||||
or
|
||||
not t instanceof ClassValue and
|
||||
what = "instance of '" + c.getName() + "'"
|
||||
)
|
||||
select ex.getNode(),
|
||||
"Non-exception $@ in exception handler which will never match raised exception.", origin, what
|
||||
"Non-exception $@ in exception handler which will never match raised exception.", origin, what
|
||||
|
||||
@@ -17,9 +17,9 @@ import Exceptions.NotImplemented
|
||||
|
||||
from Raise r, ClassValue t
|
||||
where
|
||||
type_or_typeof(r, t, _) and
|
||||
not t.isLegalExceptionType() and
|
||||
not t.failedInference(_) and
|
||||
not use_of_not_implemented_in_raise(r, _)
|
||||
type_or_typeof(r, t, _) and
|
||||
not t.isLegalExceptionType() and
|
||||
not t.failedInference(_) and
|
||||
not use_of_not_implemented_in_raise(r, _)
|
||||
select r,
|
||||
"Illegal class '" + t.getName() + "' raised; will result in a TypeError being raised instead."
|
||||
"Illegal class '" + t.getName() + "' raised; will result in a TypeError being raised instead."
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
import python
|
||||
|
||||
predicate incorrect_except_order(ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2) {
|
||||
exists(int i, int j, Try t |
|
||||
ex1 = t.getHandler(i) and
|
||||
ex2 = t.getHandler(j) and
|
||||
i < j and
|
||||
cls1 = except_class(ex1) and
|
||||
cls2 = except_class(ex2) and
|
||||
cls1 = cls2.getASuperType()
|
||||
)
|
||||
exists(int i, int j, Try t |
|
||||
ex1 = t.getHandler(i) and
|
||||
ex2 = t.getHandler(j) and
|
||||
i < j and
|
||||
cls1 = except_class(ex1) and
|
||||
cls2 = except_class(ex2) and
|
||||
cls1 = cls2.getASuperType()
|
||||
)
|
||||
}
|
||||
|
||||
ClassValue except_class(ExceptStmt ex) { ex.getType().pointsTo(result) }
|
||||
@@ -30,5 +30,5 @@ ClassValue except_class(ExceptStmt ex) { ex.getType().pointsTo(result) }
|
||||
from ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2
|
||||
where incorrect_except_order(ex1, cls1, ex2, cls2)
|
||||
select ex2,
|
||||
"Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference.",
|
||||
cls2, cls2.getName(), ex1, "except block", cls1, cls1.getName()
|
||||
"Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference.",
|
||||
cls2, cls2.getName(), ex1, "except block", cls1, cls1.getName()
|
||||
|
||||
@@ -2,9 +2,9 @@ import python
|
||||
|
||||
/** Holds if `notimpl` refers to `NotImplemented` or `NotImplemented()` in the `raise` statement */
|
||||
predicate use_of_not_implemented_in_raise(Raise raise, Expr notimpl) {
|
||||
notimpl.pointsTo(Value::named("NotImplemented")) and
|
||||
(
|
||||
notimpl = raise.getException() or
|
||||
notimpl = raise.getException().(Call).getFunc()
|
||||
)
|
||||
notimpl.pointsTo(Value::named("NotImplemented")) and
|
||||
(
|
||||
notimpl = raise.getException() or
|
||||
notimpl = raise.getException().(Call).getFunc()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,11 @@ import python
|
||||
|
||||
/** Whether the raise statement 'r' raises 'type' from origin 'orig' */
|
||||
predicate type_or_typeof(Raise r, ClassValue type, AstNode orig) {
|
||||
exists(Expr exception | exception = r.getRaised() |
|
||||
exception.pointsTo(type, orig)
|
||||
or
|
||||
not exists(ClassValue exc_type | exception.pointsTo(exc_type)) and
|
||||
not type = ClassValue::type() and // First value is an unknown exception type
|
||||
exists(Value val | exception.pointsTo(val, orig) | val.getClass() = type)
|
||||
)
|
||||
exists(Expr exception | exception = r.getRaised() |
|
||||
exception.pointsTo(type, orig)
|
||||
or
|
||||
not exists(ClassValue exc_type | exception.pointsTo(exc_type)) and
|
||||
not type = ClassValue::type() and // First value is an unknown exception type
|
||||
exists(Value val | exception.pointsTo(val, orig) | val.getClass() = type)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -13,10 +13,10 @@ import python
|
||||
|
||||
from Raise r, Value v, AstNode origin
|
||||
where
|
||||
r.getException().pointsTo(v, origin) and
|
||||
v.getClass() = ClassValue::tuple() and
|
||||
major_version() = 2
|
||||
r.getException().pointsTo(v, origin) and
|
||||
v.getClass() = ClassValue::tuple() and
|
||||
major_version() = 2
|
||||
/* Raising a tuple is a type error in Python 3, so is handled by the IllegalRaise query. */
|
||||
select r,
|
||||
"Raising $@ will result in the first element (recursively) being raised and all other elements being discarded.",
|
||||
origin, "a tuple"
|
||||
"Raising $@ will result in the first element (recursively) being raised and all other elements being discarded.",
|
||||
origin, "a tuple"
|
||||
|
||||
@@ -17,45 +17,45 @@ FunctionValue iter() { result = Value::named("iter") }
|
||||
BuiltinFunctionValue next() { result = Value::named("next") }
|
||||
|
||||
predicate call_to_iter(CallNode call, EssaVariable sequence) {
|
||||
sequence.getAUse() = iter().getArgumentForCall(call, 0)
|
||||
sequence.getAUse() = iter().getArgumentForCall(call, 0)
|
||||
}
|
||||
|
||||
predicate call_to_next(CallNode call, ControlFlowNode iter) {
|
||||
iter = next().getArgumentForCall(call, 0)
|
||||
iter = next().getArgumentForCall(call, 0)
|
||||
}
|
||||
|
||||
predicate call_to_next_has_default(CallNode call) {
|
||||
exists(call.getArg(1)) or exists(call.getArgByName("default"))
|
||||
exists(call.getArg(1)) or exists(call.getArgByName("default"))
|
||||
}
|
||||
|
||||
predicate guarded_not_empty_sequence(EssaVariable sequence) {
|
||||
sequence.getDefinition() instanceof EssaEdgeRefinement
|
||||
sequence.getDefinition() instanceof EssaEdgeRefinement
|
||||
}
|
||||
|
||||
/** The pattern `next(iter(x))` is often used where `x` is known not be empty. Check for that. */
|
||||
predicate iter_not_exhausted(EssaVariable iterator) {
|
||||
exists(EssaVariable sequence |
|
||||
call_to_iter(iterator.getDefinition().(AssignmentDefinition).getValue(), sequence) and
|
||||
guarded_not_empty_sequence(sequence)
|
||||
)
|
||||
exists(EssaVariable sequence |
|
||||
call_to_iter(iterator.getDefinition().(AssignmentDefinition).getValue(), sequence) and
|
||||
guarded_not_empty_sequence(sequence)
|
||||
)
|
||||
}
|
||||
|
||||
predicate stop_iteration_handled(CallNode call) {
|
||||
exists(Try t |
|
||||
t.containsInScope(call.getNode()) and
|
||||
t.getAHandler().getType().pointsTo(ClassValue::stopIteration())
|
||||
)
|
||||
exists(Try t |
|
||||
t.containsInScope(call.getNode()) and
|
||||
t.getAHandler().getType().pointsTo(ClassValue::stopIteration())
|
||||
)
|
||||
}
|
||||
|
||||
from CallNode call
|
||||
where
|
||||
call_to_next(call, _) and
|
||||
not call_to_next_has_default(call) and
|
||||
not exists(EssaVariable iterator |
|
||||
call_to_next(call, iterator.getAUse()) and
|
||||
iter_not_exhausted(iterator)
|
||||
) and
|
||||
call.getNode().getScope().(Function).isGenerator() and
|
||||
not exists(Comp comp | comp.contains(call.getNode())) and
|
||||
not stop_iteration_handled(call)
|
||||
call_to_next(call, _) and
|
||||
not call_to_next_has_default(call) and
|
||||
not exists(EssaVariable iterator |
|
||||
call_to_next(call, iterator.getAUse()) and
|
||||
iter_not_exhausted(iterator)
|
||||
) and
|
||||
call.getNode().getScope().(Function).isGenerator() and
|
||||
not exists(Comp comp | comp.contains(call.getNode())) and
|
||||
not stop_iteration_handled(call)
|
||||
select call, "Call to next() in a generator"
|
||||
|
||||
Reference in New Issue
Block a user