mirror of
https://github.com/github/codeql.git
synced 2025-12-24 04:36:35 +01:00
Merge pull request #8336 from tausbn/python-fix-a-bunch-of-ql-warnings
Python: Fix a bunch of QL warnings
This commit is contained in:
@@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like `hasActualResult`, but returns results that do not require a matching annotation.
|
* Holds if there is an optional result on the specified location.
|
||||||
|
*
|
||||||
|
* This is similar to `hasActualResult`, but returns results that do not require a matching annotation.
|
||||||
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
||||||
* Override this predicate to specify optional results.
|
* Override this predicate to specify optional results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like `hasActualResult`, but returns results that do not require a matching annotation.
|
* Holds if there is an optional result on the specified location.
|
||||||
|
*
|
||||||
|
* This is similar to `hasActualResult`, but returns results that do not require a matching annotation.
|
||||||
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
||||||
* Override this predicate to specify optional results.
|
* Override this predicate to specify optional results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like `hasActualResult`, but returns results that do not require a matching annotation.
|
* Holds if there is an optional result on the specified location.
|
||||||
|
*
|
||||||
|
* This is similar to `hasActualResult`, but returns results that do not require a matching annotation.
|
||||||
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
||||||
* Override this predicate to specify optional results.
|
* Override this predicate to specify optional results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
|
|
||||||
/** Syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
|
/** A syntactic node (Class, Function, Module, Expr, Stmt or Comprehension) corresponding to a flow node */
|
||||||
abstract class AstNode extends AstNode_ {
|
abstract class AstNode extends AstNode_ {
|
||||||
/*
|
/*
|
||||||
* Special comment for documentation generation.
|
* Special comment for documentation generation.
|
||||||
@@ -61,31 +61,31 @@ abstract class AstNode extends AstNode_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Parents */
|
/* Parents */
|
||||||
/** Internal implementation class */
|
/** The parent of a `Function`. Internal implementation class */
|
||||||
class FunctionParent extends FunctionParent_ { }
|
class FunctionParent extends FunctionParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of an `Arguments` node. Internal implementation class */
|
||||||
class ArgumentsParent extends ArgumentsParent_ { }
|
class ArgumentsParent extends ArgumentsParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of an `ExprList`. Internal implementation class */
|
||||||
class ExprListParent extends ExprListParent_ { }
|
class ExprListParent extends ExprListParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of an `ExprContext`. Internal implementation class */
|
||||||
class ExprContextParent extends ExprContextParent_ { }
|
class ExprContextParent extends ExprContextParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of a `StmtList`. Internal implementation class */
|
||||||
class StmtListParent extends StmtListParent_ { }
|
class StmtListParent extends StmtListParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of a `StrList`. Internal implementation class */
|
||||||
class StrListParent extends StrListParent_ { }
|
class StrListParent extends StrListParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of an `Expr`. Internal implementation class */
|
||||||
class ExprParent extends ExprParent_ { }
|
class ExprParent extends ExprParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of a `PatternList`. Internal implementation class */
|
||||||
class PatternListParent extends PatternListParent_ { }
|
class PatternListParent extends PatternListParent_ { }
|
||||||
|
|
||||||
/** Internal implementation class */
|
/** The parent of a `Pattern`. Internal implementation class */
|
||||||
class PatternParent extends PatternParent_ { }
|
class PatternParent extends PatternParent_ { }
|
||||||
|
|
||||||
class DictItem extends DictItem_, AstNode {
|
class DictItem extends DictItem_, AstNode {
|
||||||
@@ -120,7 +120,7 @@ class Comprehension extends Comprehension_, AstNode {
|
|||||||
class BytesOrStr extends BytesOrStr_ { }
|
class BytesOrStr extends BytesOrStr_ { }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Part of a string literal formed by implicit concatenation.
|
* A part of a string literal formed by implicit concatenation.
|
||||||
* For example the string literal "abc" expressed in the source as `"a" "b" "c"`
|
* For example the string literal "abc" expressed in the source as `"a" "b" "c"`
|
||||||
* would be composed of three `StringPart`s.
|
* would be composed of three `StringPart`s.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ class CommentBlock extends @py_comment {
|
|||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
string toString() { result = "Comment block" }
|
string toString() { result = "Comment block" }
|
||||||
|
|
||||||
/** The length of this comment block (in comments) */
|
/** Gets the length of this comment block (in comments) */
|
||||||
int length() { result = max(int i | comment_block_part(this, _, i)) }
|
int length() { result = max(int i | comment_block_part(this, _, i)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -76,22 +76,22 @@ class CompareOp extends int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The `CompareOp` for "equals". */
|
/** Gets the `CompareOp` for "equals". */
|
||||||
CompareOp eq() { result = 1 }
|
CompareOp eq() { result = 1 }
|
||||||
|
|
||||||
/** The `CompareOp` for "not equals". */
|
/** Gets the `CompareOp` for "not equals". */
|
||||||
CompareOp ne() { result = 2 }
|
CompareOp ne() { result = 2 }
|
||||||
|
|
||||||
/** The `CompareOp` for "less than". */
|
/** Gets the `CompareOp` for "less than". */
|
||||||
CompareOp lt() { result = 3 }
|
CompareOp lt() { result = 3 }
|
||||||
|
|
||||||
/** The `CompareOp` for "less than or equal to". */
|
/** Gets the `CompareOp` for "less than or equal to". */
|
||||||
CompareOp le() { result = 4 }
|
CompareOp le() { result = 4 }
|
||||||
|
|
||||||
/** The `CompareOp` for "greater than". */
|
/** Gets the `CompareOp` for "greater than". */
|
||||||
CompareOp gt() { result = 5 }
|
CompareOp gt() { result = 5 }
|
||||||
|
|
||||||
/** The `CompareOp` for "greater than or equal to". */
|
/** Gets the `CompareOp` for "greater than or equal to". */
|
||||||
CompareOp ge() { result = 6 }
|
CompareOp ge() { result = 6 }
|
||||||
|
|
||||||
/* Workaround precision limits in floating point numbers */
|
/* Workaround precision limits in floating point numbers */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
|
|
||||||
/** Base class for list, set and dictionary comprehensions, and generator expressions. */
|
/** The base class for list, set and dictionary comprehensions, and generator expressions. */
|
||||||
abstract class Comp extends Expr {
|
abstract class Comp extends Expr {
|
||||||
abstract Function getFunction();
|
abstract Function getFunction();
|
||||||
|
|
||||||
|
|||||||
@@ -315,7 +315,7 @@ class Ellipsis extends Ellipsis_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Immutable literal expressions (except tuples).
|
* An immutable literal expression (except tuples).
|
||||||
* Consists of string (both unicode and byte) literals and numeric literals.
|
* Consists of string (both unicode and byte) literals and numeric literals.
|
||||||
*/
|
*/
|
||||||
abstract class ImmutableLiteral extends Expr {
|
abstract class ImmutableLiteral extends Expr {
|
||||||
@@ -446,6 +446,8 @@ class Unicode extends StrConst {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the quoted representation fo this string.
|
||||||
|
*
|
||||||
* The extractor puts quotes into the name of each string (to prevent "0" clashing with 0).
|
* The extractor puts quotes into the name of each string (to prevent "0" clashing with 0).
|
||||||
* The following predicate help us match up a string/byte literals in the source
|
* The following predicate help us match up a string/byte literals in the source
|
||||||
* which the equivalent object.
|
* which the equivalent object.
|
||||||
@@ -685,7 +687,7 @@ class False extends BooleanLiteral {
|
|||||||
override boolean booleanValue() { result = false }
|
override boolean booleanValue() { result = false }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** `None` */
|
/** The `None` constant. */
|
||||||
class None extends NameConstant {
|
class None extends NameConstant {
|
||||||
/* syntax: None */
|
/* syntax: None */
|
||||||
None() { name_consts(this, "None") }
|
None() { name_consts(this, "None") }
|
||||||
@@ -728,20 +730,20 @@ class Guard extends Guard_ {
|
|||||||
/** A context in which an expression used */
|
/** A context in which an expression used */
|
||||||
class ExprContext extends ExprContext_ { }
|
class ExprContext extends ExprContext_ { }
|
||||||
|
|
||||||
/** Load context, the context of var in len(var) */
|
/** The load context, the context of var in len(var) */
|
||||||
class Load extends Load_ { }
|
class Load extends Load_ { }
|
||||||
|
|
||||||
/** Store context, the context of var in var = 0 */
|
/** The store context, the context of var in var = 0 */
|
||||||
class Store extends Store_ { }
|
class Store extends Store_ { }
|
||||||
|
|
||||||
/** Delete context, the context of var in del var */
|
/** The delete context, the context of var in del var */
|
||||||
class Del extends Del_ { }
|
class Del extends Del_ { }
|
||||||
|
|
||||||
/** This is an artifact of the Python grammar which includes an AugLoad context, even though it is never used. */
|
/** The context of an augmented load. This is an artifact of the Python grammar which includes an AugLoad context, even though it is never used. */
|
||||||
library class AugLoad extends AugLoad_ { }
|
class AugLoad extends AugLoad_ { }
|
||||||
|
|
||||||
/** Augmented store context, the context of var in var += 1 */
|
/** The augmented store context, the context of var in var += 1 */
|
||||||
class AugStore extends AugStore_ { }
|
class AugStore extends AugStore_ { }
|
||||||
|
|
||||||
/** Parameter context, the context of var in def f(var): pass */
|
/** The parameter context, the context of var in def f(var): pass */
|
||||||
class Param extends Param_ { }
|
class Param extends Param_ { }
|
||||||
|
|||||||
@@ -155,7 +155,7 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
/** Whether this flow node is the first in its scope */
|
/** Whether this flow node is the first in its scope */
|
||||||
predicate isEntryNode() { py_scope_flow(this, _, -1) }
|
predicate isEntryNode() { py_scope_flow(this, _, -1) }
|
||||||
|
|
||||||
/** The value that this ControlFlowNode points-to. */
|
/** Gets the value that this ControlFlowNode points-to. */
|
||||||
predicate pointsTo(Value value) { this.pointsTo(_, value, _) }
|
predicate pointsTo(Value value) { this.pointsTo(_, value, _) }
|
||||||
|
|
||||||
/** Gets the value that this ControlFlowNode points-to. */
|
/** Gets the value that this ControlFlowNode points-to. */
|
||||||
@@ -164,10 +164,10 @@ class ControlFlowNode extends @py_flow_node {
|
|||||||
/** Gets a value that this ControlFlowNode may points-to. */
|
/** Gets a value that this ControlFlowNode may points-to. */
|
||||||
Value inferredValue() { this.pointsTo(_, result, _) }
|
Value inferredValue() { this.pointsTo(_, result, _) }
|
||||||
|
|
||||||
/** The value and origin that this ControlFlowNode points-to. */
|
/** Gets the value and origin that this ControlFlowNode points-to. */
|
||||||
predicate pointsTo(Value value, ControlFlowNode origin) { this.pointsTo(_, value, origin) }
|
predicate pointsTo(Value value, ControlFlowNode origin) { this.pointsTo(_, value, origin) }
|
||||||
|
|
||||||
/** The value and origin that this ControlFlowNode points-to, given the context. */
|
/** Gets the value and origin that this ControlFlowNode points-to, given the context. */
|
||||||
predicate pointsTo(Context context, Value value, ControlFlowNode origin) {
|
predicate pointsTo(Context context, Value value, ControlFlowNode origin) {
|
||||||
PointsTo::pointsTo(this, context, value, origin)
|
PointsTo::pointsTo(this, context, value, origin)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,11 +5,11 @@ import python
|
|||||||
* It is the syntactic entity that is compiled to a code object.
|
* It is the syntactic entity that is compiled to a code object.
|
||||||
*/
|
*/
|
||||||
class Function extends Function_, Scope, AstNode {
|
class Function extends Function_, Scope, AstNode {
|
||||||
/** The expression defining this function */
|
/** Gets the expression defining this function */
|
||||||
CallableExpr getDefinition() { result = this.getParent() }
|
CallableExpr getDefinition() { result = this.getParent() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The scope in which this function occurs, will be a class for a method,
|
* Gets the scope in which this function occurs. This will be a class for a method,
|
||||||
* another function for nested functions, generator expressions or comprehensions,
|
* another function for nested functions, generator expressions or comprehensions,
|
||||||
* or a module for a plain function.
|
* or a module for a plain function.
|
||||||
*/
|
*/
|
||||||
@@ -183,8 +183,8 @@ class FunctionDef extends Assign {
|
|||||||
override Stmt getLastStatement() { result = this.getDefinedFunction().getLastStatement() }
|
override Stmt getLastStatement() { result = this.getDefinedFunction().getLastStatement() }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A function that uses 'fast' locals, stored in the frame not in a dictionary. */
|
||||||
class FastLocalsFunction extends Function {
|
class FastLocalsFunction extends Function {
|
||||||
/** A function that uses 'fast' locals, stored in the frame not in a dictionary. */
|
|
||||||
FastLocalsFunction() {
|
FastLocalsFunction() {
|
||||||
not exists(ImportStar i | i.getScope() = this) and
|
not exists(ImportStar i | i.getScope() = this) and
|
||||||
not exists(Exec e | e.getScope() = this)
|
not exists(Exec e | e.getScope() = this)
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ class ImportExpr extends ImportExpr_ {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the level of this import.
|
||||||
|
*
|
||||||
* The language specifies level as -1 if relative imports are to be tried first, 0 for absolute imports,
|
* The language specifies level as -1 if relative imports are to be tried first, 0 for absolute imports,
|
||||||
* and level > 0 for explicit relative imports.
|
* and level > 0 for explicit relative imports.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class FunctionMetrics extends Function {
|
|||||||
int getNumberOfLinesOfDocStrings() { py_docstringlines(this, result) }
|
int getNumberOfLinesOfDocStrings() { py_docstringlines(this, result) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cyclomatic complexity:
|
* Gets the cyclomatic complexity of the function:
|
||||||
* The number of linearly independent paths through the source code.
|
* The number of linearly independent paths through the source code.
|
||||||
* Computed as E - N + 2P,
|
* Computed as E - N + 2P,
|
||||||
* where
|
* where
|
||||||
@@ -130,13 +130,13 @@ class ClassMetrics extends Class {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The afferent coupling of a class is the number of classes that
|
* Gets the afferent coupling of a class -- the number of classes that
|
||||||
* directly depend on it.
|
* directly depend on it.
|
||||||
*/
|
*/
|
||||||
int getAfferentCoupling() { result = count(ClassMetrics t | t.dependsOn(this)) }
|
int getAfferentCoupling() { result = count(ClassMetrics t | t.dependsOn(this)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The efferent coupling of a class is the number of classes that
|
* Gets the efferent coupling of a class -- the number of classes that
|
||||||
* it directly depends on.
|
* it directly depends on.
|
||||||
*/
|
*/
|
||||||
int getEfferentCoupling() { result = count(ClassMetrics t | this.dependsOn(t)) }
|
int getEfferentCoupling() { result = count(ClassMetrics t | this.dependsOn(t)) }
|
||||||
@@ -273,13 +273,13 @@ class ModuleMetrics extends Module {
|
|||||||
int getNumberOfLinesOfDocStrings() { py_docstringlines(this, result) }
|
int getNumberOfLinesOfDocStrings() { py_docstringlines(this, result) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The afferent coupling of a class is the number of classes that
|
* Gets the afferent coupling of a class -- the number of classes that
|
||||||
* directly depend on it.
|
* directly depend on it.
|
||||||
*/
|
*/
|
||||||
int getAfferentCoupling() { result = count(ModuleMetrics t | t.dependsOn(this)) }
|
int getAfferentCoupling() { result = count(ModuleMetrics t | t.dependsOn(this)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The efferent coupling of a class is the number of classes that
|
* Gets the efferent coupling of a class -- the number of classes that
|
||||||
* it directly depends on.
|
* it directly depends on.
|
||||||
*/
|
*/
|
||||||
int getEfferentCoupling() { result = count(ModuleMetrics t | this.dependsOn(t)) }
|
int getEfferentCoupling() { result = count(ModuleMetrics t | this.dependsOn(t)) }
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ class Module extends Module_, Scope, AstNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the enclosing scope of this module (always none).
|
||||||
|
*
|
||||||
* This method will be deprecated in the next release. Please use `getEnclosingScope()` instead.
|
* This method will be deprecated in the next release. Please use `getEnclosingScope()` instead.
|
||||||
* The enclosing scope of this module (always none)
|
|
||||||
*/
|
*/
|
||||||
override Scope getScope() { none() }
|
override Scope getScope() { none() }
|
||||||
|
|
||||||
/** The enclosing scope of this module (always none) */
|
/** Gets the enclosing scope of this module (always none) */
|
||||||
override Scope getEnclosingScope() { none() }
|
override Scope getEnclosingScope() { none() }
|
||||||
|
|
||||||
/** Gets the statements forming the body of this module */
|
/** Gets the statements forming the body of this module */
|
||||||
@@ -196,7 +197,7 @@ private predicate isPotentialSourcePackage(Folder f) {
|
|||||||
private predicate isPotentialPackage(Folder f) {
|
private predicate isPotentialPackage(Folder f) {
|
||||||
exists(f.getFile("__init__.py"))
|
exists(f.getFile("__init__.py"))
|
||||||
or
|
or
|
||||||
py_flags_versioned("options.respect_init", "False", _) and major_version() = 2
|
py_flags_versioned("options.respect_init", "False", _) and major_version() = 2 and exists(f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private string moduleNameFromBase(Container file) {
|
private string moduleNameFromBase(Container file) {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import python
|
import python
|
||||||
|
|
||||||
/** Base class for operators */
|
/** The base class for operators */
|
||||||
class Operator extends Operator_ {
|
class Operator extends Operator_ {
|
||||||
/** Gets the name of the special method used to implement this operator */
|
/** Gets the name of the special method used to implement this operator */
|
||||||
string getSpecialMethodName() { none() }
|
string getSpecialMethodName() { none() }
|
||||||
@@ -131,7 +131,7 @@ class Compare extends Compare_ {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** List of comparison operators in a comparison */
|
/** A list of comparison operators in a comparison */
|
||||||
class CmpopList extends CmpopList_ { }
|
class CmpopList extends CmpopList_ { }
|
||||||
|
|
||||||
/** A comparison operator */
|
/** A comparison operator */
|
||||||
|
|||||||
@@ -9,11 +9,12 @@ class Scope extends Scope_ {
|
|||||||
Module getEnclosingModule() { result = this.getEnclosingScope().getEnclosingModule() }
|
Module getEnclosingModule() { result = this.getEnclosingScope().getEnclosingModule() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the scope enclosing this scope (modules have no enclosing scope).
|
||||||
|
*
|
||||||
* This method will be deprecated in the next release. Please use `getEnclosingScope()` instead.
|
* This method will be deprecated in the next release. Please use `getEnclosingScope()` instead.
|
||||||
* The reason for this is to avoid confusion around use of `x.getScope+()` where `x` might be an
|
* The reason for this is to avoid confusion around use of `x.getScope+()` where `x` might be an
|
||||||
* `AstNode` or a `Variable`. Forcing the users to write `x.getScope().getEnclosingScope*()` ensures that
|
* `AstNode` or a `Variable`. Forcing the users to write `x.getScope().getEnclosingScope*()` ensures that
|
||||||
* the apparent semantics and the actual semantics coincide.
|
* the apparent semantics and the actual semantics coincide.
|
||||||
* [ Gets the scope enclosing this scope (modules have no enclosing scope) ]
|
|
||||||
*/
|
*/
|
||||||
Scope getScope() { none() }
|
Scope getScope() { none() }
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ private predicate self_attribute(Attribute attr, Class cls) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper class for UndefinedClassAttribute.ql & MaybeUndefinedClassAttribute.ql */
|
/** A helper class for UndefinedClassAttribute.ql & MaybeUndefinedClassAttribute.ql */
|
||||||
class SelfAttributeRead extends SelfAttribute {
|
class SelfAttributeRead extends SelfAttribute {
|
||||||
SelfAttributeRead() {
|
SelfAttributeRead() {
|
||||||
this.getCtx() instanceof Load and
|
this.getCtx() instanceof Load and
|
||||||
|
|||||||
@@ -112,6 +112,6 @@ class SpecialMethodCallNode extends PotentialSpecialMethodCallNode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The method that is called. */
|
/** Gets the method that is called. */
|
||||||
Value getResolvedSpecialMethod() { result = resolvedSpecialMethod }
|
Value getResolvedSpecialMethod() { result = resolvedSpecialMethod }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -323,7 +323,7 @@ class Raise extends Raise_ {
|
|||||||
override Expr getASubExpression() { py_exprs(result, _, this, _) }
|
override Expr getASubExpression() { py_exprs(result, _, this, _) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The expression immediately following the `raise`, this is the
|
* Gets the expression immediately following the `raise`. This is the
|
||||||
* exception raised, but not accounting for tuples in Python 2.
|
* exception raised, but not accounting for tuples in Python 2.
|
||||||
*/
|
*/
|
||||||
Expr getException() {
|
Expr getException() {
|
||||||
@@ -332,7 +332,7 @@ class Raise extends Raise_ {
|
|||||||
result = this.getExc()
|
result = this.getExc()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The exception raised, accounting for tuples in Python 2. */
|
/** Gets the exception raised, accounting for tuples in Python 2. */
|
||||||
Expr getRaised() {
|
Expr getRaised() {
|
||||||
exists(Expr raw | raw = this.getException() |
|
exists(Expr raw | raw = this.getException() |
|
||||||
if not major_version() = 2 or not exists(raw.(Tuple).getAnElt())
|
if not major_version() = 2 or not exists(raw.(Tuple).getAnElt())
|
||||||
|
|||||||
@@ -227,7 +227,7 @@ private module SensitiveDataModeling {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any kind of variable assignment (also including with/for) where the name indicates
|
* A variable assignment (also including with/for) where the name indicates
|
||||||
* it contains sensitive data.
|
* it contains sensitive data.
|
||||||
*
|
*
|
||||||
* Note: We _could_ make any access to a variable with a sensitive name a source of
|
* Note: We _could_ make any access to a variable with a sensitive name a source of
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
private import python
|
private import python
|
||||||
private import internal.TypeTracker as Internal
|
private import internal.TypeTracker as Internal
|
||||||
|
|
||||||
/** Any string that may appear as the name of an attribute or access path. */
|
/** A string that may appear as the name of an attribute or access path. */
|
||||||
class AttributeName = Internal::ContentName;
|
class AttributeName = Internal::ContentName;
|
||||||
|
|
||||||
/** Either an attribute name, or the empty string (representing no attribute). */
|
/** An attribute name, or the empty string (representing no attribute). */
|
||||||
class OptionalAttributeName = Internal::OptionalContentName;
|
class OptionalAttributeName = Internal::OptionalContentName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Summary of the steps needed to track a value to a given dataflow node.
|
* The summary of the steps needed to track a value to a given dataflow node.
|
||||||
*
|
*
|
||||||
* This can be used to track objects that implement a certain API in order to
|
* This can be used to track objects that implement a certain API in order to
|
||||||
* recognize calls to that API. Note that type-tracking does not by itself provide a
|
* recognize calls to that API. Note that type-tracking does not by itself provide a
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ module syntheticPreUpdateNode {
|
|||||||
override Node getPreUpdateNode() { result.(SyntheticPreUpdateNode).getPostUpdateNode() = this }
|
override Node getPreUpdateNode() { result.(SyntheticPreUpdateNode).getPostUpdateNode() = this }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A label for this kind of node. This will figure in the textual representation of the synthesized pre-update node.
|
* Gets the label for this kind of node. This will figure in the textual representation of the synthesized pre-update node.
|
||||||
*
|
*
|
||||||
* There is currently only one reason for needing a pre-update node, so we always use that as the label.
|
* There is currently only one reason for needing a pre-update node, so we always use that as the label.
|
||||||
*/
|
*/
|
||||||
@@ -108,7 +108,7 @@ module syntheticPostUpdateNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A label for this kind of node. This will figure in the textual representation of the synthesized post-update node.
|
* Gets the label for this kind of node. This will figure in the textual representation of the synthesized post-update node.
|
||||||
* We favour being an arguments as the reason for the post-update node in case multiple reasons apply.
|
* We favour being an arguments as the reason for the post-update node in case multiple reasons apply.
|
||||||
*/
|
*/
|
||||||
string label() {
|
string label() {
|
||||||
@@ -122,6 +122,8 @@ module syntheticPostUpdateNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Gets the pre-update node for this node.
|
||||||
|
*
|
||||||
* An argument might have its value changed as a result of a call.
|
* An argument might have its value changed as a result of a call.
|
||||||
* Certain arguments, such as implicit self arguments are already post-update nodes
|
* Certain arguments, such as implicit self arguments are already post-update nodes
|
||||||
* and should not have an extra node synthesised.
|
* and should not have an extra node synthesised.
|
||||||
@@ -143,7 +145,7 @@ module syntheticPostUpdateNode {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An object might have its value changed after a store. */
|
/** Gets the pre-update node associated with a store. This is used for when an object might have its value changed after a store. */
|
||||||
CfgNode storePreUpdateNode() {
|
CfgNode storePreUpdateNode() {
|
||||||
exists(Attribute a |
|
exists(Attribute a |
|
||||||
result.getNode() = a.getObject().getAFlowNode() and
|
result.getNode() = a.getObject().getAFlowNode() and
|
||||||
@@ -152,7 +154,7 @@ module syntheticPostUpdateNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A node marking the state change of an object after a read.
|
* Gets a node marking the state change of an object after a read.
|
||||||
*
|
*
|
||||||
* A reverse read happens when the result of a read is modified, e.g. in
|
* A reverse read happens when the result of a read is modified, e.g. in
|
||||||
* ```python
|
* ```python
|
||||||
@@ -611,7 +613,7 @@ newtype TDataFlowCallable =
|
|||||||
TLambda(Function lambda) { lambda.isLambda() } or
|
TLambda(Function lambda) { lambda.isLambda() } or
|
||||||
TModule(Module m)
|
TModule(Module m)
|
||||||
|
|
||||||
/** Represents a callable. */
|
/** A callable. */
|
||||||
abstract class DataFlowCallable extends TDataFlowCallable {
|
abstract class DataFlowCallable extends TDataFlowCallable {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
abstract string toString();
|
abstract string toString();
|
||||||
@@ -712,7 +714,7 @@ newtype TDataFlowCall =
|
|||||||
TClassCall(CallNode call) { call = any(ClassValue c | not c.isAbsent()).getACall() } or
|
TClassCall(CallNode call) { call = any(ClassValue c | not c.isAbsent()).getACall() } or
|
||||||
TSpecialCall(SpecialMethodCallNode special)
|
TSpecialCall(SpecialMethodCallNode special)
|
||||||
|
|
||||||
/** Represents a call. */
|
/** A call. */
|
||||||
abstract class DataFlowCall extends TDataFlowCall {
|
abstract class DataFlowCall extends TDataFlowCall {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
abstract string toString();
|
abstract string toString();
|
||||||
@@ -737,7 +739,7 @@ abstract class DataFlowCall extends TDataFlowCall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a call to a function/lambda.
|
* A call to a function/lambda.
|
||||||
* This excludes calls to bound methods, classes, and special methods.
|
* This excludes calls to bound methods, classes, and special methods.
|
||||||
* Bound method calls and class calls insert an argument for the explicit
|
* Bound method calls and class calls insert an argument for the explicit
|
||||||
* `self` parameter, and special method calls have special argument passing.
|
* `self` parameter, and special method calls have special argument passing.
|
||||||
@@ -824,7 +826,7 @@ class ClassCall extends DataFlowCall, TClassCall {
|
|||||||
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getScope() }
|
override DataFlowCallable getEnclosingCallable() { result.getScope() = call.getScope() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Represents a call to a special method. */
|
/** A call to a special method. */
|
||||||
class SpecialCall extends DataFlowCall, TSpecialCall {
|
class SpecialCall extends DataFlowCall, TSpecialCall {
|
||||||
SpecialMethodCallNode special;
|
SpecialMethodCallNode special;
|
||||||
|
|
||||||
@@ -1617,6 +1619,8 @@ import IterableUnpacking
|
|||||||
*/
|
*/
|
||||||
module MatchUnpacking {
|
module MatchUnpacking {
|
||||||
/**
|
/**
|
||||||
|
* Holds when there is flow from the subject `nodeFrom` to the (top-level) pattern `nodeTo` of a `match` statement.
|
||||||
|
*
|
||||||
* The subject of a match flows to each top-level pattern
|
* The subject of a match flows to each top-level pattern
|
||||||
* (a pattern directly under a `case` statement).
|
* (a pattern directly under a `case` statement).
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ abstract class AttributePath extends TAttributePath {
|
|||||||
predicate noAttribute() { this = TNoAttribute() }
|
predicate noAttribute() { this = TNoAttribute() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** AttributePath for no attribute. */
|
/** The `AttributePath` for no attribute. */
|
||||||
class NoAttribute extends TNoAttribute, AttributePath {
|
class NoAttribute extends TNoAttribute, AttributePath {
|
||||||
override string toString() { result = "no attribute" }
|
override string toString() { result = "no attribute" }
|
||||||
|
|
||||||
@@ -88,7 +88,7 @@ class NoAttribute extends TNoAttribute, AttributePath {
|
|||||||
override AttributePath fromAttribute(string name) { none() }
|
override AttributePath fromAttribute(string name) { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** AttributePath for an attribute. */
|
/** The `AttributePath` for an attribute. */
|
||||||
class NamedAttributePath extends TAttribute, AttributePath {
|
class NamedAttributePath extends TAttribute, AttributePath {
|
||||||
override string toString() {
|
override string toString() {
|
||||||
exists(string attr |
|
exists(string attr |
|
||||||
@@ -124,8 +124,8 @@ newtype TTaintTrackingNode =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing the (node, context, path, kind) tuple.
|
* A class representing the (node, context, path, kind) tuple.
|
||||||
* Used for context-sensitive path-aware taint-tracking.
|
* Used for context-sensitive path-aware taint-tracking.
|
||||||
*/
|
*/
|
||||||
class TaintTrackingNode extends TTaintTrackingNode {
|
class TaintTrackingNode extends TTaintTrackingNode {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ deprecated class CallContext extends TaintTrackingContext {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
this.isTop()
|
this.isTop() and exists(s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -180,7 +180,7 @@ abstract class TaintKind extends string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Alias of `TaintKind`, so the two types can be used interchangeably.
|
* An Alias of `TaintKind`, so the two types can be used interchangeably.
|
||||||
*/
|
*/
|
||||||
class FlowLabel = TaintKind;
|
class FlowLabel = TaintKind;
|
||||||
|
|
||||||
@@ -561,7 +561,7 @@ module DataFlowExtension {
|
|||||||
ControlFlowNode getACalleeSuccessorNode(CallNode call) { none() }
|
ControlFlowNode getACalleeSuccessorNode(CallNode call) { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Data flow variable that modifies the basic data-flow. */
|
/** A data flow variable that modifies the basic data-flow. */
|
||||||
class DataFlowVariable extends EssaVariable {
|
class DataFlowVariable extends EssaVariable {
|
||||||
/**
|
/**
|
||||||
* Gets a successor node for data-flow.
|
* Gets a successor node for data-flow.
|
||||||
@@ -608,7 +608,7 @@ private import semmle.python.pointsto.PointsTo
|
|||||||
*/
|
*/
|
||||||
module DataFlow {
|
module DataFlow {
|
||||||
/**
|
/**
|
||||||
* Generic taint kind, source and sink classes for convenience and
|
* The generic taint kind, source and sink classes for convenience and
|
||||||
* compatibility with other language libraries
|
* compatibility with other language libraries
|
||||||
*/
|
*/
|
||||||
class Extension = DataFlowExtension::DataFlowNode;
|
class Extension = DataFlowExtension::DataFlowNode;
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ private newtype TEssaDefinition =
|
|||||||
TPhiFunction(SsaSourceVariable v, BasicBlock b) { EssaDefinitions::phiNode(v, b) }
|
TPhiFunction(SsaSourceVariable v, BasicBlock b) { EssaDefinitions::phiNode(v, b) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of an extended-SSA (ESSA) variable.
|
* A definition of an extended-SSA (ESSA) variable.
|
||||||
* There is exactly one definition for each variable,
|
* There is exactly one definition for each variable,
|
||||||
* and exactly one variable for each definition.
|
* and exactly one variable for each definition.
|
||||||
*/
|
*/
|
||||||
@@ -171,6 +171,9 @@ abstract class EssaDefinition extends TEssaDefinition {
|
|||||||
EssaVariable getVariable() { result.getDefinition() = this }
|
EssaVariable getVariable() { result.getDefinition() = this }
|
||||||
|
|
||||||
abstract BasicBlock getBasicBlock();
|
abstract BasicBlock getBasicBlock();
|
||||||
|
|
||||||
|
/** Gets the name of the primary QL class for this element. */
|
||||||
|
string getAPrimaryQlClass() { result = "EssaDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -216,13 +219,15 @@ class EssaEdgeRefinement extends EssaDefinition, TEssaEdgeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override string getRepresentation() {
|
override string getRepresentation() {
|
||||||
result = this.getAQlClass() + "(" + this.getInput().getRepresentation() + ")"
|
result = this.getAPrimaryQlClass() + "(" + this.getInput().getRepresentation() + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets the scope of the variable defined by this definition. */
|
/** Gets the scope of the variable defined by this definition. */
|
||||||
override Scope getScope() { result = this.getPredecessor().getScope() }
|
override Scope getScope() { result = this.getPredecessor().getScope() }
|
||||||
|
|
||||||
override BasicBlock getBasicBlock() { result = this.getSuccessor() }
|
override BasicBlock getBasicBlock() { result = this.getSuccessor() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "EssaEdgeRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A Phi-function as specified in classic SSA form. */
|
/** A Phi-function as specified in classic SSA form. */
|
||||||
@@ -366,6 +371,8 @@ class PhiFunction extends EssaDefinition, TPhiFunction {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "PhiFunction" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -396,7 +403,7 @@ class EssaNodeDefinition extends EssaDefinition, TEssaNodeDefinition {
|
|||||||
|
|
||||||
override Location getLocation() { result = this.getDefiningNode().getLocation() }
|
override Location getLocation() { result = this.getDefiningNode().getLocation() }
|
||||||
|
|
||||||
override string getRepresentation() { result = this.getAQlClass() }
|
override string getRepresentation() { result = this.getAPrimaryQlClass() }
|
||||||
|
|
||||||
override Scope getScope() {
|
override Scope getScope() {
|
||||||
exists(BasicBlock defb |
|
exists(BasicBlock defb |
|
||||||
@@ -414,6 +421,8 @@ class EssaNodeDefinition extends EssaDefinition, TEssaNodeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override BasicBlock getBasicBlock() { result = this.getDefiningNode().getBasicBlock() }
|
override BasicBlock getBasicBlock() { result = this.getDefiningNode().getBasicBlock() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "EssaNodeDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition of an ESSA variable that takes another ESSA variable as an input. */
|
/** A definition of an ESSA variable that takes another ESSA variable as an input. */
|
||||||
@@ -448,10 +457,10 @@ class EssaNodeRefinement extends EssaDefinition, TEssaNodeRefinement {
|
|||||||
override Location getLocation() { result = this.getDefiningNode().getLocation() }
|
override Location getLocation() { result = this.getDefiningNode().getLocation() }
|
||||||
|
|
||||||
override string getRepresentation() {
|
override string getRepresentation() {
|
||||||
result = this.getAQlClass() + "(" + this.getInput().getRepresentation() + ")"
|
result = this.getAPrimaryQlClass() + "(" + this.getInput().getRepresentation() + ")"
|
||||||
or
|
or
|
||||||
not exists(this.getInput()) and
|
not exists(this.getInput()) and
|
||||||
result = this.getAQlClass() + "(" + this.getSourceVariable().getName() + "??)"
|
result = this.getAPrimaryQlClass() + "(" + this.getSourceVariable().getName() + "??)"
|
||||||
}
|
}
|
||||||
|
|
||||||
override Scope getScope() {
|
override Scope getScope() {
|
||||||
@@ -470,6 +479,8 @@ class EssaNodeRefinement extends EssaDefinition, TEssaNodeRefinement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override BasicBlock getBasicBlock() { result = this.getDefiningNode().getBasicBlock() }
|
override BasicBlock getBasicBlock() { result = this.getDefiningNode().getBasicBlock() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "EssaNodeRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[noopt]
|
pragma[noopt]
|
||||||
@@ -500,9 +511,11 @@ class AssignmentDefinition extends EssaNodeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override string getRepresentation() { result = this.getValue().getNode().toString() }
|
override string getRepresentation() { result = this.getValue().getNode().toString() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "AssignmentDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Capture of a raised exception `except ExceptionType ex:` */
|
/** A capture of a raised exception `except ExceptionType ex:` */
|
||||||
class ExceptionCapture extends EssaNodeDefinition {
|
class ExceptionCapture extends EssaNodeDefinition {
|
||||||
ExceptionCapture() {
|
ExceptionCapture() {
|
||||||
SsaSource::exception_capture(this.getSourceVariable(), this.getDefiningNode())
|
SsaSource::exception_capture(this.getSourceVariable(), this.getDefiningNode())
|
||||||
@@ -516,6 +529,8 @@ class ExceptionCapture extends EssaNodeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override string getRepresentation() { result = "except " + this.getSourceVariable().getName() }
|
override string getRepresentation() { result = "except " + this.getSourceVariable().getName() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "ExceptionCapture" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An assignment to a variable as part of a multiple assignment `..., v, ... = val` */
|
/** An assignment to a variable as part of a multiple assignment `..., v, ... = val` */
|
||||||
@@ -536,6 +551,8 @@ class MultiAssignmentDefinition extends EssaNodeDefinition {
|
|||||||
SsaSource::multi_assignment_definition(this.getSourceVariable(), this.getDefiningNode(), index,
|
SsaSource::multi_assignment_definition(this.getSourceVariable(), this.getDefiningNode(), index,
|
||||||
lhs)
|
lhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "MultiAssignmentDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition of a variable in a `with` statement */
|
/** A definition of a variable in a `with` statement */
|
||||||
@@ -543,6 +560,8 @@ class WithDefinition extends EssaNodeDefinition {
|
|||||||
WithDefinition() { SsaSource::with_definition(this.getSourceVariable(), this.getDefiningNode()) }
|
WithDefinition() { SsaSource::with_definition(this.getSourceVariable(), this.getDefiningNode()) }
|
||||||
|
|
||||||
override string getRepresentation() { result = "with" }
|
override string getRepresentation() { result = "with" }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "WithDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition of a variable via a capture pattern */
|
/** A definition of a variable via a capture pattern */
|
||||||
@@ -552,6 +571,8 @@ class PatternCaptureDefinition extends EssaNodeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override string getRepresentation() { result = "pattern capture" }
|
override string getRepresentation() { result = "pattern capture" }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "PatternCaptureDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition of a variable via a pattern alias */
|
/** A definition of a variable via a pattern alias */
|
||||||
@@ -561,6 +582,8 @@ class PatternAliasDefinition extends EssaNodeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override string getRepresentation() { result = "pattern alias" }
|
override string getRepresentation() { result = "pattern alias" }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "PatternAliasDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition of a variable by declaring it as a parameter */
|
/** A definition of a variable by declaring it as a parameter */
|
||||||
@@ -594,6 +617,8 @@ class ParameterDefinition extends EssaNodeDefinition {
|
|||||||
|
|
||||||
/** Gets the `Parameter` this `ParameterDefinition` represents. */
|
/** Gets the `Parameter` this `ParameterDefinition` represents. */
|
||||||
Parameter getParameter() { result = this.getDefiningNode().getNode() }
|
Parameter getParameter() { result = this.getDefiningNode().getNode() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "ParameterDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A deletion of a variable `del v` */
|
/** A deletion of a variable `del v` */
|
||||||
@@ -601,10 +626,12 @@ class DeletionDefinition extends EssaNodeDefinition {
|
|||||||
DeletionDefinition() {
|
DeletionDefinition() {
|
||||||
SsaSource::deletion_definition(this.getSourceVariable(), this.getDefiningNode())
|
SsaSource::deletion_definition(this.getSourceVariable(), this.getDefiningNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "DeletionDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Definition of variable at the entry of a scope. Usually this represents the transfer of
|
* A definition of variable at the entry of a scope. Usually this represents the transfer of
|
||||||
* a global or non-local variable from one scope to another.
|
* a global or non-local variable from one scope to another.
|
||||||
*/
|
*/
|
||||||
class ScopeEntryDefinition extends EssaNodeDefinition {
|
class ScopeEntryDefinition extends EssaNodeDefinition {
|
||||||
@@ -614,16 +641,20 @@ class ScopeEntryDefinition extends EssaNodeDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override Scope getScope() { result.getEntryNode() = this.getDefiningNode() }
|
override Scope getScope() { result.getEntryNode() = this.getDefiningNode() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "ScopeEntryDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Possible redefinition of variable via `from ... import *` */
|
/** A possible redefinition of variable via `from ... import *` */
|
||||||
class ImportStarRefinement extends EssaNodeRefinement {
|
class ImportStarRefinement extends EssaNodeRefinement {
|
||||||
ImportStarRefinement() {
|
ImportStarRefinement() {
|
||||||
SsaSource::import_star_refinement(this.getSourceVariable(), _, this.getDefiningNode())
|
SsaSource::import_star_refinement(this.getSourceVariable(), _, this.getDefiningNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "ImportStarRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Assignment of an attribute `obj.attr = val` */
|
/** An assignment of an attribute `obj.attr = val` */
|
||||||
class AttributeAssignment extends EssaNodeRefinement {
|
class AttributeAssignment extends EssaNodeRefinement {
|
||||||
AttributeAssignment() {
|
AttributeAssignment() {
|
||||||
SsaSource::attribute_assignment_refinement(this.getSourceVariable(), _, this.getDefiningNode())
|
SsaSource::attribute_assignment_refinement(this.getSourceVariable(), _, this.getDefiningNode())
|
||||||
@@ -635,12 +666,16 @@ class AttributeAssignment extends EssaNodeRefinement {
|
|||||||
|
|
||||||
override string getRepresentation() {
|
override string getRepresentation() {
|
||||||
result =
|
result =
|
||||||
this.getAQlClass() + " '" + this.getName() + "'(" + this.getInput().getRepresentation() + ")"
|
this.getAPrimaryQlClass() + " '" + this.getName() + "'(" + this.getInput().getRepresentation()
|
||||||
|
+ ")"
|
||||||
or
|
or
|
||||||
not exists(this.getInput()) and
|
not exists(this.getInput()) and
|
||||||
result =
|
result =
|
||||||
this.getAQlClass() + " '" + this.getName() + "'(" + this.getSourceVariable().getName() + "??)"
|
this.getAPrimaryQlClass() + " '" + this.getName() + "'(" + this.getSourceVariable().getName() +
|
||||||
|
"??)"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "AttributeAssignment" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A use of a variable as an argument, `foo(v)`, which might modify the object referred to. */
|
/** A use of a variable as an argument, `foo(v)`, which might modify the object referred to. */
|
||||||
@@ -654,15 +689,19 @@ class ArgumentRefinement extends EssaNodeRefinement {
|
|||||||
ControlFlowNode getArgument() { result = argument }
|
ControlFlowNode getArgument() { result = argument }
|
||||||
|
|
||||||
CallNode getCall() { result = this.getDefiningNode() }
|
CallNode getCall() { result = this.getDefiningNode() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "ArgumentRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Deletion of an attribute `del obj.attr`. */
|
/** A deletion of an attribute `del obj.attr`. */
|
||||||
class EssaAttributeDeletion extends EssaNodeRefinement {
|
class EssaAttributeDeletion extends EssaNodeRefinement {
|
||||||
EssaAttributeDeletion() {
|
EssaAttributeDeletion() {
|
||||||
SsaSource::attribute_deletion_refinement(this.getSourceVariable(), _, this.getDefiningNode())
|
SsaSource::attribute_deletion_refinement(this.getSourceVariable(), _, this.getDefiningNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
string getName() { result = this.getDefiningNode().(AttrNode).getName() }
|
string getName() { result = this.getDefiningNode().(AttrNode).getName() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "EssaAttributeDeletion" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A pi-node (guard) with only one successor. */
|
/** A pi-node (guard) with only one successor. */
|
||||||
@@ -690,10 +729,12 @@ class SingleSuccessorGuard extends EssaNodeRefinement {
|
|||||||
test = this.getDefiningNode() and
|
test = this.getDefiningNode() and
|
||||||
SsaSource::test_refinement(this.getSourceVariable(), use, test)
|
SsaSource::test_refinement(this.getSourceVariable(), use, test)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "SingleSuccessorGuard" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implicit definition of the names of sub-modules in a package.
|
* An implicit definition of the names of sub-modules in a package.
|
||||||
* Although the interpreter does not pre-define these names, merely populating them
|
* Although the interpreter does not pre-define these names, merely populating them
|
||||||
* as they are imported, this is a good approximation for static analysis.
|
* as they are imported, this is a good approximation for static analysis.
|
||||||
*/
|
*/
|
||||||
@@ -701,11 +742,13 @@ class ImplicitSubModuleDefinition extends EssaNodeDefinition {
|
|||||||
ImplicitSubModuleDefinition() {
|
ImplicitSubModuleDefinition() {
|
||||||
SsaSource::init_module_submodule_defn(this.getSourceVariable(), this.getDefiningNode())
|
SsaSource::init_module_submodule_defn(this.getSourceVariable(), this.getDefiningNode())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "ImplicitSubModuleDefinition" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An implicit (possible) definition of an escaping variable at a call-site */
|
/** An implicit (possible) definition of an escaping variable at a call-site */
|
||||||
class CallsiteRefinement extends EssaNodeRefinement {
|
class CallsiteRefinement extends EssaNodeRefinement {
|
||||||
override string toString() { result = "CallsiteRefinement" }
|
override string toString() { result = "CallSiteRefinement" }
|
||||||
|
|
||||||
CallsiteRefinement() {
|
CallsiteRefinement() {
|
||||||
exists(SsaSourceVariable var, ControlFlowNode defn |
|
exists(SsaSourceVariable var, ControlFlowNode defn |
|
||||||
@@ -718,6 +761,8 @@ class CallsiteRefinement extends EssaNodeRefinement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CallNode getCall() { this.getDefiningNode() = result }
|
CallNode getCall() { this.getDefiningNode() = result }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "CallsiteRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An implicit (possible) modification of the object referred at a method call */
|
/** An implicit (possible) modification of the object referred at a method call */
|
||||||
@@ -728,14 +773,18 @@ class MethodCallsiteRefinement extends EssaNodeRefinement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
CallNode getCall() { this.getDefiningNode() = result }
|
CallNode getCall() { this.getDefiningNode() = result }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "MethodCallsiteRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** An implicit (possible) modification of `self` at a method call */
|
/** An implicit (possible) modification of `self` at a method call */
|
||||||
class SelfCallsiteRefinement extends MethodCallsiteRefinement {
|
class SelfCallsiteRefinement extends MethodCallsiteRefinement {
|
||||||
SelfCallsiteRefinement() { this.getSourceVariable().(Variable).isSelf() }
|
SelfCallsiteRefinement() { this.getSourceVariable().(Variable).isSelf() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "SelfCallsiteRefinement" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Python specific sub-class of generic EssaEdgeRefinement */
|
/** A Python specific sub-class of generic EssaEdgeRefinement */
|
||||||
class PyEdgeRefinement extends EssaEdgeRefinement {
|
class PyEdgeRefinement extends EssaEdgeRefinement {
|
||||||
override string getRepresentation() {
|
override string getRepresentation() {
|
||||||
/*
|
/*
|
||||||
@@ -750,4 +799,6 @@ class PyEdgeRefinement extends EssaEdgeRefinement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ControlFlowNode getTest() { result = this.getPredecessor().getLastNode() }
|
ControlFlowNode getTest() { result = this.getPredecessor().getLastNode() }
|
||||||
|
|
||||||
|
override string getAPrimaryQlClass() { result = "PyEdgeRefinement" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ private module SsaComputeImpl {
|
|||||||
Liveness::liveAtEntry(v, succ)
|
Liveness::liveAtEntry(v, succ)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A phi node for `v` at the beginning of basic block `b`. */
|
/** Holds if there is a phi node for `v` at the beginning of basic block `b`. */
|
||||||
cached
|
cached
|
||||||
predicate phiNode(SsaSourceVariable v, BasicBlock b) {
|
predicate phiNode(SsaSourceVariable v, BasicBlock b) {
|
||||||
(
|
(
|
||||||
@@ -175,8 +175,8 @@ private module SsaComputeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A ranking of the indices `i` at which there is an SSA definition or use of
|
* Holds if the `rankix`th definition or use of the SSA variable `v` in the basic block `b` occurs
|
||||||
* `v` in the basic block `b`.
|
* at index `i`.
|
||||||
*
|
*
|
||||||
* Basic block indices are translated to rank indices in order to skip
|
* Basic block indices are translated to rank indices in order to skip
|
||||||
* irrelevant indices at which there is no definition or use when traversing
|
* irrelevant indices at which there is no definition or use when traversing
|
||||||
@@ -187,14 +187,14 @@ private module SsaComputeImpl {
|
|||||||
i = rank[rankix](int j | variableDef(v, _, b, j) or variableUse(v, _, b, j))
|
i = rank[rankix](int j | variableDef(v, _, b, j) or variableUse(v, _, b, j))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A definition of a variable occurring at the specified rank index in basic block `b`. */
|
/** Holds if there is a definition of a variable occurring at the specified rank index in basic block `b`. */
|
||||||
cached
|
cached
|
||||||
predicate defRank(SsaSourceVariable v, BasicBlock b, int rankix, int i) {
|
predicate defRank(SsaSourceVariable v, BasicBlock b, int rankix, int i) {
|
||||||
variableDef(v, _, b, i) and
|
variableDef(v, _, b, i) and
|
||||||
defUseRank(v, b, rankix, i)
|
defUseRank(v, b, rankix, i)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A variable access `use` of `v` in `b` at index `i`. */
|
/** Holds if there is a variable access `use` of `v` in `b` at index `i`. */
|
||||||
cached
|
cached
|
||||||
predicate variableUse(SsaSourceVariable v, ControlFlowNode use, BasicBlock b, int i) {
|
predicate variableUse(SsaSourceVariable v, ControlFlowNode use, BasicBlock b, int i) {
|
||||||
(v.getAUse() = use or v.hasRefinement(use, _)) and
|
(v.getAUse() = use or v.hasRefinement(use, _)) and
|
||||||
@@ -205,7 +205,7 @@ private module SsaComputeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A definition of an SSA variable occurring at the specified position.
|
* Holds if there is a definition of an SSA variable occurring at the specified position.
|
||||||
* This is either a phi node, a `VariableUpdate`, or a parameter.
|
* This is either a phi node, a `VariableUpdate`, or a parameter.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
@@ -227,7 +227,7 @@ private module SsaComputeImpl {
|
|||||||
* dominance.
|
* dominance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/** The maximum rank index for the given variable and basic block. */
|
/** Gets the maximum rank index for the given variable and basic block. */
|
||||||
cached
|
cached
|
||||||
int lastRank(SsaSourceVariable v, BasicBlock b) {
|
int lastRank(SsaSourceVariable v, BasicBlock b) {
|
||||||
result = max(int rankix | defUseRank(v, b, rankix, _))
|
result = max(int rankix | defUseRank(v, b, rankix, _))
|
||||||
@@ -253,7 +253,7 @@ private module SsaComputeImpl {
|
|||||||
i = piIndex()
|
i = piIndex()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The SSA definition reaches the rank index `rankix` in its own basic block `b`. */
|
/** Holds if the SSA definition reaches the rank index `rankix` in its own basic block `b`. */
|
||||||
cached
|
cached
|
||||||
predicate ssaDefReachesRank(SsaSourceVariable v, BasicBlock b, int i, int rankix) {
|
predicate ssaDefReachesRank(SsaSourceVariable v, BasicBlock b, int i, int rankix) {
|
||||||
ssaDefRank(v, b, rankix, i)
|
ssaDefRank(v, b, rankix, i)
|
||||||
@@ -264,7 +264,7 @@ private module SsaComputeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSA definition of `v` at `def` reaches `use` in the same basic block
|
* Holds if the SSA definition of `v` at `def` reaches `use` in the same basic block
|
||||||
* without crossing another SSA definition of `v`.
|
* without crossing another SSA definition of `v`.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
@@ -303,7 +303,7 @@ private module SsaComputeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSA definition of `v` at `def` reaches the end of a basic block `b`, at
|
* Holds if the SSA definition of `v` at `def` reaches the end of a basic block `b`, at
|
||||||
* which point it is still live, without crossing another SSA definition of `v`.
|
* which point it is still live, without crossing another SSA definition of `v`.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
@@ -320,7 +320,7 @@ private module SsaComputeImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSA definition of `v` at `(defbb, defindex)` reaches `use` without crossing another
|
* Holds if the SSA definition of `v` at `(defbb, defindex)` reaches `use` without crossing another
|
||||||
* SSA definition of `v`.
|
* SSA definition of `v`.
|
||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
@@ -360,7 +360,7 @@ private module SsaComputeImpl {
|
|||||||
i = rank[rankix](int j | variableDefine(v, _, b, j) or variableSourceUse(v, _, b, j))
|
i = rank[rankix](int j | variableDefine(v, _, b, j) or variableSourceUse(v, _, b, j))
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A variable access `use` of `v` in `b` at index `i`. */
|
/** Holds if there is a variable access `use` of `v` in `b` at index `i`. */
|
||||||
cached
|
cached
|
||||||
predicate variableSourceUse(SsaSourceVariable v, ControlFlowNode use, BasicBlock b, int i) {
|
predicate variableSourceUse(SsaSourceVariable v, ControlFlowNode use, BasicBlock b, int i) {
|
||||||
v.getASourceUse() = use and
|
v.getASourceUse() = use and
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ abstract class GeneratedFile extends File {
|
|||||||
* There is no formal reason for the above, it just seems to work well in practice.
|
* There is no formal reason for the above, it just seems to work well in practice.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
library class GenericGeneratedFile extends GeneratedFile {
|
class GenericGeneratedFile extends GeneratedFile {
|
||||||
GenericGeneratedFile() {
|
GenericGeneratedFile() {
|
||||||
not this instanceof SpecificGeneratedFile and
|
not this instanceof SpecificGeneratedFile and
|
||||||
(
|
(
|
||||||
@@ -103,7 +103,7 @@ private predicate auto_generated(File f) {
|
|||||||
/**
|
/**
|
||||||
* A file generated by a template engine
|
* A file generated by a template engine
|
||||||
*/
|
*/
|
||||||
abstract library class SpecificGeneratedFile extends GeneratedFile {
|
abstract class SpecificGeneratedFile extends GeneratedFile {
|
||||||
/*
|
/*
|
||||||
* Currently cover Spitfire, Pyxl and Mako.
|
* Currently cover Spitfire, Pyxl and Mako.
|
||||||
* Django templates are not compiled to Python.
|
* Django templates are not compiled to Python.
|
||||||
@@ -112,7 +112,7 @@ abstract library class SpecificGeneratedFile extends GeneratedFile {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** File generated by the spitfire templating engine */
|
/** A file generated by the spitfire templating engine */
|
||||||
class SpitfireGeneratedFile extends SpecificGeneratedFile {
|
class SpitfireGeneratedFile extends SpecificGeneratedFile {
|
||||||
SpitfireGeneratedFile() {
|
SpitfireGeneratedFile() {
|
||||||
exists(Module m | m.getFile() = this and not m instanceof SpitfireTemplate |
|
exists(Module m | m.getFile() = this and not m instanceof SpitfireTemplate |
|
||||||
@@ -127,14 +127,14 @@ class SpitfireGeneratedFile extends SpecificGeneratedFile {
|
|||||||
override string getTool() { result = "spitfire" }
|
override string getTool() { result = "spitfire" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** File generated by the pyxl templating engine */
|
/** A file generated by the pyxl templating engine */
|
||||||
class PyxlGeneratedFile extends SpecificGeneratedFile {
|
class PyxlGeneratedFile extends SpecificGeneratedFile {
|
||||||
PyxlGeneratedFile() { this.getSpecifiedEncoding() = "pyxl" }
|
PyxlGeneratedFile() { this.getSpecifiedEncoding() = "pyxl" }
|
||||||
|
|
||||||
override string getTool() { result = "pyxl" }
|
override string getTool() { result = "pyxl" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** File generated by the mako templating engine */
|
/** A file generated by the mako templating engine */
|
||||||
class MakoGeneratedFile extends SpecificGeneratedFile {
|
class MakoGeneratedFile extends SpecificGeneratedFile {
|
||||||
MakoGeneratedFile() {
|
MakoGeneratedFile() {
|
||||||
exists(Module m | m.getFile() = this |
|
exists(Module m | m.getFile() = this |
|
||||||
@@ -166,7 +166,7 @@ string from_mako_import(Module m) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** File generated by Google's protobuf tool. */
|
/** A file generated by Google's protobuf tool. */
|
||||||
class ProtobufGeneratedFile extends SpecificGeneratedFile {
|
class ProtobufGeneratedFile extends SpecificGeneratedFile {
|
||||||
ProtobufGeneratedFile() {
|
ProtobufGeneratedFile() {
|
||||||
this.getAbsolutePath().regexpMatch(".*_pb2?.py") and
|
this.getAbsolutePath().regexpMatch(".*_pb2?.py") and
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class UnitTestClass extends TestScope {
|
|||||||
|
|
||||||
abstract class Test extends TestScope { }
|
abstract class Test extends TestScope { }
|
||||||
|
|
||||||
/** Class of test function that uses the `unittest` framework */
|
/** A test function that uses the `unittest` framework */
|
||||||
class UnitTestFunction extends Test {
|
class UnitTestFunction extends Test {
|
||||||
UnitTestFunction() {
|
UnitTestFunction() {
|
||||||
this.getScope+() instanceof UnitTestClass and
|
this.getScope+() instanceof UnitTestClass and
|
||||||
@@ -37,7 +37,7 @@ class NoseTestFunction extends Test {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class of functions that are clearly tests, but don't belong to a specific framework */
|
/** A function that is clearly a test, but doesn't belong to a specific framework */
|
||||||
class UnknownTestFunction extends Test {
|
class UnknownTestFunction extends Test {
|
||||||
UnknownTestFunction() {
|
UnknownTestFunction() {
|
||||||
this.(Function).getName().matches("test%") and
|
this.(Function).getName().matches("test%") and
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ private module Aiomysql {
|
|||||||
private import semmle.python.internal.Awaited
|
private import semmle.python.internal.Awaited
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `ConectionPool` is created when the result of `aiomysql.create_pool()` is awaited.
|
* Gets a `ConnectionPool` that is created when the result of `aiomysql.create_pool()` is awaited.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/pool.html
|
* See https://aiomysql.readthedocs.io/en/stable/pool.html
|
||||||
*/
|
*/
|
||||||
API::Node connectionPool() {
|
API::Node connectionPool() {
|
||||||
@@ -23,7 +23,7 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Connection` is created when
|
* Gets a `Connection` that is created when
|
||||||
* - the result of `aiomysql.connect()` is awaited.
|
* - the result of `aiomysql.connect()` is awaited.
|
||||||
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/connection.html#connection
|
* See https://aiomysql.readthedocs.io/en/stable/connection.html#connection
|
||||||
@@ -35,7 +35,7 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Cursor` is created when
|
* Gets a `Cursor` that is created when
|
||||||
* - the result of calling `cursor` on a `ConnectionPool` is awaited.
|
* - the result of calling `cursor` on a `ConnectionPool` is awaited.
|
||||||
* - the result of calling `cursor` on a `Connection` is awaited.
|
* - the result of calling `cursor` on a `Connection` is awaited.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/cursors.html
|
* See https://aiomysql.readthedocs.io/en/stable/cursors.html
|
||||||
@@ -47,7 +47,7 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calling `execute` on a `Cursor` constructs a query.
|
* A query. Calling `execute` on a `Cursor` constructs a query.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/cursors.html#Cursor.execute
|
* See https://aiomysql.readthedocs.io/en/stable/cursors.html#Cursor.execute
|
||||||
*/
|
*/
|
||||||
class CursorExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
class CursorExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
||||||
@@ -73,7 +73,7 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Awaiting the result of calling `execute` executes the query.
|
* An awaited query. Awaiting the result of calling `execute` executes the query.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/cursors.html#Cursor.execute
|
* See https://aiomysql.readthedocs.io/en/stable/cursors.html#Cursor.execute
|
||||||
*/
|
*/
|
||||||
class AwaitedCursorExecuteCall extends SqlExecution::Range {
|
class AwaitedCursorExecuteCall extends SqlExecution::Range {
|
||||||
@@ -85,7 +85,7 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Engine` is created when the result of calling `aiomysql.sa.create_engine` is awaited.
|
* Gets an `Engine` that is created when the result of calling `aiomysql.sa.create_engine` is awaited.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/sa.html#engine
|
* See https://aiomysql.readthedocs.io/en/stable/sa.html#engine
|
||||||
*/
|
*/
|
||||||
API::Node engine() {
|
API::Node engine() {
|
||||||
@@ -98,13 +98,13 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `SAConnection` is created when the result of calling `aquire` on an `Engine` is awaited.
|
* Gets an `SAConnection` that is created when the result of calling `aquire` on an `Engine` is awaited.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/sa.html#connection
|
* See https://aiomysql.readthedocs.io/en/stable/sa.html#connection
|
||||||
*/
|
*/
|
||||||
API::Node saConnection() { result = engine().getMember("acquire").getReturn().getAwaited() }
|
API::Node saConnection() { result = engine().getMember("acquire").getReturn().getAwaited() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calling `execute` on a `SAConnection` constructs a query.
|
* A query. Calling `execute` on a `SAConnection` constructs a query.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/sa.html#aiomysql.sa.SAConnection.execute
|
* See https://aiomysql.readthedocs.io/en/stable/sa.html#aiomysql.sa.SAConnection.execute
|
||||||
*/
|
*/
|
||||||
class SAConnectionExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
class SAConnectionExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
||||||
@@ -132,7 +132,7 @@ private module Aiomysql {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Awaiting the result of calling `execute` executes the query.
|
* An awaited query. Awaiting the result of calling `execute` executes the query.
|
||||||
* See https://aiomysql.readthedocs.io/en/stable/sa.html#aiomysql.sa.SAConnection.execute
|
* See https://aiomysql.readthedocs.io/en/stable/sa.html#aiomysql.sa.SAConnection.execute
|
||||||
*/
|
*/
|
||||||
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
|
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ private module Aiopg {
|
|||||||
private import semmle.python.internal.Awaited
|
private import semmle.python.internal.Awaited
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `ConectionPool` is created when the result of `aiopg.create_pool()` is awaited.
|
* Gets a `ConnectionPool` that is created when the result of `aiopg.create_pool()` is awaited.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/core.html#pool
|
* See https://aiopg.readthedocs.io/en/stable/core.html#pool
|
||||||
*/
|
*/
|
||||||
API::Node connectionPool() {
|
API::Node connectionPool() {
|
||||||
@@ -23,7 +23,7 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Connection` is created when
|
* Gets a `Connection` that is created when
|
||||||
* - the result of `aiopg.connect()` is awaited.
|
* - the result of `aiopg.connect()` is awaited.
|
||||||
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/core.html#connection
|
* See https://aiopg.readthedocs.io/en/stable/core.html#connection
|
||||||
@@ -35,7 +35,7 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Cursor` is created when
|
* Gets a `Cursor` that is created when
|
||||||
* - the result of calling `cursor` on a `ConnectionPool` is awaited.
|
* - the result of calling `cursor` on a `ConnectionPool` is awaited.
|
||||||
* - the result of calling `cursor` on a `Connection` is awaited.
|
* - the result of calling `cursor` on a `Connection` is awaited.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/core.html#cursor
|
* See https://aiopg.readthedocs.io/en/stable/core.html#cursor
|
||||||
@@ -47,7 +47,7 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calling `execute` on a `Cursor` constructs a query.
|
* A query. Calling `execute` on a `Cursor` constructs a query.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute
|
* See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute
|
||||||
*/
|
*/
|
||||||
class CursorExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
class CursorExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
||||||
@@ -73,7 +73,7 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Awaiting the result of calling `execute` executes the query.
|
* An awaited query. Awaiting the result of calling `execute` executes the query.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute
|
* See https://aiopg.readthedocs.io/en/stable/core.html#aiopg.Cursor.execute
|
||||||
*/
|
*/
|
||||||
class AwaitedCursorExecuteCall extends SqlExecution::Range {
|
class AwaitedCursorExecuteCall extends SqlExecution::Range {
|
||||||
@@ -85,7 +85,7 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An `Engine` is created when the result of calling `aiopg.sa.create_engine` is awaited.
|
* Gets an `Engine` that is created when the result of calling `aiopg.sa.create_engine` is awaited.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#engine
|
* See https://aiopg.readthedocs.io/en/stable/sa.html#engine
|
||||||
*/
|
*/
|
||||||
API::Node engine() {
|
API::Node engine() {
|
||||||
@@ -94,13 +94,13 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `SAConnection` is created when the result of calling `aquire` on an `Engine` is awaited.
|
* Gets an `SAConnection` that is created when the result of calling `aquire` on an `Engine` is awaited.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#connection
|
* See https://aiopg.readthedocs.io/en/stable/sa.html#connection
|
||||||
*/
|
*/
|
||||||
API::Node saConnection() { result = engine().getMember("acquire").getReturn().getAwaited() }
|
API::Node saConnection() { result = engine().getMember("acquire").getReturn().getAwaited() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calling `execute` on a `SAConnection` constructs a query.
|
* A query. Calling `execute` on a `SAConnection` constructs a query.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
||||||
*/
|
*/
|
||||||
class SAConnectionExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
class SAConnectionExecuteCall extends SqlConstruction::Range, DataFlow::CallCfgNode {
|
||||||
@@ -128,7 +128,7 @@ private module Aiopg {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Awaiting the result of calling `execute` executes the query.
|
* An awaited query. Awaiting the result of calling `execute` executes the query.
|
||||||
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
* See https://aiopg.readthedocs.io/en/stable/sa.html#aiopg.sa.SAConnection.execute
|
||||||
*/
|
*/
|
||||||
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
|
class AwaitedSAConnectionExecuteCall extends SqlExecution::Range {
|
||||||
|
|||||||
@@ -12,13 +12,13 @@ private import semmle.python.ApiGraphs
|
|||||||
private module Asyncpg {
|
private module Asyncpg {
|
||||||
private import semmle.python.internal.Awaited
|
private import semmle.python.internal.Awaited
|
||||||
|
|
||||||
/** A `ConectionPool` is created when the result of `asyncpg.create_pool()` is awaited. */
|
/** Gets a `ConnectionPool` that is created when the result of `asyncpg.create_pool()` is awaited. */
|
||||||
API::Node connectionPool() {
|
API::Node connectionPool() {
|
||||||
result = API::moduleImport("asyncpg").getMember("create_pool").getReturn().getAwaited()
|
result = API::moduleImport("asyncpg").getMember("create_pool").getReturn().getAwaited()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `Connection` is created when
|
* Gets a `Connection` that is created when
|
||||||
* - the result of `asyncpg.connect()` is awaited.
|
* - the result of `asyncpg.connect()` is awaited.
|
||||||
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
* - the result of calling `aquire` on a `ConnectionPool` is awaited.
|
||||||
*/
|
*/
|
||||||
@@ -46,7 +46,7 @@ private module Asyncpg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** `Connection`s and `ConnectionPool`s provide some methods that access the file system. */
|
/** A model of `Connection` and `ConnectionPool`, which provide some methods that access the file system. */
|
||||||
class FileAccessOnConnection extends FileSystemAccess::Range, DataFlow::MethodCallNode {
|
class FileAccessOnConnection extends FileSystemAccess::Range, DataFlow::MethodCallNode {
|
||||||
string methodName;
|
string methodName;
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ private import semmle.python.frameworks.PEP249
|
|||||||
*/
|
*/
|
||||||
module ClickhouseDriver {
|
module ClickhouseDriver {
|
||||||
/**
|
/**
|
||||||
* `clickhouse_driver` implements PEP249,
|
* A model of `clickhouse-driver`, which implements PEP249,
|
||||||
* providing ways to execute SQL statements against a database.
|
* providing ways to execute SQL statements against a database.
|
||||||
*/
|
*/
|
||||||
class ClickHouseDriverPEP249 extends PEP249::PEP249ModuleApiNode {
|
class ClickHouseDriverPEP249 extends PEP249::PEP249ModuleApiNode {
|
||||||
|
|||||||
@@ -1862,7 +1862,8 @@ module PrivateDjango {
|
|||||||
// routing modeling
|
// routing modeling
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* In order to recognize a class as being a django view class, based on the `as_view`
|
* A class that may be a django view class. In order to recognize a class as being a django view class,
|
||||||
|
* based on the `as_view`
|
||||||
* call, we need to be able to track such calls on _any_ class. This is provided by
|
* call, we need to be able to track such calls on _any_ class. This is provided by
|
||||||
* the member predicates of this QL class.
|
* the member predicates of this QL class.
|
||||||
*
|
*
|
||||||
@@ -1873,7 +1874,7 @@ module PrivateDjango {
|
|||||||
/** Gets a reference to this class. */
|
/** Gets a reference to this class. */
|
||||||
private DataFlow::TypeTrackingNode getARef(DataFlow::TypeTracker t) {
|
private DataFlow::TypeTrackingNode getARef(DataFlow::TypeTracker t) {
|
||||||
t.start() and
|
t.start() and
|
||||||
result.asExpr().(ClassExpr) = this.getParent()
|
result.asExpr() = this.getParent()
|
||||||
or
|
or
|
||||||
exists(DataFlow::TypeTracker t2 | result = this.getARef(t2).track(t2, t))
|
exists(DataFlow::TypeTracker t2 | result = this.getARef(t2).track(t2, t))
|
||||||
}
|
}
|
||||||
@@ -1973,7 +1974,7 @@ module PrivateDjango {
|
|||||||
/** Provides a class for modeling new django route handlers. */
|
/** Provides a class for modeling new django route handlers. */
|
||||||
module DjangoRouteHandler {
|
module DjangoRouteHandler {
|
||||||
/**
|
/**
|
||||||
* Extend this class to model new APIs. If you want to refine existing API models,
|
* A django route handler. Extend this class to model new APIs. If you want to refine existing API models,
|
||||||
* extend `DjangoRouteHandler` instead.
|
* extend `DjangoRouteHandler` instead.
|
||||||
*/
|
*/
|
||||||
abstract class Range extends Function { }
|
abstract class Range extends Function { }
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ module Flask {
|
|||||||
|
|
||||||
FlaskViewClass() {
|
FlaskViewClass() {
|
||||||
this.getABase() = Views::View::subclassRef().getAUse().asExpr() and
|
this.getABase() = Views::View::subclassRef().getAUse().asExpr() and
|
||||||
api_node.getAnImmediateUse().asExpr().(ClassExpr) = this.getParent()
|
api_node.getAnImmediateUse().asExpr() = this.getParent()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Gets a function that could handle incoming requests, if any. */
|
/** Gets a function that could handle incoming requests, if any. */
|
||||||
@@ -218,7 +218,7 @@ module Flask {
|
|||||||
class FlaskMethodViewClass extends FlaskViewClass {
|
class FlaskMethodViewClass extends FlaskViewClass {
|
||||||
FlaskMethodViewClass() {
|
FlaskMethodViewClass() {
|
||||||
this.getABase() = Views::MethodView::subclassRef().getAUse().asExpr() and
|
this.getABase() = Views::MethodView::subclassRef().getAUse().asExpr() and
|
||||||
api_node.getAnImmediateUse().asExpr().(ClassExpr) = this.getParent()
|
api_node.getAnImmediateUse().asExpr() = this.getParent()
|
||||||
}
|
}
|
||||||
|
|
||||||
override Function getARequestHandler() {
|
override Function getARequestHandler() {
|
||||||
@@ -299,7 +299,7 @@ module Flask {
|
|||||||
override Function getARequestHandler() {
|
override Function getARequestHandler() {
|
||||||
exists(DataFlow::LocalSourceNode func_src |
|
exists(DataFlow::LocalSourceNode func_src |
|
||||||
func_src.flowsTo(this.getViewArg()) and
|
func_src.flowsTo(this.getViewArg()) and
|
||||||
func_src.asExpr().(CallableExpr) = result.getDefinition()
|
func_src.asExpr() = result.getDefinition()
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(FlaskViewClass vc |
|
exists(FlaskViewClass vc |
|
||||||
|
|||||||
@@ -27,7 +27,10 @@ private module MySQLdb {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// MySQLdb
|
// MySQLdb
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** MySQLdb implements PEP 249, providing ways to execute SQL statements against a database. */
|
/**
|
||||||
|
* A model for MySQLdb as a module that implements PEP 249, providing ways to execute SQL statements
|
||||||
|
* against a database.
|
||||||
|
*/
|
||||||
class MySQLdb extends PEP249::PEP249ModuleApiNode {
|
class MySQLdb extends PEP249::PEP249ModuleApiNode {
|
||||||
MySQLdb() { this = API::moduleImport("MySQLdb") }
|
MySQLdb() { this = API::moduleImport("MySQLdb") }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,10 @@ private module Psycopg2 {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Psycopg
|
// Psycopg
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** psycopg2 implements PEP 249, providing ways to execute SQL statements against a database. */
|
/**
|
||||||
|
* A model of psycopg2 as a module that implements PEP 249, providing ways to execute SQL statements
|
||||||
|
* against a database.
|
||||||
|
*/
|
||||||
class Psycopg2 extends PEP249::PEP249ModuleApiNode {
|
class Psycopg2 extends PEP249::PEP249ModuleApiNode {
|
||||||
Psycopg2() { this = API::moduleImport("psycopg2") }
|
Psycopg2() { this = API::moduleImport("psycopg2") }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,10 @@ private import semmle.python.frameworks.PEP249
|
|||||||
* See https://pypi.org/project/PyMySQL/
|
* See https://pypi.org/project/PyMySQL/
|
||||||
*/
|
*/
|
||||||
private module PyMySQL {
|
private module PyMySQL {
|
||||||
/** PyMySQL implements PEP 249, providing ways to execute SQL statements against a database. */
|
/**
|
||||||
|
* A model of PyMySQL as a module that implements PEP 249, providing ways to execute SQL statements
|
||||||
|
* against a database.
|
||||||
|
*/
|
||||||
class PyMySQLPEP249 extends PEP249::PEP249ModuleApiNode {
|
class PyMySQLPEP249 extends PEP249::PEP249ModuleApiNode {
|
||||||
PyMySQLPEP249() { this = API::moduleImport("pymysql") }
|
PyMySQLPEP249() { this = API::moduleImport("pymysql") }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2341,7 +2341,8 @@ private module StdlibPrivate {
|
|||||||
// sqlite3
|
// sqlite3
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/**
|
/**
|
||||||
* sqlite3 implements PEP 249, providing ways to execute SQL statements against a database.
|
* A model of sqlite3 as a module that implements PEP 249, providing ways to execute SQL statements
|
||||||
|
* against a database.
|
||||||
*
|
*
|
||||||
* See https://devdocs.io/python~3.9/library/sqlite3
|
* See https://devdocs.io/python~3.9/library/sqlite3
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ private module Tornado {
|
|||||||
/** Gets a reference to this class. */
|
/** Gets a reference to this class. */
|
||||||
private DataFlow::TypeTrackingNode getARef(DataFlow::TypeTracker t) {
|
private DataFlow::TypeTrackingNode getARef(DataFlow::TypeTracker t) {
|
||||||
t.start() and
|
t.start() and
|
||||||
result.asExpr().(ClassExpr) = this.getParent()
|
result.asExpr() = this.getParent()
|
||||||
or
|
or
|
||||||
exists(DataFlow::TypeTracker t2 | result = this.getARef(t2).track(t2, t))
|
exists(DataFlow::TypeTracker t2 | result = this.getARef(t2).track(t2, t))
|
||||||
}
|
}
|
||||||
@@ -354,7 +354,7 @@ private module Tornado {
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// routing
|
// routing
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
/** A sequence that defines a number of route rules */
|
/** Gets a sequence that defines a number of route rules */
|
||||||
SequenceNode routeSetupRuleList() {
|
SequenceNode routeSetupRuleList() {
|
||||||
exists(CallNode call | call = any(tornado::web::Application::ClassInstantiation c).asCfgNode() |
|
exists(CallNode call | call = any(tornado::web::Application::ClassInstantiation c).asCfgNode() |
|
||||||
result in [call.getArg(0), call.getArgByName("handlers")]
|
result in [call.getArg(0), call.getArgByName("handlers")]
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ abstract class CallableObjectInternal extends ObjectInternal {
|
|||||||
override ObjectInternal getIterNext() { none() }
|
override ObjectInternal getIterNext() { none() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing Python functions */
|
/** A Python function. */
|
||||||
class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFunctionObject {
|
class PythonFunctionObjectInternal extends CallableObjectInternal, TPythonFunctionObject {
|
||||||
override Function getScope() {
|
override Function getScope() {
|
||||||
exists(CallableExpr expr |
|
exists(CallableExpr expr |
|
||||||
@@ -167,7 +167,7 @@ private BasicBlock blockReturningNone(Function func) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing built-in functions such as `len` or `print`. */
|
/** A built-in function such as `len` or `print`. */
|
||||||
class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunctionObject {
|
class BuiltinFunctionObjectInternal extends CallableObjectInternal, TBuiltinFunctionObject {
|
||||||
override Builtin getBuiltin() { this = TBuiltinFunctionObject(result) }
|
override Builtin getBuiltin() { this = TBuiltinFunctionObject(result) }
|
||||||
|
|
||||||
@@ -290,7 +290,7 @@ private Builtin getBuiltinFunctionReturnType(Builtin func) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing methods of built-in classes (otherwise known as method-descriptors) such as `list.append`. */
|
/** A method of a built-in class (otherwise known as method-descriptors) such as `list.append`. */
|
||||||
class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethodObject {
|
class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethodObject {
|
||||||
override Builtin getBuiltin() { this = TBuiltinMethodObject(result) }
|
override Builtin getBuiltin() { this = TBuiltinMethodObject(result) }
|
||||||
|
|
||||||
@@ -380,7 +380,7 @@ class BuiltinMethodObjectInternal extends CallableObjectInternal, TBuiltinMethod
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing bound-methods.
|
* A bound-method.
|
||||||
* Note that built-in methods, such as `[].append` are also represented as bound-methods.
|
* Note that built-in methods, such as `[].append` are also represented as bound-methods.
|
||||||
* Although built-in methods and bound-methods are distinct classes in CPython, their behavior
|
* Although built-in methods and bound-methods are distinct classes in CPython, their behavior
|
||||||
* is the same and we treat them identically.
|
* is the same and we treat them identically.
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ private import semmle.python.pointsto.PointsToContext
|
|||||||
private import semmle.python.pointsto.MRO
|
private import semmle.python.pointsto.MRO
|
||||||
private import semmle.python.types.Builtins
|
private import semmle.python.types.Builtins
|
||||||
|
|
||||||
/** Class representing classes */
|
/** A class. */
|
||||||
abstract class ClassObjectInternal extends ObjectInternal {
|
abstract class ClassObjectInternal extends ObjectInternal {
|
||||||
override string getName() { result = this.getClassDeclaration().getName() }
|
override string getName() { result = this.getClassDeclaration().getName() }
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ abstract class ClassObjectInternal extends ObjectInternal {
|
|||||||
override predicate isNotSubscriptedType() { any() }
|
override predicate isNotSubscriptedType() { any() }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing Python source classes */
|
/** A class that is defined in Python source. */
|
||||||
class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject {
|
class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject {
|
||||||
/** Gets the scope for this Python class */
|
/** Gets the scope for this Python class */
|
||||||
Class getScope() {
|
Class getScope() {
|
||||||
@@ -163,7 +163,7 @@ class PythonClassObjectInternal extends ClassObjectInternal, TPythonClassObject
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing built-in classes, except `type` */
|
/** A built-in class, except `type`. */
|
||||||
class BuiltinClassObjectInternal extends ClassObjectInternal, TBuiltinClassObject {
|
class BuiltinClassObjectInternal extends ClassObjectInternal, TBuiltinClassObject {
|
||||||
override Builtin getBuiltin() { this = TBuiltinClassObject(result) }
|
override Builtin getBuiltin() { this = TBuiltinClassObject(result) }
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ private import semmle.python.pointsto.PointsToContext
|
|||||||
private import semmle.python.types.Builtins
|
private import semmle.python.types.Builtins
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing constants.
|
* A constant.
|
||||||
* Includes `None`, `True` and `False` as
|
* Includes `None`, `True` and `False` as
|
||||||
* well as strings and integers.
|
* well as strings and integers.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ private import semmle.python.pointsto.PointsToContext
|
|||||||
private import semmle.python.pointsto.MRO
|
private import semmle.python.pointsto.MRO
|
||||||
private import semmle.python.types.Builtins
|
private import semmle.python.types.Builtins
|
||||||
|
|
||||||
/** Class representing property objects in Python */
|
/** A property object. */
|
||||||
class PropertyInternal extends ObjectInternal, TProperty {
|
class PropertyInternal extends ObjectInternal, TProperty {
|
||||||
/** Gets the name of this property */
|
/** Gets the name of this property */
|
||||||
override string getName() { result = this.getGetter().getName() }
|
override string getName() { result = this.getGetter().getName() }
|
||||||
|
|||||||
@@ -178,7 +178,6 @@ class SelfInstanceInternal extends TSelfInstance, InstanceObject {
|
|||||||
result = "self instance of " + this.getClass().(ClassObjectInternal).getName()
|
result = "self instance of " + this.getClass().(ClassObjectInternal).getName()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The boolean value of this object, if it has one */
|
|
||||||
override boolean booleanValue() {
|
override boolean booleanValue() {
|
||||||
//result = this.getClass().instancesBooleanValue()
|
//result = this.getClass().instancesBooleanValue()
|
||||||
result = maybe()
|
result = maybe()
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ class ClassScope = Class;
|
|||||||
class ModuleScope = Module;
|
class ModuleScope = Module;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing values in the Python program
|
* A value in the Python program.
|
||||||
* Each `Value` is a static approximation to a set of one or more real objects.
|
* Each `Value` is a static approximation to a set of one or more real objects.
|
||||||
*/
|
*/
|
||||||
class Value extends TObject {
|
class Value extends TObject {
|
||||||
@@ -144,7 +144,7 @@ class Value extends TObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing modules in the Python program
|
* A module in the Python program.
|
||||||
* Each `ModuleValue` represents a module object in the Python program.
|
* Each `ModuleValue` represents a module object in the Python program.
|
||||||
*/
|
*/
|
||||||
class ModuleValue extends Value instanceof ModuleObjectInternal {
|
class ModuleValue extends Value instanceof ModuleObjectInternal {
|
||||||
@@ -339,7 +339,7 @@ module Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing callables in the Python program
|
* A callable in the Python program.
|
||||||
* Callables include Python functions, built-in functions and bound-methods,
|
* Callables include Python functions, built-in functions and bound-methods,
|
||||||
* but not classes.
|
* but not classes.
|
||||||
*/
|
*/
|
||||||
@@ -447,7 +447,7 @@ class CallableValue extends Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing bound-methods, such as `o.func`, where `o` is an instance
|
* A bound-method, such as `o.func`, where `o` is an instance
|
||||||
* of a class that has a callable attribute `func`.
|
* of a class that has a callable attribute `func`.
|
||||||
*/
|
*/
|
||||||
class BoundMethodValue extends CallableValue instanceof BoundMethodObjectInternal {
|
class BoundMethodValue extends CallableValue instanceof BoundMethodObjectInternal {
|
||||||
@@ -468,7 +468,7 @@ class BoundMethodValue extends CallableValue instanceof BoundMethodObjectInterna
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing classes in the Python program, both Python and built-in.
|
* A class in the Python program, both Python and built-in.
|
||||||
*/
|
*/
|
||||||
class ClassValue extends Value {
|
class ClassValue extends Value {
|
||||||
ClassValue() { this.(ObjectInternal).isClass() = true }
|
ClassValue() { this.(ObjectInternal).isClass() = true }
|
||||||
@@ -655,7 +655,7 @@ class ClassValue extends Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class representing functions in the Python program, both Python and built-in.
|
* A function in the Python program, both Python and built-in.
|
||||||
* Note that this does not include other callables such as bound-methods.
|
* Note that this does not include other callables such as bound-methods.
|
||||||
*/
|
*/
|
||||||
abstract class FunctionValue extends CallableValue {
|
abstract class FunctionValue extends CallableValue {
|
||||||
@@ -721,7 +721,7 @@ abstract class FunctionValue extends CallableValue {
|
|||||||
predicate isLambda() { this.getOrigin().getNode() instanceof Lambda }
|
predicate isLambda() { this.getOrigin().getNode() instanceof Lambda }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing Python functions */
|
/** A Python function. */
|
||||||
class PythonFunctionValue extends FunctionValue {
|
class PythonFunctionValue extends FunctionValue {
|
||||||
PythonFunctionValue() { this instanceof PythonFunctionObjectInternal }
|
PythonFunctionValue() { this instanceof PythonFunctionObjectInternal }
|
||||||
|
|
||||||
@@ -769,7 +769,7 @@ class PythonFunctionValue extends FunctionValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing builtin functions, such as `len` or `print` */
|
/** A builtin function, such as `len` or `print`. */
|
||||||
class BuiltinFunctionValue extends FunctionValue {
|
class BuiltinFunctionValue extends FunctionValue {
|
||||||
BuiltinFunctionValue() { this instanceof BuiltinFunctionObjectInternal }
|
BuiltinFunctionValue() { this instanceof BuiltinFunctionObjectInternal }
|
||||||
|
|
||||||
@@ -796,7 +796,7 @@ class BuiltinFunctionValue extends FunctionValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Class representing builtin methods, such as `list.append` or `set.add` */
|
/** A builtin method, such as `list.append` or `set.add` */
|
||||||
class BuiltinMethodValue extends FunctionValue {
|
class BuiltinMethodValue extends FunctionValue {
|
||||||
BuiltinMethodValue() { this instanceof BuiltinMethodObjectInternal }
|
BuiltinMethodValue() { this instanceof BuiltinMethodObjectInternal }
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class ObjectInternal extends TObject {
|
|||||||
abstract string toString();
|
abstract string toString();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The boolean value of this object, this may be both
|
* Gets the boolean value of this object. This may be both
|
||||||
* true and false if the "object" represents a set of possible objects.
|
* true and false if the "object" represents a set of possible objects.
|
||||||
*/
|
*/
|
||||||
abstract boolean booleanValue();
|
abstract boolean booleanValue();
|
||||||
@@ -88,14 +88,14 @@ class ObjectInternal extends TObject {
|
|||||||
abstract predicate callResult(PointsToContext callee, ObjectInternal obj, CfgOrigin origin);
|
abstract predicate callResult(PointsToContext callee, ObjectInternal obj, CfgOrigin origin);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The integer value of things that have integer values and whose integer value is
|
* Gets the integer value of things that have integer values and whose integer value is
|
||||||
* tracked.
|
* tracked.
|
||||||
* That is, some ints, mainly small numbers, and bools.
|
* That is, some ints, mainly small numbers, and bools.
|
||||||
*/
|
*/
|
||||||
abstract int intValue();
|
abstract int intValue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The string value of things that have string values.
|
* Gets the string value of things that have string values.
|
||||||
* That is, strings.
|
* That is, strings.
|
||||||
*/
|
*/
|
||||||
abstract string strValue();
|
abstract string strValue();
|
||||||
@@ -497,7 +497,7 @@ module ObjectInternal {
|
|||||||
|
|
||||||
ObjectInternal superType() { result = TBuiltinClassObject(Builtin::special("super")) }
|
ObjectInternal superType() { result = TBuiltinClassObject(Builtin::special("super")) }
|
||||||
|
|
||||||
/** The old-style class type (Python 2 only) */
|
/** Gets the old-style class type (Python 2 only) */
|
||||||
ObjectInternal classType() { result = TBuiltinClassObject(Builtin::special("ClassType")) }
|
ObjectInternal classType() { result = TBuiltinClassObject(Builtin::special("ClassType")) }
|
||||||
|
|
||||||
ObjectInternal emptyTuple() { result.(BuiltinTupleObjectInternal).length() = 0 }
|
ObjectInternal emptyTuple() { result.(BuiltinTupleObjectInternal).length() = 0 }
|
||||||
|
|||||||
@@ -90,16 +90,8 @@ abstract class TupleObjectInternal extends SequenceObjectInternal {
|
|||||||
none()
|
none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The integer value of things that have integer values.
|
|
||||||
* That is, ints and bools.
|
|
||||||
*/
|
|
||||||
override int intValue() { none() }
|
override int intValue() { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* The integer value of things that have integer values.
|
|
||||||
* That is, strings.
|
|
||||||
*/
|
|
||||||
override string strValue() { none() }
|
override string strValue() { none() }
|
||||||
|
|
||||||
override predicate calleeAndOffset(Function scope, int paramOffset) { none() }
|
override predicate calleeAndOffset(Function scope, int paramOffset) { none() }
|
||||||
@@ -241,16 +233,8 @@ class SysVersionInfoObjectInternal extends TSysVersionInfo, SequenceObjectIntern
|
|||||||
none()
|
none()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* The integer value of things that have integer values.
|
|
||||||
* That is, ints and bools.
|
|
||||||
*/
|
|
||||||
override int intValue() { none() }
|
override int intValue() { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* The integer value of things that have integer values.
|
|
||||||
* That is, strings.
|
|
||||||
*/
|
|
||||||
override string strValue() { none() }
|
override string strValue() { none() }
|
||||||
|
|
||||||
override predicate calleeAndOffset(Function scope, int paramOffset) { none() }
|
override predicate calleeAndOffset(Function scope, int paramOffset) { none() }
|
||||||
@@ -261,10 +245,6 @@ class SysVersionInfoObjectInternal extends TSysVersionInfo, SequenceObjectIntern
|
|||||||
|
|
||||||
override predicate subscriptUnknown() { none() }
|
override predicate subscriptUnknown() { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the length of the sequence that this "object" represents.
|
|
||||||
* Always returns a value for a sequence, will be -1 if object has no fixed length.
|
|
||||||
*/
|
|
||||||
override int length() { result = 5 }
|
override int length() { result = 5 }
|
||||||
|
|
||||||
override predicate functionAndOffset(CallableObjectInternal function, int offset) { none() }
|
override predicate functionAndOffset(CallableObjectInternal function, int offset) { none() }
|
||||||
|
|||||||
@@ -453,7 +453,7 @@ predicate common_module_name(string name) { name = ["zope.interface", "six.moves
|
|||||||
* This acts as a helper for ClassObjectInternal allowing some lookup without
|
* This acts as a helper for ClassObjectInternal allowing some lookup without
|
||||||
* recursion.
|
* recursion.
|
||||||
*/
|
*/
|
||||||
library class ClassDecl extends @py_object {
|
class ClassDecl extends @py_object {
|
||||||
ClassDecl() {
|
ClassDecl() {
|
||||||
this.(Builtin).isClass() and not this = Builtin::unknownType()
|
this.(Builtin).isClass() and not this = Builtin::unknownType()
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ module BasePointsTo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The kwargs parameter (**kwargs) in a function definition is always a dict */
|
/** Gets the kwargs parameter (`**kwargs`). In a function definition this is always a dict. */
|
||||||
predicate kwargs_points_to(ControlFlowNode f, ClassObject cls) {
|
predicate kwargs_points_to(ControlFlowNode f, ClassObject cls) {
|
||||||
exists(Function func | func.getKwarg() = f.getNode()) and
|
exists(Function func | func.getKwarg() = f.getNode()) and
|
||||||
cls = theDictType()
|
cls = theDictType()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The varargs (*varargs) in a function definition is always a tuple */
|
/** Gets the varargs parameter (`*varargs`). In a function definition this is always a tuple. */
|
||||||
predicate varargs_points_to(ControlFlowNode f, ClassObject cls) {
|
predicate varargs_points_to(ControlFlowNode f, ClassObject cls) {
|
||||||
exists(Function func | func.getVararg() = f.getNode()) and
|
exists(Function func | func.getVararg() = f.getNode()) and
|
||||||
cls = theTupleType()
|
cls = theTupleType()
|
||||||
@@ -124,7 +124,7 @@ int version_tuple_compare(Object t) {
|
|||||||
predicate baseless_is_new_style(ClassObject cls) {
|
predicate baseless_is_new_style(ClassObject cls) {
|
||||||
cls.isBuiltin()
|
cls.isBuiltin()
|
||||||
or
|
or
|
||||||
major_version() = 3
|
major_version() = 3 and exists(cls)
|
||||||
or
|
or
|
||||||
exists(cls.declaredMetaClass())
|
exists(cls.declaredMetaClass())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,8 @@ private newtype TTInvocation =
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* A function invocation.
|
||||||
|
*
|
||||||
* This class represents a static approximation to the
|
* This class represents a static approximation to the
|
||||||
* dynamic call-graph. A `FunctionInvocation` represents
|
* dynamic call-graph. A `FunctionInvocation` represents
|
||||||
* all calls made to a function for a given context.
|
* all calls made to a function for a given context.
|
||||||
|
|||||||
@@ -329,7 +329,7 @@ private class ClassListList extends TClassListList {
|
|||||||
result = ConsList(removed_head, removed_tail)
|
result = ConsList(removed_head, removed_tail)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
this = EmptyList() and result = EmptyList()
|
this = EmptyList() and result = EmptyList() and exists(cls)
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ private import semmle.python.types.Builtins
|
|||||||
private import semmle.python.types.Extensions
|
private import semmle.python.types.Extensions
|
||||||
|
|
||||||
/* Use this version for speed */
|
/* Use this version for speed */
|
||||||
library class CfgOrigin extends @py_object {
|
class CfgOrigin extends @py_object {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
string toString() {
|
string toString() {
|
||||||
/* Not to be displayed */
|
/* Not to be displayed */
|
||||||
@@ -1076,7 +1076,7 @@ module InterProceduralPointsTo {
|
|||||||
/** Helper for default_parameter_points_to */
|
/** Helper for default_parameter_points_to */
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
private predicate context_for_default_value(ParameterDefinition def, PointsToContext context) {
|
private predicate context_for_default_value(ParameterDefinition def, PointsToContext context) {
|
||||||
context.isRuntime()
|
context.isRuntime() and exists(def)
|
||||||
or
|
or
|
||||||
exists(PointsToContext caller, CallNode call, PythonFunctionObjectInternal func, int n |
|
exists(PointsToContext caller, CallNode call, PythonFunctionObjectInternal func, int n |
|
||||||
context.fromCall(call, func, caller) and
|
context.fromCall(call, func, caller) and
|
||||||
@@ -2286,7 +2286,7 @@ module Types {
|
|||||||
func != six_add_metaclass_function() and result = false
|
func != six_add_metaclass_function() and result = false
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
not exists(Module m | m.getName() = "six") and result = false
|
not exists(Module m | m.getName() = "six") and result = false and exists(cls)
|
||||||
or
|
or
|
||||||
exists(Class pycls |
|
exists(Class pycls |
|
||||||
pycls = cls.getScope() and
|
pycls = cls.getScope() and
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ module Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Points-to context. Context can be one of:
|
* A points-to context. Context can be one of:
|
||||||
* * "main": Used for scripts.
|
* * "main": Used for scripts.
|
||||||
* * "import": Use for non-script modules.
|
* * "import": Use for non-script modules.
|
||||||
* * "default": Use for functions and methods without caller context.
|
* * "default": Use for functions and methods without caller context.
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ abstract deprecated class StringKind extends TaintKind {
|
|||||||
deprecated private class StringEqualitySanitizer extends Sanitizer {
|
deprecated private class StringEqualitySanitizer extends Sanitizer {
|
||||||
StringEqualitySanitizer() { this = "string equality sanitizer" }
|
StringEqualitySanitizer() { this = "string equality sanitizer" }
|
||||||
|
|
||||||
/** The test `if untrusted == "KNOWN_VALUE":` sanitizes `untrusted` on its `true` edge. */
|
/* The test `if untrusted == "KNOWN_VALUE":` sanitizes `untrusted` on its `true` edge. */
|
||||||
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
||||||
taint instanceof StringKind and
|
taint instanceof StringKind and
|
||||||
exists(ControlFlowNode const, Cmpop op | const.getNode() instanceof StrConst |
|
exists(ControlFlowNode const, Cmpop op | const.getNode() instanceof StrConst |
|
||||||
|
|||||||
@@ -79,18 +79,12 @@ deprecated class ExternalUrlSplitResult extends ExternalStringSequenceKind {
|
|||||||
override TaintKind getTaintOfAttribute(string name) {
|
override TaintKind getTaintOfAttribute(string name) {
|
||||||
result = super.getTaintOfAttribute(name)
|
result = super.getTaintOfAttribute(name)
|
||||||
or
|
or
|
||||||
(
|
name in [
|
||||||
// namedtuple field names
|
// namedtuple field names
|
||||||
name = "scheme" or
|
"scheme", "netloc", "path", "query", "fragment",
|
||||||
name = "netloc" or
|
// class methods
|
||||||
name = "path" or
|
"password", "username", "hostname",
|
||||||
name = "query" or
|
] and
|
||||||
name = "fragment" or
|
|
||||||
// class methods
|
|
||||||
name = "username" or
|
|
||||||
name = "password" or
|
|
||||||
name = "hostname"
|
|
||||||
) and
|
|
||||||
result instanceof ExternalStringKind
|
result instanceof ExternalStringKind
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -108,19 +102,12 @@ deprecated class ExternalUrlParseResult extends ExternalStringSequenceKind {
|
|||||||
override TaintKind getTaintOfAttribute(string name) {
|
override TaintKind getTaintOfAttribute(string name) {
|
||||||
result = super.getTaintOfAttribute(name)
|
result = super.getTaintOfAttribute(name)
|
||||||
or
|
or
|
||||||
(
|
name in [
|
||||||
// namedtuple field names
|
// namedtuple field names
|
||||||
name = "scheme" or
|
"scheme", "netloc", "path", "params", "query", "fragment",
|
||||||
name = "netloc" or
|
// class methods
|
||||||
name = "path" or
|
"username", "password", "hostname",
|
||||||
name = "params" or
|
] and
|
||||||
name = "query" or
|
|
||||||
name = "fragment" or
|
|
||||||
// class methods
|
|
||||||
name = "username" or
|
|
||||||
name = "password" or
|
|
||||||
name = "hostname"
|
|
||||||
) and
|
|
||||||
result instanceof ExternalStringKind
|
result instanceof ExternalStringKind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ class PyxlEndIfTag extends PyxlTag {
|
|||||||
class PyxlRawHtml extends PyxlTag {
|
class PyxlRawHtml extends PyxlTag {
|
||||||
PyxlRawHtml() { this.getPyxlTagName() = "rawhtml" }
|
PyxlRawHtml() { this.getPyxlTagName() = "rawhtml" }
|
||||||
|
|
||||||
/** The text for this raw html, if it is simple text. */
|
/** Gets the text for this raw html, if it is simple text. */
|
||||||
string getText() {
|
string getText() {
|
||||||
exists(Unicode text |
|
exists(Unicode text |
|
||||||
text = this.getValue() and
|
text = this.getValue() and
|
||||||
|
|||||||
@@ -63,13 +63,13 @@ class ClassObject extends Object {
|
|||||||
ClassObject getAnImproperSuperType() { result = this.getABaseType*() }
|
ClassObject getAnImproperSuperType() { result = this.getABaseType*() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this class is a new style class.
|
* Holds if this class is a new style class.
|
||||||
* A new style class is one that implicitly or explicitly inherits from `object`.
|
* A new style class is one that implicitly or explicitly inherits from `object`.
|
||||||
*/
|
*/
|
||||||
predicate isNewStyle() { Types::isNewStyle(this.theClass()) }
|
predicate isNewStyle() { Types::isNewStyle(this.theClass()) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether this class is an old style class.
|
* Holds if this class is an old style class.
|
||||||
* An old style class is one that does not inherit from `object`.
|
* An old style class is one that does not inherit from `object`.
|
||||||
*/
|
*/
|
||||||
predicate isOldStyle() { Types::isOldStyle(this.theClass()) }
|
predicate isOldStyle() { Types::isOldStyle(this.theClass()) }
|
||||||
@@ -357,7 +357,7 @@ class ClassObject extends Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The 'str' class. This is the same as the 'bytes' class for
|
* Gets the 'str' class. This is the same as the 'bytes' class for
|
||||||
* Python 2 and the 'unicode' class for Python 3
|
* Python 2 and the 'unicode' class for Python 3
|
||||||
*/
|
*/
|
||||||
ClassObject theStrType() {
|
ClassObject theStrType() {
|
||||||
@@ -375,128 +375,128 @@ ClassObject theAbcMetaClassObject() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Common builtin classes */
|
/* Common builtin classes */
|
||||||
/** The built-in class NoneType */
|
/** Gets the built-in class NoneType */
|
||||||
ClassObject theNoneType() { result.asBuiltin() = Builtin::special("NoneType") }
|
ClassObject theNoneType() { result.asBuiltin() = Builtin::special("NoneType") }
|
||||||
|
|
||||||
/** The built-in class 'bool' */
|
/** Gets the built-in class 'bool' */
|
||||||
ClassObject theBoolType() { result.asBuiltin() = Builtin::special("bool") }
|
ClassObject theBoolType() { result.asBuiltin() = Builtin::special("bool") }
|
||||||
|
|
||||||
/** The builtin class 'type' */
|
/** Gets the builtin class 'type' */
|
||||||
ClassObject theTypeType() { result.asBuiltin() = Builtin::special("type") }
|
ClassObject theTypeType() { result.asBuiltin() = Builtin::special("type") }
|
||||||
|
|
||||||
/** The builtin object ClassType (for old-style classes) */
|
/** Gets the builtin object ClassType (for old-style classes) */
|
||||||
ClassObject theClassType() { result.asBuiltin() = Builtin::special("ClassType") }
|
ClassObject theClassType() { result.asBuiltin() = Builtin::special("ClassType") }
|
||||||
|
|
||||||
/** The builtin object InstanceType (for old-style classes) */
|
/** Gets the builtin object InstanceType (for old-style classes) */
|
||||||
ClassObject theInstanceType() { result.asBuiltin() = Builtin::special("InstanceType") }
|
ClassObject theInstanceType() { result.asBuiltin() = Builtin::special("InstanceType") }
|
||||||
|
|
||||||
/** The builtin class 'tuple' */
|
/** Gets the builtin class 'tuple' */
|
||||||
ClassObject theTupleType() { result.asBuiltin() = Builtin::special("tuple") }
|
ClassObject theTupleType() { result.asBuiltin() = Builtin::special("tuple") }
|
||||||
|
|
||||||
/** The builtin class 'int' */
|
/** Gets the builtin class 'int' */
|
||||||
ClassObject theIntType() { result.asBuiltin() = Builtin::special("int") }
|
ClassObject theIntType() { result.asBuiltin() = Builtin::special("int") }
|
||||||
|
|
||||||
/** The builtin class 'long' (Python 2 only) */
|
/** Gets the builtin class 'long' (Python 2 only) */
|
||||||
ClassObject theLongType() { result.asBuiltin() = Builtin::special("long") }
|
ClassObject theLongType() { result.asBuiltin() = Builtin::special("long") }
|
||||||
|
|
||||||
/** The builtin class 'float' */
|
/** Gets the builtin class 'float' */
|
||||||
ClassObject theFloatType() { result.asBuiltin() = Builtin::special("float") }
|
ClassObject theFloatType() { result.asBuiltin() = Builtin::special("float") }
|
||||||
|
|
||||||
/** The builtin class 'complex' */
|
/** Gets the builtin class 'complex' */
|
||||||
ClassObject theComplexType() { result.asBuiltin() = Builtin::special("complex") }
|
ClassObject theComplexType() { result.asBuiltin() = Builtin::special("complex") }
|
||||||
|
|
||||||
/** The builtin class 'object' */
|
/** Gets the builtin class 'object' */
|
||||||
ClassObject theObjectType() { result.asBuiltin() = Builtin::special("object") }
|
ClassObject theObjectType() { result.asBuiltin() = Builtin::special("object") }
|
||||||
|
|
||||||
/** The builtin class 'list' */
|
/** Gets the builtin class 'list' */
|
||||||
ClassObject theListType() { result.asBuiltin() = Builtin::special("list") }
|
ClassObject theListType() { result.asBuiltin() = Builtin::special("list") }
|
||||||
|
|
||||||
/** The builtin class 'dict' */
|
/** Gets the builtin class 'dict' */
|
||||||
ClassObject theDictType() { result.asBuiltin() = Builtin::special("dict") }
|
ClassObject theDictType() { result.asBuiltin() = Builtin::special("dict") }
|
||||||
|
|
||||||
/** The builtin class 'Exception' */
|
/** Gets the builtin class 'Exception' */
|
||||||
ClassObject theExceptionType() { result.asBuiltin() = Builtin::special("Exception") }
|
ClassObject theExceptionType() { result.asBuiltin() = Builtin::special("Exception") }
|
||||||
|
|
||||||
/** The builtin class for unicode. unicode in Python2, str in Python3 */
|
/** Gets the builtin class for unicode. unicode in Python2, str in Python3 */
|
||||||
ClassObject theUnicodeType() { result.asBuiltin() = Builtin::special("unicode") }
|
ClassObject theUnicodeType() { result.asBuiltin() = Builtin::special("unicode") }
|
||||||
|
|
||||||
/** The builtin class '(x)range' */
|
/** Gets the builtin class '(x)range' */
|
||||||
ClassObject theRangeType() {
|
ClassObject theRangeType() {
|
||||||
result = Object::builtin("xrange")
|
result = Object::builtin("xrange")
|
||||||
or
|
or
|
||||||
major_version() = 3 and result = Object::builtin("range")
|
major_version() = 3 and result = Object::builtin("range")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The builtin class for bytes. str in Python2, bytes in Python3 */
|
/** Gets the builtin class for bytes. str in Python2, bytes in Python3 */
|
||||||
ClassObject theBytesType() { result.asBuiltin() = Builtin::special("bytes") }
|
ClassObject theBytesType() { result.asBuiltin() = Builtin::special("bytes") }
|
||||||
|
|
||||||
/** The builtin class 'set' */
|
/** Gets the builtin class 'set' */
|
||||||
ClassObject theSetType() { result.asBuiltin() = Builtin::special("set") }
|
ClassObject theSetType() { result.asBuiltin() = Builtin::special("set") }
|
||||||
|
|
||||||
/** The builtin class 'property' */
|
/** Gets the builtin class 'property' */
|
||||||
ClassObject thePropertyType() { result.asBuiltin() = Builtin::special("property") }
|
ClassObject thePropertyType() { result.asBuiltin() = Builtin::special("property") }
|
||||||
|
|
||||||
/** The builtin class 'BaseException' */
|
/** Gets the builtin class 'BaseException' */
|
||||||
ClassObject theBaseExceptionType() { result.asBuiltin() = Builtin::special("BaseException") }
|
ClassObject theBaseExceptionType() { result.asBuiltin() = Builtin::special("BaseException") }
|
||||||
|
|
||||||
/** The class of builtin-functions */
|
/** Gets the class of builtin-functions */
|
||||||
ClassObject theBuiltinFunctionType() {
|
ClassObject theBuiltinFunctionType() {
|
||||||
result.asBuiltin() = Builtin::special("BuiltinFunctionType")
|
result.asBuiltin() = Builtin::special("BuiltinFunctionType")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The class of Python functions */
|
/** Gets the class of Python functions */
|
||||||
ClassObject thePyFunctionType() { result.asBuiltin() = Builtin::special("FunctionType") }
|
ClassObject thePyFunctionType() { result.asBuiltin() = Builtin::special("FunctionType") }
|
||||||
|
|
||||||
/** The builtin class 'classmethod' */
|
/** Gets the builtin class 'classmethod' */
|
||||||
ClassObject theClassMethodType() { result.asBuiltin() = Builtin::special("ClassMethod") }
|
ClassObject theClassMethodType() { result.asBuiltin() = Builtin::special("ClassMethod") }
|
||||||
|
|
||||||
/** The builtin class 'staticmethod' */
|
/** Gets the builtin class 'staticmethod' */
|
||||||
ClassObject theStaticMethodType() { result.asBuiltin() = Builtin::special("StaticMethod") }
|
ClassObject theStaticMethodType() { result.asBuiltin() = Builtin::special("StaticMethod") }
|
||||||
|
|
||||||
/** The class of modules */
|
/** Gets the class of modules */
|
||||||
ClassObject theModuleType() { result.asBuiltin() = Builtin::special("ModuleType") }
|
ClassObject theModuleType() { result.asBuiltin() = Builtin::special("ModuleType") }
|
||||||
|
|
||||||
/** The class of generators */
|
/** Gets the class of generators */
|
||||||
ClassObject theGeneratorType() { result.asBuiltin() = Builtin::special("generator") }
|
ClassObject theGeneratorType() { result.asBuiltin() = Builtin::special("generator") }
|
||||||
|
|
||||||
/** The builtin class 'TypeError' */
|
/** Gets the builtin class 'TypeError' */
|
||||||
ClassObject theTypeErrorType() { result.asBuiltin() = Builtin::special("TypeError") }
|
ClassObject theTypeErrorType() { result.asBuiltin() = Builtin::special("TypeError") }
|
||||||
|
|
||||||
/** The builtin class 'AttributeError' */
|
/** Gets the builtin class 'AttributeError' */
|
||||||
ClassObject theAttributeErrorType() { result.asBuiltin() = Builtin::special("AttributeError") }
|
ClassObject theAttributeErrorType() { result.asBuiltin() = Builtin::special("AttributeError") }
|
||||||
|
|
||||||
/** The builtin class 'KeyError' */
|
/** Gets the builtin class 'KeyError' */
|
||||||
ClassObject theKeyErrorType() { result.asBuiltin() = Builtin::special("KeyError") }
|
ClassObject theKeyErrorType() { result.asBuiltin() = Builtin::special("KeyError") }
|
||||||
|
|
||||||
/** The builtin class of bound methods */
|
/** Gets the builtin class of bound methods */
|
||||||
pragma[noinline]
|
pragma[noinline]
|
||||||
ClassObject theBoundMethodType() { result.asBuiltin() = Builtin::special("MethodType") }
|
ClassObject theBoundMethodType() { result.asBuiltin() = Builtin::special("MethodType") }
|
||||||
|
|
||||||
/** The builtin class of builtin properties */
|
/** Gets the builtin class of builtin properties */
|
||||||
ClassObject theGetSetDescriptorType() {
|
ClassObject theGetSetDescriptorType() {
|
||||||
result.asBuiltin() = Builtin::special("GetSetDescriptorType")
|
result.asBuiltin() = Builtin::special("GetSetDescriptorType")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The method descriptor class */
|
/** Gets the method descriptor class */
|
||||||
ClassObject theMethodDescriptorType() {
|
ClassObject theMethodDescriptorType() {
|
||||||
result.asBuiltin() = Builtin::special("MethodDescriptorType")
|
result.asBuiltin() = Builtin::special("MethodDescriptorType")
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The class of builtin properties */
|
/** Gets the class of builtin properties */
|
||||||
ClassObject theBuiltinPropertyType() {
|
ClassObject theBuiltinPropertyType() {
|
||||||
/* This is CPython specific */
|
/* This is CPython specific */
|
||||||
result.isC() and
|
result.isC() and
|
||||||
result.getName() = "getset_descriptor"
|
result.getName() = "getset_descriptor"
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The builtin class 'IOError' */
|
/** Gets the builtin class 'IOError' */
|
||||||
ClassObject theIOErrorType() { result = Object::builtin("IOError") }
|
ClassObject theIOErrorType() { result = Object::builtin("IOError") }
|
||||||
|
|
||||||
/** The builtin class 'super' */
|
/** Gets the builtin class 'super' */
|
||||||
ClassObject theSuperType() { result = Object::builtin("super") }
|
ClassObject theSuperType() { result = Object::builtin("super") }
|
||||||
|
|
||||||
/** The builtin class 'StopIteration' */
|
/** Gets the builtin class 'StopIteration' */
|
||||||
ClassObject theStopIterationType() { result = Object::builtin("StopIteration") }
|
ClassObject theStopIterationType() { result = Object::builtin("StopIteration") }
|
||||||
|
|
||||||
/** The builtin class 'NotImplementedError' */
|
/** Gets the builtin class 'NotImplementedError' */
|
||||||
ClassObject theNotImplementedErrorType() { result = Object::builtin("NotImplementedError") }
|
ClassObject theNotImplementedErrorType() { result = Object::builtin("NotImplementedError") }
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
|
|
||||||
import python
|
import python
|
||||||
|
|
||||||
/** Subset of ControlFlowNodes which might raise an exception */
|
/** The subset of ControlFlowNodes which might raise an exception */
|
||||||
class RaisingNode extends ControlFlowNode {
|
class RaisingNode extends ControlFlowNode {
|
||||||
RaisingNode() {
|
RaisingNode() {
|
||||||
exists(this.getAnExceptionalSuccessor())
|
exists(this.getAnExceptionalSuccessor())
|
||||||
@@ -363,7 +363,7 @@ predicate scope_raises_unknown(Scope s) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** ControlFlowNode for an 'except' statement. */
|
/** The ControlFlowNode for an 'except' statement. */
|
||||||
class ExceptFlowNode extends ControlFlowNode {
|
class ExceptFlowNode extends ControlFlowNode {
|
||||||
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
|
ExceptFlowNode() { this.getNode() instanceof ExceptStmt }
|
||||||
|
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ abstract deprecated class CustomPointsToAttribute extends Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* An example */
|
/* An example */
|
||||||
/** Any variable iterating over range or xrange must be an integer */
|
/** An extension representing the fact that a variable iterating over range or xrange must be an integer */
|
||||||
class RangeIterationVariableFact extends PointsToExtension {
|
class RangeIterationVariableFact extends PointsToExtension {
|
||||||
RangeIterationVariableFact() {
|
RangeIterationVariableFact() {
|
||||||
exists(For f, ControlFlowNode iterable |
|
exists(For f, ControlFlowNode iterable |
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ private predicate is_an_object(@py_object obj) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* An object.
|
||||||
|
*
|
||||||
* Instances of this class represent objects in the Python program. However, since
|
* Instances of this class represent objects in the Python program. However, since
|
||||||
* the QL database is static and Python programs are dynamic, there are necessarily a
|
* the QL database is static and Python programs are dynamic, there are necessarily a
|
||||||
* number of approximations.
|
* number of approximations.
|
||||||
@@ -138,7 +140,7 @@ class Object extends @py_object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Boolean value of this object if it always evaluates to true or false.
|
* Gets the Boolean value of this object if it always evaluates to true or false.
|
||||||
* For example:
|
* For example:
|
||||||
* false for None, true for 7 and no result for int(x)
|
* false for None, true for 7 and no result for int(x)
|
||||||
*/
|
*/
|
||||||
@@ -217,7 +219,7 @@ private Object findByName3(string longName) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Numeric objects (ints and floats).
|
* A numeric object (int or float).
|
||||||
* Includes those occurring in the source as a literal
|
* Includes those occurring in the source as a literal
|
||||||
* or in a builtin module as a value.
|
* or in a builtin module as a value.
|
||||||
*/
|
*/
|
||||||
@@ -269,7 +271,7 @@ class NumericObject extends Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* String objects (unicode or bytes).
|
* A string object (unicode or bytes).
|
||||||
* Includes those occurring in the source as a literal
|
* Includes those occurring in the source as a literal
|
||||||
* or in a builtin module as a value.
|
* or in a builtin module as a value.
|
||||||
*/
|
*/
|
||||||
@@ -299,7 +301,7 @@ class StringObject extends Object {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sequence objects (lists and tuples)
|
* A sequence object (list or tuple)
|
||||||
* Includes those occurring in the source as a literal
|
* Includes those occurring in the source as a literal
|
||||||
* or in a builtin module as a value.
|
* or in a builtin module as a value.
|
||||||
*/
|
*/
|
||||||
@@ -358,34 +360,34 @@ class ListObject extends SequenceObject {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The `builtin` module */
|
/** Gets the `builtin` module */
|
||||||
BuiltinModuleObject theBuiltinModuleObject() { result.asBuiltin() = Builtin::builtinModule() }
|
BuiltinModuleObject theBuiltinModuleObject() { result.asBuiltin() = Builtin::builtinModule() }
|
||||||
|
|
||||||
/** The `sys` module */
|
/** Gets the `sys` module */
|
||||||
BuiltinModuleObject theSysModuleObject() { result.asBuiltin() = Builtin::special("sys") }
|
BuiltinModuleObject theSysModuleObject() { result.asBuiltin() = Builtin::special("sys") }
|
||||||
|
|
||||||
/** DEPRECATED -- Use `Object::builtin(name)` instead. */
|
/** DEPRECATED -- Use `Object::builtin(name)` instead. */
|
||||||
deprecated Object builtin_object(string name) { result = Object::builtin(name) }
|
deprecated Object builtin_object(string name) { result = Object::builtin(name) }
|
||||||
|
|
||||||
/** The built-in object None */
|
/** Gets the built-in object None */
|
||||||
Object theNoneObject() { result.asBuiltin() = Builtin::special("None") }
|
Object theNoneObject() { result.asBuiltin() = Builtin::special("None") }
|
||||||
|
|
||||||
/** The built-in object True */
|
/** Gets the built-in object True */
|
||||||
Object theTrueObject() { result.asBuiltin() = Builtin::special("True") }
|
Object theTrueObject() { result.asBuiltin() = Builtin::special("True") }
|
||||||
|
|
||||||
/** The built-in object False */
|
/** Gets the built-in object False */
|
||||||
Object theFalseObject() { result.asBuiltin() = Builtin::special("False") }
|
Object theFalseObject() { result.asBuiltin() = Builtin::special("False") }
|
||||||
|
|
||||||
/** The NameError class */
|
/** Gets the NameError class */
|
||||||
Object theNameErrorType() { result = Object::builtin("NameError") }
|
Object theNameErrorType() { result = Object::builtin("NameError") }
|
||||||
|
|
||||||
/** The StandardError class */
|
/** Gets the StandardError class */
|
||||||
Object theStandardErrorType() { result = Object::builtin("StandardError") }
|
Object theStandardErrorType() { result = Object::builtin("StandardError") }
|
||||||
|
|
||||||
/** The IndexError class */
|
/** Gets the IndexError class */
|
||||||
Object theIndexErrorType() { result = Object::builtin("IndexError") }
|
Object theIndexErrorType() { result = Object::builtin("IndexError") }
|
||||||
|
|
||||||
/** The LookupError class */
|
/** Gets the LookupError class */
|
||||||
Object theLookupErrorType() { result = Object::builtin("LookupError") }
|
Object theLookupErrorType() { result = Object::builtin("LookupError") }
|
||||||
|
|
||||||
/** DEPRECATED -- Use `Object::quitter(name)` instead. */
|
/** DEPRECATED -- Use `Object::quitter(name)` instead. */
|
||||||
@@ -400,13 +402,13 @@ deprecated Object theEmptyTupleObject() { result = TupleObject::empty() }
|
|||||||
module Object {
|
module Object {
|
||||||
Object builtin(string name) { result.asBuiltin() = Builtin::builtin(name) }
|
Object builtin(string name) { result.asBuiltin() = Builtin::builtin(name) }
|
||||||
|
|
||||||
/** The named quitter object (quit or exit) in the builtin namespace */
|
/** Gets the named quitter object (quit or exit) in the builtin namespace */
|
||||||
Object quitter(string name) {
|
Object quitter(string name) {
|
||||||
(name = "quit" or name = "exit") and
|
(name = "quit" or name = "exit") and
|
||||||
result = builtin(name)
|
result = builtin(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The builtin object `NotImplemented`. Not be confused with `NotImplementedError`. */
|
/** Gets the builtin object `NotImplemented`. Not be confused with `NotImplementedError`. */
|
||||||
Object notImplemented() { result = builtin("NotImplemented") }
|
Object notImplemented() { result = builtin("NotImplemented") }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import python
|
|||||||
import semmle.python.web.Http
|
import semmle.python.web.Http
|
||||||
import semmle.python.types.Extensions
|
import semmle.python.types.Extensions
|
||||||
|
|
||||||
/** The bottle module */
|
/** Gets the bottle module */
|
||||||
deprecated ModuleValue theBottleModule() { result = Module::named("bottle") }
|
deprecated ModuleValue theBottleModule() { result = Module::named("bottle") }
|
||||||
|
|
||||||
/** The bottle.Bottle class */
|
/** Gets the bottle.Bottle class */
|
||||||
deprecated ClassValue theBottleClass() { result = theBottleModule().attr("Bottle") }
|
deprecated ClassValue theBottleClass() { result = theBottleModule().attr("Bottle") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import semmle.python.web.bottle.General
|
|||||||
deprecated FunctionValue bottle_redirect() { result = theBottleModule().attr("redirect") }
|
deprecated FunctionValue bottle_redirect() { result = theBottleModule().attr("redirect") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents an argument to the `bottle.redirect` function.
|
* An argument to the `bottle.redirect` function.
|
||||||
*/
|
*/
|
||||||
deprecated class BottleRedirect extends TaintSink {
|
deprecated class BottleRedirect extends TaintSink {
|
||||||
override string toString() { result = "bottle.redirect" }
|
override string toString() { result = "bottle.redirect" }
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ deprecated class UntrustedFile extends TaintKind {
|
|||||||
// TO DO.. File uploads -- Should check about file uploads for other frameworks as well.
|
// TO DO.. File uploads -- Should check about file uploads for other frameworks as well.
|
||||||
// Move UntrustedFile to shared location
|
// Move UntrustedFile to shared location
|
||||||
//
|
//
|
||||||
/** Parameter to a bottle request handler function */
|
/** A parameter to a bottle request handler function */
|
||||||
deprecated class BottleRequestParameter extends HttpRequestTaintSource {
|
deprecated class BottleRequestParameter extends HttpRequestTaintSource {
|
||||||
BottleRequestParameter() {
|
BottleRequestParameter() {
|
||||||
exists(BottleRoute route | route.getANamedArgument() = this.(ControlFlowNode).getNode())
|
exists(BottleRoute route | route.getANamedArgument() = this.(ControlFlowNode).getNode())
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import python
|
import python
|
||||||
import semmle.python.web.Http
|
import semmle.python.web.Http
|
||||||
|
|
||||||
/** The falcon API class */
|
/** Gets the falcon API class */
|
||||||
deprecated ClassValue theFalconAPIClass() { result = Value::named("falcon.API") }
|
deprecated ClassValue theFalconAPIClass() { result = Value::named("falcon.API") }
|
||||||
|
|
||||||
/** Holds if `route` is routed to `resource` */
|
/** Holds if `route` is routed to `resource` */
|
||||||
|
|||||||
@@ -2,10 +2,10 @@ import python
|
|||||||
import semmle.python.web.Http
|
import semmle.python.web.Http
|
||||||
import semmle.python.web.flask.Response
|
import semmle.python.web.flask.Response
|
||||||
|
|
||||||
/** The flask app class */
|
/** Gets the flask app class */
|
||||||
deprecated ClassValue theFlaskClass() { result = Value::named("flask.Flask") }
|
deprecated ClassValue theFlaskClass() { result = Value::named("flask.Flask") }
|
||||||
|
|
||||||
/** The flask MethodView class */
|
/** Gets the flask MethodView class */
|
||||||
deprecated ClassValue theFlaskMethodViewClass() { result = Value::named("flask.views.MethodView") }
|
deprecated ClassValue theFlaskMethodViewClass() { result = Value::named("flask.views.MethodView") }
|
||||||
|
|
||||||
deprecated ClassValue theFlaskReponseClass() { result = Value::named("flask.Response") }
|
deprecated ClassValue theFlaskReponseClass() { result = Value::named("flask.Response") }
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import python
|
import python
|
||||||
private import semmle.python.pointsto.PointsTo
|
private import semmle.python.pointsto.PointsTo
|
||||||
|
|
||||||
/** Helper class for UndefinedClassAttribute.ql and MaybeUndefinedClassAttribute.ql */
|
/** A helper class for UndefinedClassAttribute.ql and MaybeUndefinedClassAttribute.ql */
|
||||||
class CheckClass extends ClassObject {
|
class CheckClass extends ClassObject {
|
||||||
private predicate ofInterest() {
|
private predicate ofInterest() {
|
||||||
not this.unknowableAttributes() and
|
not this.unknowableAttributes() and
|
||||||
|
|||||||
@@ -32,7 +32,11 @@ 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. */
|
/**
|
||||||
|
* Holds if `iterator` is not exhausted.
|
||||||
|
*
|
||||||
|
* The pattern `next(iter(x))` is often used where `x` is known not be empty. Check for that.
|
||||||
|
*/
|
||||||
predicate iter_not_exhausted(EssaVariable iterator) {
|
predicate iter_not_exhausted(EssaVariable iterator) {
|
||||||
exists(EssaVariable sequence |
|
exists(EssaVariable sequence |
|
||||||
call_to_iter(iterator.getDefinition().(AssignmentDefinition).getValue(), sequence) and
|
call_to_iter(iterator.getDefinition().(AssignmentDefinition).getValue(), sequence) and
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import python
|
import python
|
||||||
|
|
||||||
/** A string constant that looks like it may be used in string formatting operations. */
|
/** A string constant that looks like it may be used in string formatting operations. */
|
||||||
library class PossibleAdvancedFormatString extends StrConst {
|
class PossibleAdvancedFormatString extends StrConst {
|
||||||
PossibleAdvancedFormatString() { this.getText().matches("%{%}%") }
|
PossibleAdvancedFormatString() { this.getText().matches("%{%}%") }
|
||||||
|
|
||||||
private predicate field(int start, int end) {
|
private predicate field(int start, int end) {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
import python
|
import python
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The module `name` was deprecated in Python version `major`.`minor`,
|
* Holds if the module `name` was deprecated in Python version `major`.`minor`,
|
||||||
* and module `instead` should be used instead (or `instead = "no replacement"`)
|
* and module `instead` should be used instead (or `instead = "no replacement"`)
|
||||||
*/
|
*/
|
||||||
predicate deprecated_module(string name, string instead, int major, int minor) {
|
predicate deprecated_module(string name, string instead, int major, int minor) {
|
||||||
|
|||||||
@@ -178,7 +178,7 @@ class CommentedOutCodeBlock extends @py_comment {
|
|||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
string toString() { result = "Commented out code" }
|
string toString() { result = "Commented out code" }
|
||||||
|
|
||||||
/** Whether this commented-out code block contains the comment c */
|
/** Holds if this commented-out code block contains the comment c */
|
||||||
predicate contains(Comment c) {
|
predicate contains(Comment c) {
|
||||||
this = c
|
this = c
|
||||||
or
|
or
|
||||||
@@ -189,7 +189,7 @@ class CommentedOutCodeBlock extends @py_comment {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** The length of this comment block (in comments) */
|
/** Gets the length of this comment block (in comments) */
|
||||||
int length() { result = count(Comment c | this.contains(c)) }
|
int length() { result = count(Comment c | this.contains(c)) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class ExtractMembersSink extends TaintSink {
|
|||||||
class TarFileInfoSanitizer extends Sanitizer {
|
class TarFileInfoSanitizer extends Sanitizer {
|
||||||
TarFileInfoSanitizer() { this = "TarInfo sanitizer" }
|
TarFileInfoSanitizer() { this = "TarInfo sanitizer" }
|
||||||
|
|
||||||
/** The test `if <path_sanitizing_test>:` clears taint on its `false` edge. */
|
/* The test `if <path_sanitizing_test>:` clears taint on its `false` edge. */
|
||||||
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
||||||
taint instanceof TarFileInfo and
|
taint instanceof TarFileInfo and
|
||||||
clears_taint_on_false_edge(test.getTest(), test.getSense())
|
clears_taint_on_false_edge(test.getTest(), test.getSense())
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ abstract class TlsLibrary extends string {
|
|||||||
bindingset[this]
|
bindingset[this]
|
||||||
TlsLibrary() { any() }
|
TlsLibrary() { any() }
|
||||||
|
|
||||||
/** The name of a specific protocol version. */
|
/** Gets the name of a specific protocol version. */
|
||||||
abstract string specific_version_name(ProtocolVersion version);
|
abstract string specific_version_name(ProtocolVersion version);
|
||||||
|
|
||||||
/** Gets a name, which is a member of `version_constants`, that can be used to specify the protocol family `family`. */
|
/** Gets a name, which is a member of `version_constants`, that can be used to specify the protocol family `family`. */
|
||||||
|
|||||||
@@ -5,12 +5,12 @@ import python
|
|||||||
*/
|
*/
|
||||||
class Definition extends NameNode, DefinitionNode {
|
class Definition extends NameNode, DefinitionNode {
|
||||||
/**
|
/**
|
||||||
* The variable defined by this control-flow node.
|
* Gets the variable defined by this control-flow node.
|
||||||
*/
|
*/
|
||||||
Variable getVariable() { this.defines(result) }
|
Variable getVariable() { this.defines(result) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The SSA variable corresponding to the current definition. Since SSA variables
|
* Gets the SSA variable corresponding to the current definition. Since SSA variables
|
||||||
* are only generated for definitions with at least one use, not all definitions
|
* are only generated for definitions with at least one use, not all definitions
|
||||||
* will have an SSA variable.
|
* will have an SSA variable.
|
||||||
*/
|
*/
|
||||||
@@ -67,7 +67,7 @@ class Definition extends NameNode, DefinitionNode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An immediate re-definition of this definition's variable.
|
* Gets an immediate re-definition of this definition's variable.
|
||||||
*/
|
*/
|
||||||
Definition getARedef() {
|
Definition getARedef() {
|
||||||
result != this and
|
result != this and
|
||||||
|
|||||||
@@ -47,6 +47,8 @@ predicate simple_literal(Expr e) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Holds if the redefinition is uninteresting.
|
||||||
|
*
|
||||||
* A multiple definition is 'uninteresting' if it sets a variable to a
|
* A multiple definition is 'uninteresting' if it sets a variable to a
|
||||||
* simple literal before reassigning it.
|
* simple literal before reassigning it.
|
||||||
* x = None
|
* x = None
|
||||||
|
|||||||
@@ -17,30 +17,13 @@ import Shadowing
|
|||||||
import semmle.python.types.Builtins
|
import semmle.python.types.Builtins
|
||||||
|
|
||||||
predicate allow_list(string name) {
|
predicate allow_list(string name) {
|
||||||
/* These are rarely used and thus unlikely to be confusing */
|
name in [
|
||||||
name = "iter" or
|
/* These are rarely used and thus unlikely to be confusing */
|
||||||
name = "next" or
|
"iter", "next", "input", "file", "apply", "slice", "buffer", "coerce", "intern", "exit",
|
||||||
name = "input" or
|
"quit", "license",
|
||||||
name = "file" or
|
/* These are short and/or hard to avoid */
|
||||||
name = "apply" or
|
"dir", "id", "max", "min", "sum", "cmp", "chr", "ord", "bytes", "_",
|
||||||
name = "slice" or
|
]
|
||||||
name = "buffer" or
|
|
||||||
name = "coerce" or
|
|
||||||
name = "intern" or
|
|
||||||
name = "exit" or
|
|
||||||
name = "quit" or
|
|
||||||
name = "license" or
|
|
||||||
/* These are short and/or hard to avoid */
|
|
||||||
name = "dir" or
|
|
||||||
name = "id" or
|
|
||||||
name = "max" or
|
|
||||||
name = "min" or
|
|
||||||
name = "sum" or
|
|
||||||
name = "cmp" or
|
|
||||||
name = "chr" or
|
|
||||||
name = "ord" or
|
|
||||||
name = "bytes" or
|
|
||||||
name = "_"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate shadows(Name d, string name, Function scope, int line) {
|
predicate shadows(Name d, string name, Function scope, int line) {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import python
|
|||||||
import Loop
|
import Loop
|
||||||
import semmle.python.dataflow.TaintTracking
|
import semmle.python.dataflow.TaintTracking
|
||||||
|
|
||||||
/** Marker for "uninitialized". */
|
/** A marker for "uninitialized". */
|
||||||
class Uninitialized extends TaintKind {
|
class Uninitialized extends TaintKind {
|
||||||
Uninitialized() { this = "undefined" }
|
Uninitialized() { this = "undefined" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -467,10 +467,10 @@ Definition getUniqueDefinition(Expr use) {
|
|||||||
not result = TLocalDefinition(use)
|
not result = TLocalDefinition(use)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Helper class to get suitable locations for attributes */
|
/** A helper class to get suitable locations for attributes */
|
||||||
class NiceLocationExpr extends @py_expr {
|
class NiceLocationExpr extends Expr {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
string toString() { result = this.(Expr).toString() }
|
override string toString() { result = this.(Expr).toString() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if this element is at the specified location.
|
* Holds if this element is at the specified location.
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ predicate ok_to_fail(ImportExpr ie) {
|
|||||||
os_specific_import(ie) != get_os()
|
os_specific_import(ie) != get_os()
|
||||||
}
|
}
|
||||||
|
|
||||||
class VersionTest extends @py_flow_node {
|
class VersionTest extends ControlFlowNode {
|
||||||
VersionTest() {
|
VersionTest() {
|
||||||
exists(string name |
|
exists(string name |
|
||||||
name.matches("%version%") and
|
name.matches("%version%") and
|
||||||
@@ -66,7 +66,7 @@ class VersionTest extends @py_flow_node {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
string toString() { result = "VersionTest" }
|
override string toString() { result = "VersionTest" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** A guard on the version of the Python interpreter */
|
/** A guard on the version of the Python interpreter */
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import ClientSuppliedIpUsedInSecurityCheckLib
|
|||||||
import DataFlow::PathGraph
|
import DataFlow::PathGraph
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Taint-tracking configuration tracing flow from obtaining a client ip from an HTTP header to a sensitive use.
|
* A taint-tracking configuration tracing flow from obtaining a client ip from an HTTP header to a sensitive use.
|
||||||
*/
|
*/
|
||||||
class ClientSuppliedIpUsedInSecurityCheckConfig extends TaintTracking::Configuration {
|
class ClientSuppliedIpUsedInSecurityCheckConfig extends TaintTracking::Configuration {
|
||||||
ClientSuppliedIpUsedInSecurityCheckConfig() { this = "ClientSuppliedIpUsedInSecurityCheckConfig" }
|
ClientSuppliedIpUsedInSecurityCheckConfig() { this = "ClientSuppliedIpUsedInSecurityCheckConfig" }
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import experimental.semmle.python.templates.SSTISink
|
|||||||
deprecated ClassValue theAirspeedTemplateClass() { result = Value::named("airspeed.Template") }
|
deprecated ClassValue theAirspeedTemplateClass() { result = Value::named("airspeed.Template") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `airspeed.Template` class instantiation argument.
|
* A sink representing the `airspeed.Template` class instantiation argument.
|
||||||
*
|
*
|
||||||
* import airspeed
|
* import airspeed
|
||||||
* temp = airspeed.Template(`"sink"`)
|
* temp = airspeed.Template(`"sink"`)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ deprecated ClassValue theBottleSimpleTemplateClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `bottle.SimpleTemplate` class instantiation argument.
|
* A sink representing the `bottle.SimpleTemplate` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from bottle import SimpleTemplate
|
* from bottle import SimpleTemplate
|
||||||
* template = SimpleTemplate(`sink`)
|
* template = SimpleTemplate(`sink`)
|
||||||
@@ -29,7 +29,7 @@ deprecated class BottleSimpleTemplateSink extends SSTISink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `bottle.template` function call argument.
|
* A sink representing the `bottle.template` function call argument.
|
||||||
*
|
*
|
||||||
* from bottle import template
|
* from bottle import template
|
||||||
* tmp = template(`sink`)
|
* tmp = template(`sink`)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ deprecated ClassValue theChameleonPageTemplateClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `chameleon.PageTemplate` class instantiation argument.
|
* A sink representing the `chameleon.PageTemplate` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from chameleon import PageTemplate
|
* from chameleon import PageTemplate
|
||||||
* template = PageTemplate(`sink`)
|
* template = PageTemplate(`sink`)
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ deprecated ClassValue theCheetahTemplateClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the instantiation argument of any class which derives from
|
* A sink representing the instantiation argument of any class which derives from
|
||||||
* the `Cheetah.Template.Template` class .
|
* the `Cheetah.Template.Template` class .
|
||||||
*
|
*
|
||||||
* from Cheetah.Template import Template
|
* from Cheetah.Template import Template
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import experimental.semmle.python.templates.SSTISink
|
|||||||
deprecated Value theChevronRenderFunc() { result = Value::named("chevron.render") }
|
deprecated Value theChevronRenderFunc() { result = Value::named("chevron.render") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `chevron.render` function call argument.
|
* A sink representing the `chevron.render` function call argument.
|
||||||
*
|
*
|
||||||
* import chevron
|
* import chevron
|
||||||
* tmp = chevron.render(`sink`,{ 'key' : 'value' })
|
* tmp = chevron.render(`sink`,{ 'key' : 'value' })
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import experimental.semmle.python.templates.SSTISink
|
|||||||
deprecated ClassValue theDjangoTemplateClass() { result = Value::named("django.template.Template") }
|
deprecated ClassValue theDjangoTemplateClass() { result = Value::named("django.template.Template") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representng `django.template.Template` class instantiation argument.
|
* A sink representng `django.template.Template` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from django.template import Template
|
* from django.template import Template
|
||||||
* template = Template(`sink`)
|
* template = Template(`sink`)
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ deprecated Value theFlaskRenderTemplateClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representng `flask.render_template_string` function call argument.
|
* A sink representng `flask.render_template_string` function call argument.
|
||||||
*
|
*
|
||||||
* from flask import render_template_string
|
* from flask import render_template_string
|
||||||
* render_template_string(`sink`)
|
* render_template_string(`sink`)
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ deprecated ClassValue theGenshiMarkupTemplateClass() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `genshi.template.TextTemplate` class instantiation argument.
|
* A sink representing the `genshi.template.TextTemplate` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from genshi.template import TextTemplate
|
* from genshi.template import TextTemplate
|
||||||
* tmpl = TextTemplate('sink')
|
* tmpl = TextTemplate('sink')
|
||||||
@@ -34,7 +34,7 @@ deprecated class GenshiTextTemplateSink extends SSTISink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `genshi.template.MarkupTemplate` class instantiation argument.
|
* A sink representing the `genshi.template.MarkupTemplate` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from genshi.template import MarkupTemplate
|
* from genshi.template import MarkupTemplate
|
||||||
* tmpl = MarkupTemplate('sink')
|
* tmpl = MarkupTemplate('sink')
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ deprecated ClassValue theJinja2TemplateClass() { result = Value::named("jinja2.T
|
|||||||
deprecated Value theJinja2FromStringValue() { result = Value::named("jinja2.from_string") }
|
deprecated Value theJinja2FromStringValue() { result = Value::named("jinja2.from_string") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `jinja2.Template` class instantiation argument.
|
* A sink representing the `jinja2.Template` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from jinja2 import Template
|
* from jinja2 import Template
|
||||||
* template = Template(`sink`)
|
* template = Template(`sink`)
|
||||||
@@ -30,7 +30,7 @@ deprecated class Jinja2TemplateSink extends SSTISink {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `jinja2.from_string` function call argument.
|
* A sink representing the `jinja2.from_string` function call argument.
|
||||||
*
|
*
|
||||||
* from jinja2 import from_string
|
* from jinja2 import from_string
|
||||||
* template = from_string(`sink`)
|
* template = from_string(`sink`)
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import experimental.semmle.python.templates.SSTISink
|
|||||||
deprecated ClassValue theMakoTemplateClass() { result = Value::named("mako.template.Template") }
|
deprecated ClassValue theMakoTemplateClass() { result = Value::named("mako.template.Template") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `mako.template.Template` class instantiation argument.
|
* A sink representing the `mako.template.Template` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from mako.template import Template
|
* from mako.template import Template
|
||||||
* mytemplate = Template("hello world!")
|
* mytemplate = Template("hello world!")
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import experimental.semmle.python.templates.SSTISink
|
|||||||
deprecated ClassValue theTRenderTemplateClass() { result = Value::named("trender.TRender") }
|
deprecated ClassValue theTRenderTemplateClass() { result = Value::named("trender.TRender") }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sink representing the `trender.TRender` class instantiation argument.
|
* A sink representing the `trender.TRender` class instantiation argument.
|
||||||
*
|
*
|
||||||
* from trender import TRender
|
* from trender import TRender
|
||||||
* template = TRender(`sink`)
|
* template = TRender(`sink`)
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import semmle.python.PrintAst
|
|||||||
import analysis.DefinitionTracking
|
import analysis.DefinitionTracking
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The source file to generate an AST from.
|
* Gets the source file that will be used to generate the AST.
|
||||||
*/
|
*/
|
||||||
external string selectedSourceFile();
|
external string selectedSourceFile();
|
||||||
|
|
||||||
|
|||||||
@@ -81,7 +81,7 @@ module ModificationOfParameterWithDefault {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A name of a list function that modifies the list.
|
* Gets the name of a list function that modifies the list.
|
||||||
* See https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
|
* See https://docs.python.org/3/tutorial/datastructures.html#more-on-lists
|
||||||
*/
|
*/
|
||||||
string list_modifying_method() {
|
string list_modifying_method() {
|
||||||
@@ -89,7 +89,7 @@ module ModificationOfParameterWithDefault {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A name of a dict function that modifies the dict.
|
* Gets the name of a dict function that modifies the dict.
|
||||||
* See https://docs.python.org/3/library/stdtypes.html#dict
|
* See https://docs.python.org/3/library/stdtypes.html#dict
|
||||||
*/
|
*/
|
||||||
string dict_modifying_method() { result in ["clear", "pop", "popitem", "setdefault", "update"] }
|
string dict_modifying_method() { result in ["clear", "pop", "popitem", "setdefault", "update"] }
|
||||||
|
|||||||
@@ -124,7 +124,9 @@ abstract class InlineExpectationsTest extends string {
|
|||||||
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
abstract predicate hasActualResult(Location location, string element, string tag, string value);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like `hasActualResult`, but returns results that do not require a matching annotation.
|
* Holds if there is an optional result on the specified location.
|
||||||
|
*
|
||||||
|
* This is similar to `hasActualResult`, but returns results that do not require a matching annotation.
|
||||||
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
* A failure will still arise if there is an annotation that does not match any results, but not vice versa.
|
||||||
* Override this predicate to specify optional results.
|
* Override this predicate to specify optional results.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import TestUtilities.InlineExpectationsTest
|
|||||||
class UnresolvedCallExpectations extends InlineExpectationsTest {
|
class UnresolvedCallExpectations extends InlineExpectationsTest {
|
||||||
UnresolvedCallExpectations() { this = "UnresolvedCallExpectations" }
|
UnresolvedCallExpectations() { this = "UnresolvedCallExpectations" }
|
||||||
|
|
||||||
override string getARelevantTag() { result = ["unresolved_call"] }
|
override string getARelevantTag() { result = "unresolved_call" }
|
||||||
|
|
||||||
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
override predicate hasActualResult(Location location, string element, string tag, string value) {
|
||||||
exists(location.getFile().getRelativePath()) and
|
exists(location.getFile().getRelativePath()) and
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ private newtype TCallGraphResolver =
|
|||||||
TPointsToResolver() or
|
TPointsToResolver() or
|
||||||
TTypeTrackerResolver()
|
TTypeTrackerResolver()
|
||||||
|
|
||||||
/** Describes a method of call graph resolution */
|
/** A method of call graph resolution */
|
||||||
abstract class CallGraphResolver extends TCallGraphResolver {
|
abstract class CallGraphResolver extends TCallGraphResolver {
|
||||||
abstract predicate callEdge(Call call, Function callable);
|
abstract predicate callEdge(Call call, Function callable);
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import python
|
|||||||
private import semmle.python.objects.ObjectInternal
|
private import semmle.python.objects.ObjectInternal
|
||||||
private import semmle.python.pointsto.PointsTo
|
private import semmle.python.pointsto.PointsTo
|
||||||
|
|
||||||
/** Make unknown type visible */
|
/** An unknown type. Not usually visible. */
|
||||||
class UnknownType extends UnknownClassInternal {
|
class UnknownType extends UnknownClassInternal {
|
||||||
override string toString() { result = "*UNKNOWN TYPE" }
|
override string toString() { result = "*UNKNOWN TYPE" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import python
|
|||||||
private import semmle.python.objects.ObjectInternal
|
private import semmle.python.objects.ObjectInternal
|
||||||
private import semmle.python.pointsto.PointsTo
|
private import semmle.python.pointsto.PointsTo
|
||||||
|
|
||||||
/** Make unknown type visible */
|
/** An unknown type. Not usually visible. */
|
||||||
class UnknownType extends UnknownClassInternal {
|
class UnknownType extends UnknownClassInternal {
|
||||||
override string toString() { result = "*UNKNOWN TYPE" }
|
override string toString() { result = "*UNKNOWN TYPE" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import python
|
import python
|
||||||
private import semmle.python.objects.ObjectInternal
|
private import semmle.python.objects.ObjectInternal
|
||||||
|
|
||||||
/** Make unknown type visible */
|
/** An unknown type. Not usually visible. */
|
||||||
class UnknownType extends UnknownClassInternal {
|
class UnknownType extends UnknownClassInternal {
|
||||||
override string toString() { result = "*UNKNOWN TYPE" }
|
override string toString() { result = "*UNKNOWN TYPE" }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,12 @@ class SimpleSource extends TaintSource {
|
|||||||
class MySimpleSanitizer extends Sanitizer {
|
class MySimpleSanitizer extends Sanitizer {
|
||||||
MySimpleSanitizer() { this = "MySimpleSanitizer" }
|
MySimpleSanitizer() { this = "MySimpleSanitizer" }
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The test `if is_safe(arg):` sanitizes `arg` on its `true` edge.
|
* The test `if is_safe(arg):` sanitizes `arg` on its `true` edge.
|
||||||
*
|
*
|
||||||
* Can't handle `if not is_safe(arg):` :\ that's why it's called MySimpleSanitizer
|
* Can't handle `if not is_safe(arg):` :\ that's why it's called MySimpleSanitizer
|
||||||
*/
|
*/
|
||||||
|
|
||||||
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
||||||
taint instanceof ExternalStringKind and
|
taint instanceof ExternalStringKind and
|
||||||
exists(CallNode call | test.getTest() = call and test.getSense() = true |
|
exists(CallNode call | test.getTest() = call and test.getSense() = true |
|
||||||
@@ -30,7 +31,7 @@ class MySimpleSanitizer extends Sanitizer {
|
|||||||
class MySanitizerHandlingNot extends Sanitizer {
|
class MySanitizerHandlingNot extends Sanitizer {
|
||||||
MySanitizerHandlingNot() { this = "MySanitizerHandlingNot" }
|
MySanitizerHandlingNot() { this = "MySanitizerHandlingNot" }
|
||||||
|
|
||||||
/** The test `if is_safe(arg):` sanitizes `arg` on its `true` edge. */
|
/** Holds if the test `if is_safe(arg):` sanitizes `arg` on its `true` edge. */
|
||||||
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
override predicate sanitizingEdge(TaintKind taint, PyEdgeRefinement test) {
|
||||||
taint instanceof ExternalStringKind and
|
taint instanceof ExternalStringKind and
|
||||||
clears_taint_on_true(test.getTest(), test.getSense(), test)
|
clears_taint_on_true(test.getTest(), test.getSense(), test)
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Wally extends Engineer {
|
|||||||
Wally() { this = "Wally" }
|
Wally() { this = "Wally" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Then the configuration */
|
/** The configuration for this example. */
|
||||||
class DilbertConfig extends TaintTracking::Configuration {
|
class DilbertConfig extends TaintTracking::Configuration {
|
||||||
DilbertConfig() { this = "Dilbert config" }
|
DilbertConfig() { this = "Dilbert config" }
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user