mirror of
https://github.com/github/codeql.git
synced 2025-12-19 02:13:17 +01:00
Merge branch 'main' into re-modeling
This commit is contained in:
@@ -1352,7 +1352,10 @@ abstract class DataFlowCall extends TDataFlowCall {
|
||||
abstract ControlFlowNode getNode();
|
||||
|
||||
/** Gets the enclosing callable of this call. */
|
||||
abstract DataFlowCallable getEnclosingCallable();
|
||||
DataFlowCallable getEnclosingCallable() { result = getCallableScope(this.getScope()) }
|
||||
|
||||
/** Gets the scope of this node, if any. */
|
||||
abstract Scope getScope();
|
||||
|
||||
/** Gets the location of this dataflow call. */
|
||||
abstract Location getLocation();
|
||||
@@ -1400,7 +1403,7 @@ class NormalCall extends ExtractedDataFlowCall, TNormalCall {
|
||||
|
||||
override ControlFlowNode getNode() { result = call }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getScope() }
|
||||
override Scope getScope() { result = call.getScope() }
|
||||
|
||||
override DataFlowCallable getCallable() { result.(DataFlowFunction).getScope() = target }
|
||||
|
||||
@@ -1450,7 +1453,7 @@ class PotentialLibraryCall extends ExtractedDataFlowCall, TPotentialLibraryCall
|
||||
|
||||
override ControlFlowNode getNode() { result = call }
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getScope() }
|
||||
override Scope getScope() { result = call.getScope() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1474,6 +1477,8 @@ class SummaryCall extends DataFlowCall, TSummaryCall {
|
||||
|
||||
override DataFlowCallable getEnclosingCallable() { result.asLibraryCallable() = c }
|
||||
|
||||
override Scope getScope() { none() }
|
||||
|
||||
override DataFlowCallable getCallable() { none() }
|
||||
|
||||
override ArgumentNode getArgument(ArgumentPosition apos) { none() }
|
||||
|
||||
@@ -1044,3 +1044,11 @@ class ContentApprox = Unit;
|
||||
/** Gets an approximated value for content `c`. */
|
||||
pragma[inline]
|
||||
ContentApprox getContentApprox(Content c) { any() }
|
||||
|
||||
/** Helper for `.getEnclosingCallable`. */
|
||||
DataFlowCallable getCallableScope(Scope s) {
|
||||
result.getScope() = s
|
||||
or
|
||||
not exists(DataFlowCallable c | c.getScope() = s) and
|
||||
result = getCallableScope(s.getEnclosingScope())
|
||||
}
|
||||
|
||||
@@ -117,14 +117,6 @@ newtype TNode =
|
||||
exists(ParameterPosition ppos | ppos.isKeyword(_) | exists(callable.getParameter(ppos)))
|
||||
}
|
||||
|
||||
/** Helper for `Node::getEnclosingCallable`. */
|
||||
private DataFlowCallable getCallableScope(Scope s) {
|
||||
result.getScope() = s
|
||||
or
|
||||
not exists(DataFlowCallable c | c.getScope() = s) and
|
||||
result = getCallableScope(s.getEnclosingScope())
|
||||
}
|
||||
|
||||
private import semmle.python.internal.CachedStages
|
||||
|
||||
/**
|
||||
|
||||
@@ -128,6 +128,8 @@ private module CryptodomeModel {
|
||||
this = newCall.getReturn().getMember(methodName).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = newCall }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(cipherName) }
|
||||
|
||||
override DataFlow::Node getAnInput() {
|
||||
@@ -181,21 +183,23 @@ private module CryptodomeModel {
|
||||
class CryptodomeGenericSignatureOperation extends Cryptography::CryptographicOperation::Range,
|
||||
DataFlow::CallCfgNode
|
||||
{
|
||||
API::CallNode newCall;
|
||||
string methodName;
|
||||
string signatureName;
|
||||
|
||||
CryptodomeGenericSignatureOperation() {
|
||||
methodName in ["sign", "verify"] and
|
||||
this =
|
||||
newCall =
|
||||
API::moduleImport(["Crypto", "Cryptodome"])
|
||||
.getMember("Signature")
|
||||
.getMember(signatureName)
|
||||
.getMember("new")
|
||||
.getReturn()
|
||||
.getMember(methodName)
|
||||
.getACall()
|
||||
.getACall() and
|
||||
this = newCall.getReturn().getMember(methodName).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = newCall }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() {
|
||||
result.matchesName(signatureName)
|
||||
}
|
||||
@@ -221,19 +225,23 @@ private module CryptodomeModel {
|
||||
class CryptodomeGenericHashOperation extends Cryptography::CryptographicOperation::Range,
|
||||
DataFlow::CallCfgNode
|
||||
{
|
||||
API::CallNode newCall;
|
||||
string hashName;
|
||||
|
||||
CryptodomeGenericHashOperation() {
|
||||
exists(API::Node hashModule |
|
||||
hashModule =
|
||||
API::moduleImport(["Crypto", "Cryptodome"]).getMember("Hash").getMember(hashName)
|
||||
API::moduleImport(["Crypto", "Cryptodome"]).getMember("Hash").getMember(hashName) and
|
||||
newCall = hashModule.getMember("new").getACall()
|
||||
|
|
||||
this = hashModule.getMember("new").getACall()
|
||||
this = newCall
|
||||
or
|
||||
this = hashModule.getMember("new").getReturn().getMember("update").getACall()
|
||||
this = newCall.getReturn().getMember("update").getACall()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = newCall }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||
|
||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("data")] }
|
||||
|
||||
@@ -209,18 +209,18 @@ private module CryptographyModel {
|
||||
class CryptographyGenericCipherOperation extends Cryptography::CryptographicOperation::Range,
|
||||
DataFlow::MethodCallNode
|
||||
{
|
||||
API::CallNode init;
|
||||
string algorithmName;
|
||||
string modeName;
|
||||
|
||||
CryptographyGenericCipherOperation() {
|
||||
this =
|
||||
cipherInstance(algorithmName, modeName)
|
||||
.getMember(["decryptor", "encryptor"])
|
||||
.getReturn()
|
||||
.getMember(["update", "update_into"])
|
||||
.getACall()
|
||||
init =
|
||||
cipherInstance(algorithmName, modeName).getMember(["decryptor", "encryptor"]).getACall() and
|
||||
this = init.getReturn().getMember(["update", "update_into"]).getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = init }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() {
|
||||
result.matchesName(algorithmName)
|
||||
}
|
||||
@@ -247,19 +247,17 @@ private module CryptographyModel {
|
||||
}
|
||||
|
||||
/** Gets a reference to a Hash instance using algorithm with `algorithmName`. */
|
||||
private API::Node hashInstance(string algorithmName) {
|
||||
exists(API::CallNode call | result = call.getReturn() |
|
||||
call =
|
||||
API::moduleImport("cryptography")
|
||||
.getMember("hazmat")
|
||||
.getMember("primitives")
|
||||
.getMember("hashes")
|
||||
.getMember("Hash")
|
||||
.getACall() and
|
||||
algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [
|
||||
call.getArg(0), call.getArgByName("algorithm")
|
||||
]
|
||||
)
|
||||
private API::CallNode hashInstance(string algorithmName) {
|
||||
result =
|
||||
API::moduleImport("cryptography")
|
||||
.getMember("hazmat")
|
||||
.getMember("primitives")
|
||||
.getMember("hashes")
|
||||
.getMember("Hash")
|
||||
.getACall() and
|
||||
algorithmClassRef(algorithmName).getReturn().getAValueReachableFromSource() in [
|
||||
result.getArg(0), result.getArgByName("algorithm")
|
||||
]
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -268,12 +266,16 @@ private module CryptographyModel {
|
||||
class CryptographyGenericHashOperation extends Cryptography::CryptographicOperation::Range,
|
||||
DataFlow::MethodCallNode
|
||||
{
|
||||
API::CallNode init;
|
||||
string algorithmName;
|
||||
|
||||
CryptographyGenericHashOperation() {
|
||||
this = hashInstance(algorithmName).getMember("update").getACall()
|
||||
init = hashInstance(algorithmName) and
|
||||
this = init.getReturn().getMember("update").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = init }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() {
|
||||
result.matchesName(algorithmName)
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ private module Rsa {
|
||||
class RsaEncryptCall extends Cryptography::CryptographicOperation::Range, DataFlow::CallCfgNode {
|
||||
RsaEncryptCall() { this = API::moduleImport("rsa").getMember("encrypt").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
|
||||
|
||||
override DataFlow::Node getAnInput() {
|
||||
@@ -54,6 +56,8 @@ private module Rsa {
|
||||
class RsaDecryptCall extends Cryptography::CryptographicOperation::Range, DataFlow::CallCfgNode {
|
||||
RsaDecryptCall() { this = API::moduleImport("rsa").getMember("decrypt").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
|
||||
|
||||
override DataFlow::Node getAnInput() { result in [this.getArg(0), this.getArgByName("crypto")] }
|
||||
@@ -69,6 +73,8 @@ private module Rsa {
|
||||
class RsaSignCall extends Cryptography::CryptographicOperation::Range, DataFlow::CallCfgNode {
|
||||
RsaSignCall() { this = API::moduleImport("rsa").getMember("sign").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() {
|
||||
// signature part
|
||||
result.getName() = "RSA"
|
||||
@@ -96,6 +102,8 @@ private module Rsa {
|
||||
class RsaVerifyCall extends Cryptography::CryptographicOperation::Range, DataFlow::CallCfgNode {
|
||||
RsaVerifyCall() { this = API::moduleImport("rsa").getMember("verify").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() {
|
||||
// note that technically there is also a hashing operation going on but we don't
|
||||
// know what algorithm is used up front, since it is encoded in the signature
|
||||
@@ -121,6 +129,8 @@ private module Rsa {
|
||||
{
|
||||
RsaComputeHashCall() { this = API::moduleImport("rsa").getMember("compute_hash").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() {
|
||||
exists(StrConst str, DataFlow::Node hashNameArg |
|
||||
hashNameArg in [this.getArg(1), this.getArgByName("method_name")] and
|
||||
@@ -144,6 +154,8 @@ private module Rsa {
|
||||
class RsaSignHashCall extends Cryptography::CryptographicOperation::Range, DataFlow::CallCfgNode {
|
||||
RsaSignHashCall() { this = API::moduleImport("rsa").getMember("sign_hash").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.getName() = "RSA" }
|
||||
|
||||
override DataFlow::Node getAnInput() {
|
||||
|
||||
@@ -2747,6 +2747,8 @@ private module StdlibPrivate {
|
||||
exists(this.getParameter(1, "data"))
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getParameter(1, "data").asSink() }
|
||||
@@ -2758,12 +2760,16 @@ private module StdlibPrivate {
|
||||
* A hashing operation by using the `update` method on the result of calling the `hashlib.new` function.
|
||||
*/
|
||||
class HashlibNewUpdateCall extends Cryptography::CryptographicOperation::Range, API::CallNode {
|
||||
API::CallNode init;
|
||||
string hashName;
|
||||
|
||||
HashlibNewUpdateCall() {
|
||||
this = hashlibNewCall(hashName).getReturn().getMember("update").getACall()
|
||||
init = hashlibNewCall(hashName) and
|
||||
this = init.getReturn().getMember("update").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = init }
|
||||
|
||||
override Cryptography::CryptographicAlgorithm getAlgorithm() { result.matchesName(hashName) }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
||||
@@ -2802,7 +2808,14 @@ private module StdlibPrivate {
|
||||
* (such as `hashlib.md5`), by calling its' `update` method.
|
||||
*/
|
||||
class HashlibHashClassUpdateCall extends HashlibGenericHashOperation {
|
||||
HashlibHashClassUpdateCall() { this = hashClass.getReturn().getMember("update").getACall() }
|
||||
API::CallNode init;
|
||||
|
||||
HashlibHashClassUpdateCall() {
|
||||
init = hashClass.getACall() and
|
||||
this = hashClass.getReturn().getMember("update").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = init }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getArg(0) }
|
||||
}
|
||||
@@ -2819,6 +2832,8 @@ private module StdlibPrivate {
|
||||
exists([this.getArg(0), this.getArgByName("string")])
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override DataFlow::Node getAnInput() {
|
||||
result = this.getArg(0)
|
||||
or
|
||||
@@ -2865,6 +2880,8 @@ private module StdlibPrivate {
|
||||
exists(this.getParameter(1, "msg").asSink())
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override API::Node getDigestArg() { result = digestArg }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getParameter(1, "msg").asSink() }
|
||||
@@ -2876,12 +2893,16 @@ private module StdlibPrivate {
|
||||
* See https://docs.python.org/3.11/library/hmac.html#hmac.HMAC.update
|
||||
*/
|
||||
class HmacUpdateCall extends HmacCryptographicOperation {
|
||||
API::CallNode init;
|
||||
API::Node digestArg;
|
||||
|
||||
HmacUpdateCall() {
|
||||
this = getHmacConstructorCall(digestArg).getReturn().getMember("update").getACall()
|
||||
init = getHmacConstructorCall(digestArg) and
|
||||
this = init.getReturn().getMember("update").getACall()
|
||||
}
|
||||
|
||||
override DataFlow::Node getInitialization() { result = init }
|
||||
|
||||
override API::Node getDigestArg() { result = digestArg }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getParameter(0, "msg").asSink() }
|
||||
@@ -2895,6 +2916,8 @@ private module StdlibPrivate {
|
||||
class HmacDigestCall extends HmacCryptographicOperation {
|
||||
HmacDigestCall() { this = API::moduleImport("hmac").getMember("digest").getACall() }
|
||||
|
||||
override DataFlow::Node getInitialization() { result = this }
|
||||
|
||||
override API::Node getDigestArg() { result = this.getParameter(2, "digest") }
|
||||
|
||||
override DataFlow::Node getAnInput() { result = this.getParameter(1, "msg").asSink() }
|
||||
|
||||
@@ -40,6 +40,9 @@ module Cryptography {
|
||||
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
|
||||
CryptographicAlgorithm getAlgorithm() { result = super.getAlgorithm() }
|
||||
|
||||
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
DataFlow::Node getInitialization() { result = super.getInitialization() }
|
||||
|
||||
/** Gets an input the algorithm is used on, for example the plain text input to be encrypted. */
|
||||
DataFlow::Node getAnInput() { result = super.getAnInput() }
|
||||
|
||||
@@ -65,6 +68,9 @@ module Cryptography {
|
||||
* extend `CryptographicOperation` instead.
|
||||
*/
|
||||
abstract class Range extends DataFlow::Node {
|
||||
/** Gets the data-flow node where the cryptographic algorithm used in this operation is configured. */
|
||||
abstract DataFlow::Node getInitialization();
|
||||
|
||||
/** Gets the algorithm used, if it matches a known `CryptographicAlgorithm`. */
|
||||
abstract CryptographicAlgorithm getAlgorithm();
|
||||
|
||||
|
||||
@@ -13,18 +13,15 @@
|
||||
import python
|
||||
import semmle.python.Concepts
|
||||
|
||||
from
|
||||
Cryptography::CryptographicOperation operation, Cryptography::CryptographicAlgorithm algorithm,
|
||||
string msgPrefix
|
||||
from Cryptography::CryptographicOperation operation, string msgPrefix
|
||||
where
|
||||
algorithm = operation.getAlgorithm() and
|
||||
// `Cryptography::HashingAlgorithm` and `Cryptography::PasswordHashingAlgorithm` are
|
||||
// handled by `py/weak-sensitive-data-hashing`
|
||||
algorithm instanceof Cryptography::EncryptionAlgorithm and
|
||||
(
|
||||
exists(Cryptography::EncryptionAlgorithm algorithm | algorithm = operation.getAlgorithm() |
|
||||
algorithm.isWeak() and
|
||||
msgPrefix = "The cryptographic algorithm " + operation.getAlgorithm().getName()
|
||||
msgPrefix = "The cryptographic algorithm " + algorithm.getName()
|
||||
)
|
||||
or
|
||||
operation.getBlockMode().isWeak() and msgPrefix = "The block mode " + operation.getBlockMode()
|
||||
select operation, msgPrefix + " is broken or weak, and should not be used."
|
||||
select operation, "$@ is broken or weak, and should not be used.", operation.getInitialization(),
|
||||
msgPrefix
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
| new_cls_param.py:14:6:14:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| test.py:21:6:21:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| test.py:25:6:25:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| test.py:29:6:29:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
# Originally we had module and functions as `DataFlowCallable``, and any call inside a
|
||||
# class scope would not have a result for getEnclosingCallable. Since this was only a
|
||||
# consistency error for calls, originally we added a new `DataFlowClassScope` only for
|
||||
# those classes that had a call in their scope. That's why all the class definitions in
|
||||
# this test do a call to the dummy function `func`.
|
||||
#
|
||||
# Note: this was shortsighted, since most DataFlow::Node use `getCallableScope` helper
|
||||
# to define their .getEnclosingCallable(), which picks the first DataFlowCallable to
|
||||
# contain the node. (so for some classes that would be DataFlowClassScope, and for some
|
||||
# it would be the module/function containing the class definition)
|
||||
|
||||
def func(*args, **kwargs):
|
||||
print("func()")
|
||||
|
||||
class Cls:
|
||||
func()
|
||||
class Inner:
|
||||
func()
|
||||
|
||||
def other_func():
|
||||
class Cls2:
|
||||
func()
|
||||
return Cls2
|
||||
|
||||
x = other_func()
|
||||
@@ -1,7 +1,5 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
| datamodel.py:71:6:71:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| datamodel.py:76:6:76:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -1,11 +1,5 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
| test_collections.py:39:17:39:38 | Lambda() | Call should have one enclosing callable but has 0. |
|
||||
| test_collections.py:39:17:39:38 | Lambda() | Call should have one enclosing callable but has 0. |
|
||||
| test_collections.py:45:19:45:24 | mod() | Call should have one enclosing callable but has 0. |
|
||||
| test_collections.py:45:19:45:24 | mod() | Call should have one enclosing callable but has 0. |
|
||||
| test_collections.py:52:13:52:24 | mod_local() | Call should have one enclosing callable but has 0. |
|
||||
| test_collections.py:52:13:52:24 | mod_local() | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -1,36 +1,5 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
| code/bound_method_arg.py:5:6:5:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/callable_as_argument.py:37:6:37:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/callable_as_argument.py:49:10:49:21 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_construction.py:13:6:13:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:9:6:9:13 | property() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:11:9:11:32 | print() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:14:6:14:15 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:19:6:19:16 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:36:12:36:62 | property() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:38:6:38:13 | property() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_properties.py:40:9:40:38 | print() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:10:6:10:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:14:6:14:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:104:6:104:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:108:6:108:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:112:6:112:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:116:6:116:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:120:6:120:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:149:6:149:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_subclass.py:153:6:153:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_super.py:13:6:13:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_super.py:28:6:28:17 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_super.py:36:6:36:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/class_super.py:40:6:40:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/func_defined_outside_class.py:17:18:17:41 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/func_defined_outside_class.py:18:18:18:40 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/func_defined_outside_class.py:38:11:38:21 | _gen() | Call should have one enclosing callable but has 0. |
|
||||
| code/func_defined_outside_class.py:39:11:39:21 | _gen() | Call should have one enclosing callable but has 0. |
|
||||
| code/nested_class.py:3:10:3:21 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/nested_class.py:7:10:7:21 | staticmethod() | Call should have one enclosing callable but has 0. |
|
||||
| code/self_passing.py:60:6:60:16 | classmethod() | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -1,9 +1,5 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
| test_captured.py:7:22:7:25 | p() | Call should have one enclosing callable but has 0. |
|
||||
| test_captured.py:7:22:7:25 | p() | Call should have one enclosing callable but has 0. |
|
||||
| test_captured.py:14:26:14:30 | pp() | Call should have one enclosing callable but has 0. |
|
||||
| test_captured.py:14:26:14:30 | pp() | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -1,40 +1,5 @@
|
||||
uniqueEnclosingCallable
|
||||
uniqueCallEnclosingCallable
|
||||
| testapp/orm_form_test.py:7:12:7:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:30:13:30:44 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:34:25:34:56 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:35:33:35:64 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:39:21:39:52 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:40:33:40:64 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:118:13:118:44 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:122:25:122:56 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:123:33:123:64 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:127:21:127:52 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_inheritance.py:128:33:128:64 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_security_tests.py:16:12:16:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_security_tests.py:17:11:17:31 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_security_tests.py:93:12:93:65 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_security_tests.py:112:12:112:65 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:29:12:29:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:43:12:43:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:59:12:59:61 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:74:12:74:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:90:12:90:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:111:12:111:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:127:12:127:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:128:13:128:44 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:145:12:145:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:146:13:146:44 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:162:12:162:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:178:12:178:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:181:12:181:64 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:207:12:207:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:208:12:208:70 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:234:12:234:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:235:12:235:95 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:256:12:256:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:274:12:274:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
| testapp/orm_tests.py:295:12:295:43 | Attribute() | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
| test_cryptodome.py:11:13:11:42 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 is broken or weak, and should not be used. |
|
||||
| test_cryptodome.py:16:13:16:42 | ControlFlowNode for Attribute() | The block mode ECB is broken or weak, and should not be used. |
|
||||
| test_cryptography.py:13:13:13:44 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 is broken or weak, and should not be used. |
|
||||
| test_cryptography.py:22:13:22:58 | ControlFlowNode for Attribute() | The block mode ECB is broken or weak, and should not be used. |
|
||||
| test_cryptodome.py:11:13:11:42 | ControlFlowNode for Attribute() | $@ is broken or weak, and should not be used. | test_cryptodome.py:10:10:10:22 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 |
|
||||
| test_cryptodome.py:16:13:16:42 | ControlFlowNode for Attribute() | $@ is broken or weak, and should not be used. | test_cryptodome.py:15:10:15:35 | ControlFlowNode for Attribute() | The block mode ECB |
|
||||
| test_cryptography.py:13:13:13:44 | ControlFlowNode for Attribute() | $@ is broken or weak, and should not be used. | test_cryptography.py:12:13:12:30 | ControlFlowNode for Attribute() | The cryptographic algorithm ARC4 |
|
||||
| test_cryptography.py:22:13:22:58 | ControlFlowNode for Attribute() | $@ is broken or weak, and should not be used. | test_cryptography.py:21:13:21:30 | ControlFlowNode for Attribute() | The block mode ECB |
|
||||
|
||||
Reference in New Issue
Block a user