From 8ee2587997c8bf8a9c076c7ab32a8a90626eca17 Mon Sep 17 00:00:00 2001 From: Rebecca Valentine Date: Mon, 2 Mar 2020 17:04:32 -0800 Subject: [PATCH 1/4] Python: Moves library predicates to suffixed names --- python/ql/src/Exceptions/Raising.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/Exceptions/Raising.qll b/python/ql/src/Exceptions/Raising.qll index b820bfa24e9c..312998cef257 100644 --- a/python/ql/src/Exceptions/Raising.qll +++ b/python/ql/src/Exceptions/Raising.qll @@ -1,7 +1,7 @@ import python /** Whether the raise statement 'r' raises 'type' from origin 'orig' */ -predicate type_or_typeof(Raise r, ClassObject type, AstNode orig) { +predicate type_or_typeof_objectapi(Raise r, ClassObject type, AstNode orig) { exists(Expr exception | exception = r.getRaised() | exception.refersTo(type, _, orig) From 0dcd52bd874a5ec1824994fab9e2e4ef16b8408b Mon Sep 17 00:00:00 2001 From: Rebecca Valentine Date: Mon, 2 Mar 2020 17:35:13 -0800 Subject: [PATCH 2/4] Python: Moves dependent query over to suffixed predicate names --- python/ql/src/Exceptions/IllegalRaise.ql | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/python/ql/src/Exceptions/IllegalRaise.ql b/python/ql/src/Exceptions/IllegalRaise.ql index 673289b9e975..89f8ab91c35f 100644 --- a/python/ql/src/Exceptions/IllegalRaise.ql +++ b/python/ql/src/Exceptions/IllegalRaise.ql @@ -16,6 +16,6 @@ import Raising import Exceptions.NotImplemented from Raise r, ClassObject t -where type_or_typeof(r, t, _) and not t.isLegalExceptionType() and not t.failedInference() and not use_of_not_implemented_in_raise(r, _) +where type_or_typeof_objectapi(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." From 7161ca57c8ac7e4304b64c84510870e68c95869c Mon Sep 17 00:00:00 2001 From: Rebecca Valentine Date: Mon, 2 Mar 2020 18:45:41 -0800 Subject: [PATCH 3/4] Python: Adds modernizations and moves query over to them --- python/ql/src/Exceptions/IllegalRaise.ql | 4 ++-- python/ql/src/Exceptions/Raising.qll | 15 +++++++++++++++ python/ql/src/semmle/python/objects/ObjectAPI.qll | 9 +++++++++ 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/python/ql/src/Exceptions/IllegalRaise.ql b/python/ql/src/Exceptions/IllegalRaise.ql index 89f8ab91c35f..da1bc56ae336 100644 --- a/python/ql/src/Exceptions/IllegalRaise.ql +++ b/python/ql/src/Exceptions/IllegalRaise.ql @@ -15,7 +15,7 @@ import python import Raising import Exceptions.NotImplemented -from Raise r, ClassObject t -where type_or_typeof_objectapi(r, t, _) and not t.isLegalExceptionType() and not t.failedInference() and not use_of_not_implemented_in_raise(r, _) +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, _) select r, "Illegal class '" + t.getName() + "' raised; will result in a TypeError being raised instead." diff --git a/python/ql/src/Exceptions/Raising.qll b/python/ql/src/Exceptions/Raising.qll index 312998cef257..2aa6ef4af8da 100644 --- a/python/ql/src/Exceptions/Raising.qll +++ b/python/ql/src/Exceptions/Raising.qll @@ -12,3 +12,18 @@ predicate type_or_typeof_objectapi(Raise r, ClassObject type, AstNode orig) { ) } + +/** 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 + ) + ) + +} diff --git a/python/ql/src/semmle/python/objects/ObjectAPI.qll b/python/ql/src/semmle/python/objects/ObjectAPI.qll index 1f1f7001da1c..49087648c523 100644 --- a/python/ql/src/semmle/python/objects/ObjectAPI.qll +++ b/python/ql/src/semmle/python/objects/ObjectAPI.qll @@ -481,6 +481,15 @@ class ClassValue extends Value { predicate declaresAttribute(string name) { this.(ClassObjectInternal).getClassDeclaration().declaresAttribute(name) } + + /** Whether this class is a legal exception class. + * What constitutes a legal exception class differs between major versions */ + predicate isLegalExceptionType() { + not this.isNewStyle() or + this.getASuperType() = ClassValue::baseException() + or + major_version() = 2 and this = ClassValue::tuple() + } } From a8ae843059b566aaf10feab103181012d5c476b1 Mon Sep 17 00:00:00 2001 From: Rebecca Valentine Date: Mon, 2 Mar 2020 18:46:19 -0800 Subject: [PATCH 4/4] Python: Removes now obsolete original predicate --- python/ql/src/Exceptions/Raising.qll | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/python/ql/src/Exceptions/Raising.qll b/python/ql/src/Exceptions/Raising.qll index 2aa6ef4af8da..7e53c0bbd271 100644 --- a/python/ql/src/Exceptions/Raising.qll +++ b/python/ql/src/Exceptions/Raising.qll @@ -1,18 +1,5 @@ import python -/** Whether the raise statement 'r' raises 'type' from origin 'orig' */ -predicate type_or_typeof_objectapi(Raise r, ClassObject type, AstNode orig) { - exists(Expr exception | - exception = r.getRaised() | - exception.refersTo(type, _, orig) - or - not exists(ClassObject exc_type | exception.refersTo(exc_type)) and - not type = theTypeType() and // First value is an unknown exception type - exception.refersTo(_, type, orig) - ) - -} - /** Whether the raise statement 'r' raises 'type' from origin 'orig' */ predicate type_or_typeof(Raise r, ClassValue type, AstNode orig) { exists(Expr exception |