Skip to content

Commit 3bedd5c

Browse files
committed
Python: Adds modernized predicates and moves query over to them
1 parent 5fea31e commit 3bedd5c

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

python/ql/src/Exceptions/EmptyExcept.ql

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,27 @@ predicate encode_decode_objectapi(Expr ex, ClassObject type) {
7373
)
7474
}
7575

76+
predicate encode_decode(Expr ex, ClassValue type) {
77+
exists(string name |
78+
ex.(Call).getFunc().(Attribute).getName() = name |
79+
name = "encode" and type = ClassValue::unicodeEncodeError()
80+
or
81+
name = "decode" and type = ClassValue::unicodeDecodeError()
82+
)
83+
}
84+
7685
predicate small_handler_objectapi(ExceptStmt ex, Stmt s, ClassObject type) {
7786
not exists(ex.getTry().getStmt(1)) and
7887
s = ex.getTry().getStmt(0) and
7988
ex.getType().refersTo(type)
8089
}
8190

91+
predicate small_handler(ExceptStmt ex, Stmt s, ClassValue type) {
92+
not exists(ex.getTry().getStmt(1)) and
93+
s = ex.getTry().getStmt(0) and
94+
ex.getType().pointsTo(type)
95+
}
96+
8297
/** Holds if this exception handler is sufficiently small in scope to not need a comment
8398
* as to what it is doing.
8499
*/
@@ -95,12 +110,25 @@ predicate focussed_handler_objectapi(ExceptStmt ex) {
95110
)
96111
}
97112

113+
predicate focussed_handler(ExceptStmt ex) {
114+
exists(Stmt s, ClassValue type |
115+
small_handler(ex, s, type) |
116+
subscript(s) and type.getASuperType() = ClassValue::lookupError()
117+
or
118+
attribute_access(s) and type = ClassValue::attributeError()
119+
or
120+
s.(ExprStmt).getValue() instanceof Name and type = ClassValue::nameError()
121+
or
122+
encode_decode(s.(ExprStmt).getValue(), type)
123+
)
124+
}
125+
98126
Try try_return() {
99127
not exists(result.getStmt(1)) and result.getStmt(0) instanceof Return
100128
}
101129

102130
from ExceptStmt ex
103131
where empty_except(ex) and no_else(ex) and no_comment(ex) and not non_local_control_flow(ex)
104132
and not ex.getTry() = try_return() and try_has_normal_exit(ex.getTry()) and
105-
not focussed_handler_objectapi(ex)
133+
not focussed_handler(ex)
106134
select ex, "'except' clause does nothing but pass and there is no explanatory comment."

python/ql/src/semmle/python/objects/ObjectAPI.qll

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,11 @@ module ClassValue {
882882
result = TBuiltinClassObject(Builtin::builtin("KeyError"))
883883
}
884884

885+
/** Get the `ClassValue` for the `LookupError` class. */
886+
ClassValue lookupError() {
887+
result = TBuiltinClassObject(Builtin::builtin("LookupError"))
888+
}
889+
885890
/** Get the `ClassValue` for the `IOError` class. */
886891
ClassValue ioError() {
887892
result = TBuiltinClassObject(Builtin::builtin("IOError"))
@@ -896,5 +901,15 @@ module ClassValue {
896901
ClassValue importError() {
897902
result = TBuiltinClassObject(Builtin::builtin("ImportError"))
898903
}
904+
905+
/** Get the `ClassValue` for the `UnicodeEncodeError` class. */
906+
ClassValue unicodeEncodeError() {
907+
result = TBuiltinClassObject(Builtin::builtin("UnicodeEncodeError"))
908+
}
909+
910+
/** Get the `ClassValue` for the `UnicodeDecodeError` class. */
911+
ClassValue unicodeDecodeError() {
912+
result = TBuiltinClassObject(Builtin::builtin("UnicodeDecodeError"))
913+
}
899914

900915
}

0 commit comments

Comments
 (0)