Skip to content

Commit e42002e

Browse files
Promote IncorrectExceptOrder.
However, we lose some results due to not considering builtin/stdlib types.
1 parent 963e028 commit e42002e

File tree

2 files changed

+19
-14
lines changed

2 files changed

+19
-14
lines changed

python/ql/src/Exceptions/IncorrectExceptOrder.qhelp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,20 @@ is a super class of <code>Error</code>.
2525

2626
<p>Reorganize the <code>except</code> blocks so that the more specific <code>except</code>
2727
is defined first. Alternatively, if the more specific <code>except</code> block is
28-
no longer required then it should be deleted.</p>
28+
no longer required, then it should be deleted.</p>
2929

3030
</recommendation>
3131
<example>
32-
<p>In this example the <code>except Exception:</code> will handle <code>AttributeError</code> preventing the
32+
<p>In the following example, the <code>except Exception:</code> will handle <code>AttributeError</code> preventing the
3333
subsequent handler from ever executing.</p>
3434
<sample src="IncorrectExceptOrder.py" />
3535

3636

3737
</example>
3838
<references>
3939

40-
<li>Python Language Reference: <a href="http://docs.python.org/2.7/reference/compound_stmts.html#try">The try statement</a>,
41-
<a href="http://docs.python.org/2.7/reference/executionmodel.html#exceptions">Exceptions</a>.</li>
40+
<li>Python Language Reference: <a href="http://docs.python.org/3/reference/compound_stmts.html#try">The try statement</a>,
41+
<a href="http://docs.python.org/3/reference/executionmodel.html#exceptions">Exceptions</a>.</li>
4242

4343

4444
</references>

python/ql/src/Exceptions/IncorrectExceptOrder.ql

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,27 @@
1414
*/
1515

1616
import python
17+
import semmle.python.dataflow.new.internal.DataFlowDispatch
1718

18-
predicate incorrect_except_order(ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2) {
19+
predicate incorrectExceptOrder(ExceptStmt ex1, Class cls1, ExceptStmt ex2, Class cls2) {
1920
exists(int i, int j, Try t |
2021
ex1 = t.getHandler(i) and
2122
ex2 = t.getHandler(j) and
2223
i < j and
23-
cls1 = except_class(ex1) and
24-
cls2 = except_class(ex2) and
25-
cls1 = cls2.getASuperType()
24+
cls1 = exceptClass(ex1) and
25+
cls2 = exceptClass(ex2) and
26+
cls1 = getADirectSuperclass*(cls2)
2627
)
2728
}
2829

29-
ClassValue except_class(ExceptStmt ex) { ex.getType().pointsTo(result) }
30+
Class exceptClass(ExceptStmt ex) { ex.getType() = classTracker(result).asExpr() }
3031

31-
from ExceptStmt ex1, ClassValue cls1, ExceptStmt ex2, ClassValue cls2
32-
where incorrect_except_order(ex1, cls1, ex2, cls2)
33-
select ex2,
34-
"Except block for $@ is unreachable; the more general $@ for $@ will always be executed in preference.",
35-
cls2, cls2.getName(), ex1, "except block", cls1, cls1.getName()
32+
from ExceptStmt ex1, Class cls1, ExceptStmt ex2, Class cls2, string msg
33+
where
34+
incorrectExceptOrder(ex1, cls1, ex2, cls2) and
35+
if cls1 = cls2
36+
then msg = "This except block handling $@ is unreachable; as $@ also handles $@."
37+
else
38+
msg =
39+
"This except block handling $@ is unreachable; as $@ for the more general $@ always subsumes it."
40+
select ex2, msg, cls2, cls2.getName(), ex1, "this except block", cls1, cls1.getName()

0 commit comments

Comments
 (0)