mirror of
https://github.com/github/codeql.git
synced 2026-04-21 23:14:03 +02:00
@@ -17,6 +17,7 @@
|
||||
|
||||
## Changes to code extraction
|
||||
|
||||
* Fix extraction of `for` statements where the condition declares new variables using `is`.
|
||||
* Initializers of `stackalloc` arrays are now extracted.
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
## General improvements
|
||||
|
||||
* Support for popular libraries has been improved. Consequently, queries may produce more results on code bases that use the following features:
|
||||
* Support for popular libraries has been improved. Consequently, queries may produce better results on code bases that use the following features:
|
||||
- client-side code, for example [React](https://reactjs.org/)
|
||||
- cookies and webstorage, for example [js-cookie](https://github.com/js-cookie/js-cookie)
|
||||
- server-side code, for example [hapi](https://hapijs.com/)
|
||||
@@ -18,15 +18,18 @@
|
||||
| Incomplete regular expression for hostnames (`js/incomplete-hostname-regexp`) | correctness, security, external/cwe/cwe-020 | Highlights hostname sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default.|
|
||||
| Incomplete URL substring sanitization | correctness, security, external/cwe/cwe-020 | Highlights URL sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results shown on LGTM by default. |
|
||||
| Incorrect suffix check (`js/incorrect-suffix-check`) | correctness, security, external/cwe/cwe-020 | Highlights error-prone suffix checks based on `indexOf`, indicating a potential violation of [CWE-20](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default. |
|
||||
| Loop iteration skipped due to shifting (`js/loop-iteration-skipped-due-to-shifting`) | correctness | Highlights code that removes an element from an array while iterating over it, causing the loop to skip over some elements. Results are shown on LGTM by default. |
|
||||
| Useless comparison test (`js/useless-comparison-test`) | correctness | Highlights code that is unreachable due to a numeric comparison that is always true or always false. Results are shown on LGTM by default. |
|
||||
|
||||
## Changes to existing queries
|
||||
|
||||
| **Query** | **Expected impact** | **Change** |
|
||||
|--------------------------------------------|------------------------------|------------------------------------------------------------------------------|
|
||||
| Client-side cross-site scripting | More results | This rule now recognizes WinJS functions that are vulnerable to HTML injection. |
|
||||
| Client-side cross-site scripting | More true-positive results, fewer false-positive results. | This rule now recognizes WinJS functions that are vulnerable to HTML injection, and no longer flags certain safe uses of jQuery. |
|
||||
| Insecure randomness | More results | This rule now flags insecure uses of `crypto.pseudoRandomBytes`. |
|
||||
| Uncontrolled data used in network request | More results | This rule now recognizes host values that are vulnerable to injection. |
|
||||
| Unused parameter | Fewer false-positive results | This rule no longer flags parameters with leading underscore. |
|
||||
| Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that are implictly used by JSX elements, and no longer flags variables with leading underscore. |
|
||||
| Uncontrolled data used in path expression | Fewer false-positive results | This rule now recognizes the Express `root` option, which prevents path traversal. |
|
||||
|
||||
## Changes to QL libraries
|
||||
|
||||
@@ -55,10 +55,18 @@ class Macro extends PreprocessorDirective, @ppd_define {
|
||||
}
|
||||
|
||||
/**
|
||||
* A macro access (macro expansion or other macro access).
|
||||
* A macro access. For example:
|
||||
* ```
|
||||
* #ifdef MACRO1 // this line contains a MacroAccess
|
||||
* int x = MACRO2; // this line contains a MacroAccess
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* See also `MacroInvocation`, which represents only macro accesses
|
||||
* that are expanded (such as in the second line of the example above).
|
||||
*/
|
||||
class MacroAccess extends Locatable, @macroinvocation {
|
||||
/** Gets the macro being invoked. */
|
||||
/** Gets the macro that is being accessed. */
|
||||
Macro getMacro() { macroinvocations(underlyingElement(this),unresolveElement(result),_,_) }
|
||||
|
||||
/**
|
||||
@@ -73,7 +81,7 @@ class MacroAccess extends Locatable, @macroinvocation {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the location of this macro invocation. For a nested invocation, where
|
||||
* Gets the location of this macro access. For a nested access, where
|
||||
* `exists(this.getParentInvocation())`, this yields a location either inside
|
||||
* a `#define` directive or inside an argument to another macro.
|
||||
*/
|
||||
@@ -126,14 +134,22 @@ class MacroAccess extends Locatable, @macroinvocation {
|
||||
|
||||
override string toString() { result = this.getMacro().getHead() }
|
||||
|
||||
/** Gets the name of the invoked macro. */
|
||||
/** Gets the name of the accessed macro. */
|
||||
string getMacroName() {
|
||||
result = getMacro().getName()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A macro invocation (macro expansion).
|
||||
* A macro invocation (macro access that is expanded). For example:
|
||||
* ```
|
||||
* #ifdef MACRO1
|
||||
* int x = MACRO2; // this line contains a MacroInvocation
|
||||
* #endif
|
||||
* ```
|
||||
*
|
||||
* See also `MacroAccess`, which also represents macro accesses where the macro
|
||||
* is checked but not expanded (such as in the first line of the example above).
|
||||
*/
|
||||
class MacroInvocation extends MacroAccess {
|
||||
MacroInvocation() {
|
||||
@@ -174,7 +190,7 @@ class MacroInvocation extends MacroAccess {
|
||||
/**
|
||||
* Gets the top-level expression associated with this macro invocation,
|
||||
* if any. Note that this predicate will fail if the top-level expanded
|
||||
* element is a statement rather than an expression.
|
||||
* element is not an expression (for example if it is a statement).
|
||||
*/
|
||||
Expr getExpr() {
|
||||
result = getAnExpandedElement() and
|
||||
@@ -185,7 +201,7 @@ class MacroInvocation extends MacroAccess {
|
||||
/**
|
||||
* Gets the top-level statement associated with this macro invocation, if
|
||||
* any. Note that this predicate will fail if the top-level expanded
|
||||
* element is an expression rather than a statement.
|
||||
* element is not a statement (for example if it is an expression).
|
||||
*/
|
||||
Stmt getStmt() {
|
||||
result = getAnExpandedElement() and
|
||||
|
||||
@@ -58,7 +58,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.ModelError(symbol, "Undhandled accessor kind");
|
||||
Context.ModelError(symbol, "Unhandled accessor kind");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
if (symbol.IsStatic) tb.Append("static");
|
||||
tb.Append(ContainingType);
|
||||
AddParametersToId(Context, tb, symbol);
|
||||
tb.Append("; constructor");
|
||||
tb.Append(";constructor");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,12 +30,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Context.Emit(Tuples.events(this, symbol.GetName(), ContainingType, type.TypeRef, Create(Context, symbol.OriginalDefinition)));
|
||||
|
||||
var adder = symbol.AddMethod;
|
||||
if (adder != null)
|
||||
EventAccessor.Create(Context, adder);
|
||||
|
||||
var remover = symbol.RemoveMethod;
|
||||
if (remover != null)
|
||||
EventAccessor.Create(Context, remover);
|
||||
|
||||
if (!(adder is null))
|
||||
Method.Create(Context, adder);
|
||||
|
||||
if (!(remover is null))
|
||||
Method.Create(Context, remover);
|
||||
|
||||
ExtractModifiers();
|
||||
BindComments();
|
||||
|
||||
@@ -117,17 +117,19 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
public void OperatorCall(ExpressionSyntax node)
|
||||
{
|
||||
var @operator = cx.GetSymbolInfo(node);
|
||||
var method = @operator.Symbol as IMethodSymbol;
|
||||
|
||||
if (GetCallType(cx, node) == CallType.Dynamic)
|
||||
if (@operator.Symbol is IMethodSymbol method)
|
||||
{
|
||||
UserOperator.OperatorSymbol(method.Name, out string operatorName);
|
||||
cx.Emit(Tuples.dynamic_member_name(this, operatorName));
|
||||
return;
|
||||
}
|
||||
|
||||
if (method != null)
|
||||
var callType = GetCallType(cx, node);
|
||||
if (callType == CallType.Dynamic)
|
||||
{
|
||||
UserOperator.OperatorSymbol(method.Name, out string operatorName);
|
||||
cx.Emit(Tuples.dynamic_member_name(this, operatorName));
|
||||
return;
|
||||
}
|
||||
|
||||
cx.Emit(Tuples.expr_call(this, Method.Create(cx, method)));
|
||||
}
|
||||
}
|
||||
|
||||
public enum CallType
|
||||
@@ -148,12 +150,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
var @operator = cx.GetSymbolInfo(node);
|
||||
|
||||
if (@operator.Symbol != null)
|
||||
if (@operator.Symbol is IMethodSymbol method)
|
||||
{
|
||||
var method = @operator.Symbol as IMethodSymbol;
|
||||
|
||||
var containingSymbol = method.ContainingSymbol as ITypeSymbol;
|
||||
if (containingSymbol != null && containingSymbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Dynamic)
|
||||
if (method.ContainingSymbol is ITypeSymbol containingSymbol && containingSymbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Dynamic)
|
||||
{
|
||||
return CallType.Dynamic;
|
||||
}
|
||||
|
||||
@@ -33,58 +33,37 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
/// <summary>
|
||||
/// Represents a chain of method calls (the operand being recursive).
|
||||
/// </summary>
|
||||
class ClauseCall
|
||||
abstract class Clause
|
||||
{
|
||||
public ClauseCall operand;
|
||||
public IMethodSymbol method;
|
||||
public readonly List<ExpressionSyntax> arguments = new List<ExpressionSyntax>();
|
||||
public SyntaxNode node;
|
||||
public ISymbol declaration;
|
||||
public SyntaxToken name;
|
||||
public ISymbol intoDeclaration;
|
||||
protected readonly IMethodSymbol method;
|
||||
protected readonly List<ExpressionSyntax> arguments = new List<ExpressionSyntax>();
|
||||
protected readonly SyntaxNode node;
|
||||
|
||||
protected Clause(IMethodSymbol method, SyntaxNode node)
|
||||
{
|
||||
this.method = method;
|
||||
this.node = node;
|
||||
}
|
||||
|
||||
public ExpressionSyntax Expr => arguments.First();
|
||||
|
||||
public ClauseCall WithClause(IMethodSymbol newMethod, SyntaxNode newNode, SyntaxToken newName = default(SyntaxToken), ISymbol newDeclaration = null)
|
||||
{
|
||||
return new ClauseCall
|
||||
{
|
||||
operand = this,
|
||||
method = newMethod,
|
||||
node = newNode,
|
||||
name = newName,
|
||||
declaration = newDeclaration
|
||||
};
|
||||
}
|
||||
public CallClause WithCallClause(IMethodSymbol newMethod, SyntaxNode newNode) =>
|
||||
new CallClause(this, newMethod, newNode);
|
||||
|
||||
public ClauseCall AddArgument(ExpressionSyntax arg)
|
||||
public LetClause WithLetClause(IMethodSymbol newMethod, SyntaxNode newNode, ISymbol newDeclaration, SyntaxToken newName) =>
|
||||
new LetClause(this, newMethod, newNode, newDeclaration, newName);
|
||||
|
||||
public Clause AddArgument(ExpressionSyntax arg)
|
||||
{
|
||||
if (arg != null)
|
||||
arguments.Add(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
public ClauseCall WithInto(ISymbol into)
|
||||
{
|
||||
intoDeclaration = into;
|
||||
return this;
|
||||
}
|
||||
|
||||
Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement)
|
||||
{
|
||||
return DeclareRangeVariable(cx, parent, child, getElement, declaration);
|
||||
}
|
||||
|
||||
void DeclareIntoVariable(Context cx, IExpressionParentEntity parent, int intoChild, bool getElement)
|
||||
{
|
||||
if (intoDeclaration != null)
|
||||
DeclareRangeVariable(cx, parent, intoChild, getElement, intoDeclaration);
|
||||
}
|
||||
|
||||
Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol)
|
||||
protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name)
|
||||
{
|
||||
var type = Type.Create(cx, cx.GetType(Expr));
|
||||
Semmle.Extraction.Entities.Location nameLoc;
|
||||
Extraction.Entities.Location nameLoc;
|
||||
|
||||
Type declType;
|
||||
if (getElement)
|
||||
@@ -115,7 +94,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
return decl;
|
||||
}
|
||||
|
||||
void PopulateArguments(Context cx, QueryCall callExpr, int child)
|
||||
protected void PopulateArguments(Context cx, QueryCall callExpr, int child)
|
||||
{
|
||||
foreach (var e in arguments)
|
||||
{
|
||||
@@ -123,34 +102,79 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
}
|
||||
}
|
||||
|
||||
public Expression Populate(Context cx, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
if (declaration != null) // The first "from" clause, or a "let" clause
|
||||
{
|
||||
if (operand == null)
|
||||
{
|
||||
return DeclareRangeVariable(cx, parent, child, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (method == null)
|
||||
cx.ModelError(node, "Unable to determine target of query expression");
|
||||
public abstract Expression Populate(Context cx, IExpressionParentEntity parent, int child);
|
||||
}
|
||||
|
||||
var callExpr = new QueryCall(cx, method, node, parent, child);
|
||||
operand.Populate(cx, callExpr, 0);
|
||||
DeclareRangeVariable(cx, callExpr, 1, false);
|
||||
PopulateArguments(cx, callExpr, 2);
|
||||
DeclareIntoVariable(cx, callExpr, 2 + arguments.Count, false);
|
||||
return callExpr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
var callExpr = new QueryCall(cx, method, node, parent, child);
|
||||
operand.Populate(cx, callExpr, 0);
|
||||
PopulateArguments(cx, callExpr, 1);
|
||||
return callExpr;
|
||||
}
|
||||
class RangeClause : Clause
|
||||
{
|
||||
readonly ISymbol declaration;
|
||||
readonly SyntaxToken name;
|
||||
|
||||
public RangeClause(IMethodSymbol method, SyntaxNode node, ISymbol declaration, SyntaxToken name) : base(method, node)
|
||||
{
|
||||
this.declaration = declaration;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public override Expression Populate(Context cx, IExpressionParentEntity parent, int child) =>
|
||||
DeclareRangeVariable(cx, parent, child, true, declaration, name);
|
||||
}
|
||||
|
||||
class LetClause : Clause
|
||||
{
|
||||
readonly Clause operand;
|
||||
readonly ISymbol declaration;
|
||||
readonly SyntaxToken name;
|
||||
ISymbol intoDeclaration;
|
||||
|
||||
public LetClause(Clause operand, IMethodSymbol method, SyntaxNode node, ISymbol declaration, SyntaxToken name) : base(method, node)
|
||||
{
|
||||
this.operand = operand;
|
||||
this.declaration = declaration;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Clause WithInto(ISymbol into)
|
||||
{
|
||||
intoDeclaration = into;
|
||||
return this;
|
||||
}
|
||||
|
||||
void DeclareIntoVariable(Context cx, IExpressionParentEntity parent, int intoChild, bool getElement)
|
||||
{
|
||||
if (intoDeclaration != null)
|
||||
DeclareRangeVariable(cx, parent, intoChild, getElement, intoDeclaration, name);
|
||||
}
|
||||
|
||||
public override Expression Populate(Context cx, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
if (method == null)
|
||||
cx.ModelError(node, "Unable to determine target of query expression");
|
||||
|
||||
var callExpr = new QueryCall(cx, method, node, parent, child);
|
||||
operand.Populate(cx, callExpr, 0);
|
||||
DeclareRangeVariable(cx, callExpr, 1, false, declaration, name);
|
||||
PopulateArguments(cx, callExpr, 2);
|
||||
DeclareIntoVariable(cx, callExpr, 2 + arguments.Count, false);
|
||||
return callExpr;
|
||||
}
|
||||
}
|
||||
|
||||
class CallClause : Clause
|
||||
{
|
||||
readonly Clause operand;
|
||||
|
||||
public CallClause(Clause operand, IMethodSymbol method, SyntaxNode node) : base(method, node)
|
||||
{
|
||||
this.operand = operand;
|
||||
}
|
||||
|
||||
public override Expression Populate(Context cx, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var callExpr = new QueryCall(cx, method, node, parent, child);
|
||||
operand.Populate(cx, callExpr, 0);
|
||||
PopulateArguments(cx, callExpr, 1);
|
||||
return callExpr;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -161,18 +185,12 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
/// <param name="cx">The extraction context.</param>
|
||||
/// <param name="node">The query expression.</param>
|
||||
/// <returns>A "syntax tree" of the query.</returns>
|
||||
static ClauseCall ConstructQueryExpression(Context cx, QueryExpressionSyntax node)
|
||||
static Clause ConstructQueryExpression(Context cx, QueryExpressionSyntax node)
|
||||
{
|
||||
var info = cx.Model(node).GetQueryClauseInfo(node.FromClause);
|
||||
var method = info.OperationInfo.Symbol as IMethodSymbol;
|
||||
|
||||
ClauseCall clauseExpr = new ClauseCall
|
||||
{
|
||||
declaration = cx.Model(node).GetDeclaredSymbol(node.FromClause),
|
||||
name = node.FromClause.Identifier,
|
||||
method = method,
|
||||
node = node.FromClause
|
||||
}.AddArgument(node.FromClause.Expression);
|
||||
Clause clauseExpr = new RangeClause(method, node.FromClause, cx.Model(node).GetDeclaredSymbol(node.FromClause), node.FromClause.Identifier).AddArgument(node.FromClause.Expression);
|
||||
|
||||
foreach (var qc in node.Body.Clauses)
|
||||
{
|
||||
@@ -188,7 +206,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
{
|
||||
method = cx.Model(node).GetSymbolInfo(ordering).Symbol as IMethodSymbol;
|
||||
|
||||
clauseExpr = clauseExpr.WithClause(method, orderByClause).AddArgument(ordering.Expression);
|
||||
clauseExpr = clauseExpr.WithCallClause(method, orderByClause).AddArgument(ordering.Expression);
|
||||
|
||||
if (method == null)
|
||||
cx.ModelError(ordering, "Could not determine method call for orderby clause");
|
||||
@@ -196,23 +214,23 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
break;
|
||||
case SyntaxKind.WhereClause:
|
||||
var whereClause = (WhereClauseSyntax)qc;
|
||||
clauseExpr = clauseExpr.WithClause(method, whereClause).AddArgument(whereClause.Condition);
|
||||
clauseExpr = clauseExpr.WithCallClause(method, whereClause).AddArgument(whereClause.Condition);
|
||||
break;
|
||||
case SyntaxKind.FromClause:
|
||||
var fromClause = (FromClauseSyntax)qc;
|
||||
clauseExpr = clauseExpr.
|
||||
WithClause(method, fromClause, fromClause.Identifier, cx.Model(node).GetDeclaredSymbol(fromClause)).
|
||||
WithLetClause(method, fromClause, cx.Model(node).GetDeclaredSymbol(fromClause), fromClause.Identifier).
|
||||
AddArgument(fromClause.Expression);
|
||||
break;
|
||||
case SyntaxKind.LetClause:
|
||||
var letClause = (LetClauseSyntax)qc;
|
||||
clauseExpr = clauseExpr.WithClause(method, letClause, letClause.Identifier, cx.Model(node).GetDeclaredSymbol(letClause)).
|
||||
clauseExpr = clauseExpr.WithLetClause(method, letClause, cx.Model(node).GetDeclaredSymbol(letClause), letClause.Identifier).
|
||||
AddArgument(letClause.Expression);
|
||||
break;
|
||||
case SyntaxKind.JoinClause:
|
||||
var joinClause = (JoinClauseSyntax)qc;
|
||||
|
||||
clauseExpr = clauseExpr.WithClause(method, joinClause, joinClause.Identifier, cx.Model(node).GetDeclaredSymbol(joinClause)).
|
||||
clauseExpr = clauseExpr.WithLetClause(method, joinClause, cx.Model(node).GetDeclaredSymbol(joinClause), joinClause.Identifier).
|
||||
AddArgument(joinClause.InExpression).
|
||||
AddArgument(joinClause.LeftExpression).
|
||||
AddArgument(joinClause.RightExpression);
|
||||
@@ -220,7 +238,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
if (joinClause.Into != null)
|
||||
{
|
||||
var into = cx.Model(node).GetDeclaredSymbol(joinClause.Into);
|
||||
clauseExpr.WithInto(into);
|
||||
((LetClause)clauseExpr).WithInto(into);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -231,16 +249,13 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
|
||||
method = cx.Model(node).GetSymbolInfo(node.Body.SelectOrGroup).Symbol as IMethodSymbol;
|
||||
|
||||
var selectClause = node.Body.SelectOrGroup as SelectClauseSyntax;
|
||||
var groupClause = node.Body.SelectOrGroup as GroupClauseSyntax;
|
||||
clauseExpr = new CallClause(clauseExpr, method, node.Body.SelectOrGroup);
|
||||
|
||||
clauseExpr = new ClauseCall { operand = clauseExpr, method = method, node = node.Body.SelectOrGroup };
|
||||
|
||||
if (selectClause != null)
|
||||
if (node.Body.SelectOrGroup is SelectClauseSyntax selectClause)
|
||||
{
|
||||
clauseExpr.AddArgument(selectClause.Expression);
|
||||
}
|
||||
else if (groupClause != null)
|
||||
else if (node.Body.SelectOrGroup is GroupClauseSyntax groupClause)
|
||||
{
|
||||
clauseExpr.
|
||||
AddArgument(groupClause.GroupExpression).
|
||||
|
||||
@@ -21,18 +21,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var getter = symbol.GetMethod;
|
||||
var setter = symbol.SetMethod;
|
||||
|
||||
if (getter == null && setter == null)
|
||||
if (getter is null && setter is null)
|
||||
Context.ModelError(symbol, "No indexer accessor defined");
|
||||
|
||||
if (getter != null)
|
||||
{
|
||||
Getter = Accessor.Create(Context, getter);
|
||||
}
|
||||
if (!(getter is null))
|
||||
Method.Create(Context, getter);
|
||||
|
||||
if (setter != null)
|
||||
{
|
||||
Setter = Accessor.Create(Context, setter);
|
||||
}
|
||||
if (!(setter is null))
|
||||
Method.Create(Context, setter);
|
||||
|
||||
for (var i = 0; i < symbol.Parameters.Length; ++i)
|
||||
{
|
||||
@@ -40,26 +36,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Parameter.Create(Context, symbol.Parameters[i], this, original);
|
||||
}
|
||||
|
||||
if (getter != null)
|
||||
{
|
||||
Getter = Accessor.Create(Context, getter);
|
||||
Context.Emit(Tuples.accessors(Getter, 1, getter.Name, this, Getter.OriginalDefinition));
|
||||
|
||||
Context.Emit(Tuples.accessor_location(Getter, Getter.Location));
|
||||
Getter.Overrides();
|
||||
Getter.ExtractModifiers();
|
||||
}
|
||||
|
||||
if (setter != null)
|
||||
{
|
||||
Setter = Accessor.Create(Context, setter);
|
||||
Context.Emit(Tuples.accessors(Setter, 2, setter.Name, this, Setter.OriginalDefinition));
|
||||
|
||||
Context.Emit(Tuples.accessor_location(Setter, Setter.Location));
|
||||
Setter.Overrides();
|
||||
Setter.ExtractModifiers();
|
||||
}
|
||||
|
||||
if (IsSourceDeclaration)
|
||||
{
|
||||
var expressionBody = ExpressionBody;
|
||||
|
||||
@@ -256,7 +256,15 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
if (methodDecl == null) return null;
|
||||
|
||||
switch (methodDecl.MethodKind)
|
||||
var methodKind = methodDecl.MethodKind;
|
||||
|
||||
if(methodKind == MethodKind.ExplicitInterfaceImplementation)
|
||||
{
|
||||
// Retrieve the original method kind
|
||||
methodKind = methodDecl.ExplicitInterfaceImplementations.Select(m => m.MethodKind).FirstOrDefault();
|
||||
}
|
||||
|
||||
switch (methodKind)
|
||||
{
|
||||
case MethodKind.StaticConstructor:
|
||||
case MethodKind.Constructor:
|
||||
@@ -264,13 +272,12 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
case MethodKind.ReducedExtension:
|
||||
case MethodKind.Ordinary:
|
||||
case MethodKind.DelegateInvoke:
|
||||
case MethodKind.ExplicitInterfaceImplementation:
|
||||
return OrdinaryMethod.Create(cx, methodDecl);
|
||||
case MethodKind.Destructor:
|
||||
return Destructor.Create(cx, methodDecl);
|
||||
case MethodKind.PropertyGet:
|
||||
case MethodKind.PropertySet:
|
||||
return Accessor.Create(cx, methodDecl);
|
||||
return methodDecl.AssociatedSymbol is null ? OrdinaryMethod.Create(cx, methodDecl) : (Method)Accessor.Create(cx, methodDecl);
|
||||
case MethodKind.EventAdd:
|
||||
case MethodKind.EventRemove:
|
||||
return EventAccessor.Create(cx, methodDecl);
|
||||
|
||||
@@ -2,7 +2,7 @@ using Microsoft.CodeAnalysis;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.Entities
|
||||
{
|
||||
class Namespace : CachedEntity<INamespaceSymbol>
|
||||
sealed class Namespace : CachedEntity<INamespaceSymbol>
|
||||
{
|
||||
Namespace(Context cx, INamespaceSymbol init)
|
||||
: base(cx, init) { }
|
||||
@@ -31,7 +31,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
public static Namespace Create(Context cx, INamespaceSymbol ns) => NamespaceFactory.Instance.CreateEntity(cx, ns);
|
||||
public static Namespace Create(Context cx, INamespaceSymbol ns) => NamespaceFactory.Instance.CreateEntity2(cx, ns);
|
||||
|
||||
class NamespaceFactory : ICachedEntityFactory<INamespaceSymbol, Namespace>
|
||||
{
|
||||
@@ -41,5 +41,14 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
|
||||
|
||||
public override int GetHashCode() => QualifiedName.GetHashCode();
|
||||
|
||||
string QualifiedName => symbol.ToDisplayString();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Namespace ns && QualifiedName == ns.QualifiedName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,6 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
}
|
||||
|
||||
protected Accessor Getter { get; set; }
|
||||
protected Accessor Setter { get; set; }
|
||||
|
||||
public override void Populate()
|
||||
{
|
||||
ExtractMetadataHandle();
|
||||
@@ -38,12 +35,13 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
Context.Emit(Tuples.properties(this, symbol.GetName(), ContainingType, type.TypeRef, Create(Context, symbol.OriginalDefinition)));
|
||||
|
||||
var getter = symbol.GetMethod;
|
||||
if (getter != null)
|
||||
Getter = Accessor.Create(Context, getter);
|
||||
|
||||
var setter = symbol.SetMethod;
|
||||
if (setter != null)
|
||||
Setter = Accessor.Create(Context, setter);
|
||||
|
||||
if (!(getter is null))
|
||||
Method.Create(Context, getter);
|
||||
|
||||
if (!(setter is null))
|
||||
Method.Create(Context, setter);
|
||||
|
||||
var declSyntaxReferences = IsSourceDeclaration ?
|
||||
symbol.DeclaringSyntaxReferences.
|
||||
@@ -101,7 +99,9 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public static Property Create(Context cx, IPropertySymbol prop)
|
||||
{
|
||||
return prop.IsIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntity(cx, prop);
|
||||
bool isIndexer = prop.IsIndexer || prop.ExplicitInterfaceImplementations.Any(e => e.IsIndexer);
|
||||
|
||||
return isIndexer ? Indexer.Create(cx, prop) : PropertyFactory.Instance.CreateEntity(cx, prop);
|
||||
}
|
||||
|
||||
public void VisitDeclaration(Context cx, PropertyDeclarationSyntax p)
|
||||
|
||||
@@ -28,7 +28,10 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
|
||||
Expression.Create(cx, init, this, child--);
|
||||
}
|
||||
|
||||
Statement.Create(cx, Stmt.Statement, this, 1 + Stmt.Incrementors.Count);
|
||||
if (Stmt.Condition != null)
|
||||
{
|
||||
Expression.Create(cx, Stmt.Condition, this, 0);
|
||||
}
|
||||
|
||||
child = 1;
|
||||
foreach (var inc in Stmt.Incrementors)
|
||||
@@ -36,10 +39,7 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
|
||||
Expression.Create(cx, inc, this, child++);
|
||||
}
|
||||
|
||||
if (Stmt.Condition != null)
|
||||
{
|
||||
Expression.Create(cx, Stmt.Condition, this, 0);
|
||||
}
|
||||
Statement.Create(cx, Stmt.Statement, this, 1 + Stmt.Incrementors.Count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
referencedType = Type.Create(cx, symbol);
|
||||
}
|
||||
|
||||
public static NamedTypeRef Create(Context cx, INamedTypeSymbol type) => NamedTypeRefFactory.Instance.CreateEntity(cx, type);
|
||||
public static NamedTypeRef Create(Context cx, INamedTypeSymbol type) => NamedTypeRefFactory.Instance.CreateEntity2(cx, type);
|
||||
|
||||
class NamedTypeRefFactory : ICachedEntityFactory<INamedTypeSymbol, NamedTypeRef>
|
||||
{
|
||||
|
||||
@@ -158,7 +158,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
var param = invokeMethod.Parameters[i];
|
||||
var originalParam = invokeMethod.OriginalDefinition.Parameters[i];
|
||||
var originalParamEntity = Equals(param, originalParam) ? null :
|
||||
DelegateTypeParameter.Create(Context, originalParam, Create(Context, ((INamedTypeSymbol)symbol).ConstructedFrom));
|
||||
DelegateTypeParameter.Create(Context, originalParam, Create(Context, ((INamedTypeSymbol)symbol).OriginalDefinition));
|
||||
DelegateTypeParameter.Create(Context, param, this, originalParamEntity);
|
||||
}
|
||||
|
||||
|
||||
@@ -43,28 +43,90 @@ namespace Semmle.Extraction
|
||||
int NewId() => TrapWriter.IdCounter++;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the cached label for the given entity, or creates a new
|
||||
/// (cached) label if it hasn't already been created. The label
|
||||
/// is set on the supplied <paramref name="entity"/> object.
|
||||
/// Creates a new entity using the factory.
|
||||
/// </summary>
|
||||
/// <returns><code>true</code> iff the label already existed.</returns>
|
||||
public bool GetOrAddCachedLabel(ICachedEntity entity)
|
||||
/// <param name="factory">The entity factory.</param>
|
||||
/// <param name="init">The initializer for the entity.</param>
|
||||
/// <returns>The new/existing entity.</returns>
|
||||
public Entity CreateEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity
|
||||
{
|
||||
var id = GetId(entity);
|
||||
if (id == null)
|
||||
throw new InternalError("Attempt to create a null entity for {0}", entity.GetType());
|
||||
return init == null ? CreateEntity2(factory, init) : CreateNonNullEntity(factory, init);
|
||||
}
|
||||
|
||||
Label existingLabel;
|
||||
if (labelCache.TryGetValue(id, out existingLabel))
|
||||
/// <summary>
|
||||
/// Creates a new entity using the factory.
|
||||
/// Uses a different cache to <see cref="CreateEntity{Type, Entity}(ICachedEntityFactory{Type, Entity}, Type)"/>,
|
||||
/// and can store null values.
|
||||
/// </summary>
|
||||
/// <param name="factory">The entity factory.</param>
|
||||
/// <param name="init">The initializer for the entity.</param>
|
||||
/// <returns>The new/existing entity.</returns>
|
||||
public Entity CreateEntity2<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity
|
||||
{
|
||||
using (StackGuard)
|
||||
{
|
||||
entity.Label = existingLabel;
|
||||
return true;
|
||||
}
|
||||
var entity = factory.Create(this, init);
|
||||
|
||||
entity.Label = new Label(NewId());
|
||||
DefineLabel(entity.Label, id);
|
||||
labelCache[id] = entity.Label;
|
||||
return false;
|
||||
if (entityLabelCache.TryGetValue(entity, out var label))
|
||||
{
|
||||
entity.Label = label;
|
||||
}
|
||||
else
|
||||
{
|
||||
var id = entity.Id;
|
||||
#if DEBUG_LABELS
|
||||
CheckEntityHasUniqueLabel(id, entity);
|
||||
#endif
|
||||
label = new Label(NewId());
|
||||
entity.Label = label;
|
||||
entityLabelCache[entity] = label;
|
||||
DefineLabel(label, id);
|
||||
if (entity.NeedsPopulation)
|
||||
Populate(init as ISymbol, entity);
|
||||
}
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
#if DEBUG_LABELS
|
||||
private void CheckEntityHasUniqueLabel(IId id, ICachedEntity entity)
|
||||
{
|
||||
if (idLabelCache.TryGetValue(id, out var originalEntity))
|
||||
{
|
||||
Extractor.Message(new Message { message = "Label collision for " + id.ToString(), severity = Severity.Warning });
|
||||
}
|
||||
else
|
||||
{
|
||||
idLabelCache[id] = entity;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
private Entity CreateNonNullEntity<Type, Entity>(ICachedEntityFactory<Type, Entity> factory, Type init) where Entity : ICachedEntity
|
||||
{
|
||||
if (objectEntityCache.TryGetValue(init, out var cached))
|
||||
return (Entity)cached;
|
||||
|
||||
using (StackGuard)
|
||||
{
|
||||
var label = new Label(NewId());
|
||||
var entity = factory.Create(this, init);
|
||||
entity.Label = label;
|
||||
|
||||
objectEntityCache[init] = entity;
|
||||
|
||||
var id = entity.Id;
|
||||
DefineLabel(label, id);
|
||||
|
||||
#if DEBUG_LABELS
|
||||
CheckEntityHasUniqueLabel(id, entity);
|
||||
#endif
|
||||
|
||||
if (entity.NeedsPopulation)
|
||||
Populate(init as ISymbol, entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -90,25 +152,6 @@ namespace Semmle.Extraction
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the ID belonging to cached entity <paramref name="entity"/>.
|
||||
///
|
||||
/// The ID itself is also cached, but unlike the label cache (which is used
|
||||
/// to prevent reextraction/infinite loops), this is a pure performance
|
||||
/// optimization. Moreover, the label cache is injective, which the ID cache
|
||||
/// need not be.
|
||||
/// </summary>
|
||||
IId GetId(ICachedEntity entity)
|
||||
{
|
||||
IId id;
|
||||
if (!idCache.TryGetValue(entity, out id))
|
||||
{
|
||||
id = entity.Id;
|
||||
idCache[entity] = id;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a fresh label with ID "*", and set it on the
|
||||
/// supplied <paramref name="entity"/> object.
|
||||
@@ -120,7 +163,11 @@ namespace Semmle.Extraction
|
||||
entity.Label = label;
|
||||
}
|
||||
|
||||
readonly Dictionary<IId, Label> labelCache = new Dictionary<IId, Label>();
|
||||
#if DEBUG_LABELS
|
||||
readonly Dictionary<IId, ICachedEntity> idLabelCache = new Dictionary<IId, ICachedEntity>();
|
||||
#endif
|
||||
readonly Dictionary<object, ICachedEntity> objectEntityCache = new Dictionary<object, ICachedEntity>();
|
||||
readonly Dictionary<ICachedEntity, Label> entityLabelCache = new Dictionary<ICachedEntity, Label>();
|
||||
readonly HashSet<Label> extractedGenerics = new HashSet<Label>();
|
||||
|
||||
public void DefineLabel(IEntity entity)
|
||||
@@ -134,8 +181,6 @@ namespace Semmle.Extraction
|
||||
TrapWriter.Emit(new DefineLabelEmitter(label, id));
|
||||
}
|
||||
|
||||
readonly Dictionary<object, IId> idCache = new Dictionary<object, IId>();
|
||||
|
||||
/// <summary>
|
||||
/// Queue of items to populate later.
|
||||
/// The only reason for this is so that the call stack does not
|
||||
|
||||
@@ -2,7 +2,7 @@ using System.IO;
|
||||
|
||||
namespace Semmle.Extraction.Entities
|
||||
{
|
||||
class Folder : CachedEntity<DirectoryInfo>
|
||||
sealed class Folder : CachedEntity<DirectoryInfo>
|
||||
{
|
||||
Folder(Context cx, DirectoryInfo init)
|
||||
: base(cx, init)
|
||||
@@ -39,7 +39,7 @@ namespace Semmle.Extraction.Entities
|
||||
public override IId Id => new Key(DatabasePath, ";folder");
|
||||
|
||||
public static Folder Create(Context cx, DirectoryInfo folder) =>
|
||||
FolderFactory.Instance.CreateEntity(cx, folder);
|
||||
FolderFactory.Instance.CreateEntity2(cx, folder);
|
||||
|
||||
public override Microsoft.CodeAnalysis.Location ReportingLocation => null;
|
||||
|
||||
@@ -51,5 +51,12 @@ namespace Semmle.Extraction.Entities
|
||||
}
|
||||
|
||||
public override TrapStackBehaviour TrapStackBehaviour => TrapStackBehaviour.NoLabel;
|
||||
|
||||
public override int GetHashCode() => Path.GetHashCode();
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
return obj is Folder folder && folder.Path == Path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,6 +79,8 @@ namespace Semmle.Extraction
|
||||
void Populate();
|
||||
|
||||
bool NeedsPopulation { get; }
|
||||
|
||||
object UnderlyingObject { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -96,48 +98,36 @@ namespace Semmle.Extraction
|
||||
public static class ICachedEntityFactoryExtensions
|
||||
{
|
||||
public static Entity CreateEntity<Entity, T1, T2>(this ICachedEntityFactory<(T1, T2), Entity> factory, Context cx, T1 t1, T2 t2)
|
||||
where Entity : ICachedEntity
|
||||
{
|
||||
return factory.CreateEntity(cx, (t1, t2));
|
||||
}
|
||||
where Entity : ICachedEntity => factory.CreateEntity2(cx, (t1, t2));
|
||||
|
||||
public static Entity CreateEntity<Entity, T1, T2, T3>(this ICachedEntityFactory<(T1, T2, T3), Entity> factory, Context cx, T1 t1, T2 t2, T3 t3)
|
||||
where Entity : ICachedEntity
|
||||
{
|
||||
return factory.CreateEntity(cx, (t1, t2, t3));
|
||||
}
|
||||
where Entity : ICachedEntity => factory.CreateEntity2(cx, (t1, t2, t3));
|
||||
|
||||
public static Entity CreateEntity<Entity, T1, T2, T3, T4>(this ICachedEntityFactory<(T1, T2, T3, T4), Entity> factory, Context cx, T1 t1, T2 t2, T3 t3, T4 t4)
|
||||
where Entity : ICachedEntity
|
||||
{
|
||||
return factory.CreateEntity(cx, (t1, t2, t3, t4));
|
||||
}
|
||||
where Entity : ICachedEntity => factory.CreateEntity2(cx, (t1, t2, t3, t4));
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new entity or returns the existing one from the cache.
|
||||
/// Creates and populates a new entity, or returns the existing one from the cache.
|
||||
/// </summary>
|
||||
/// <typeparam name="Type">The symbol type used to construct the entity.</typeparam>
|
||||
/// <typeparam name="Entity">The type of the entity to create.</typeparam>
|
||||
/// <param name="cx">The extractor context.</param>
|
||||
/// <param name="factory">The factory used to construct the entity.</param>
|
||||
/// <param name="t">The initializer for the entity.</param>
|
||||
/// <returns></returns>
|
||||
/// <param name="init">The initializer for the entity, which may not be null.</param>
|
||||
/// <returns>The entity.</returns>
|
||||
public static Entity CreateEntity<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, Type init)
|
||||
where Entity : ICachedEntity
|
||||
{
|
||||
using (cx.StackGuard)
|
||||
{
|
||||
var entity = factory.Create(cx, init);
|
||||
if (cx.GetOrAddCachedLabel(entity))
|
||||
return entity;
|
||||
where Entity : ICachedEntity => cx.CreateEntity(factory, init);
|
||||
|
||||
if (!entity.NeedsPopulation)
|
||||
return entity;
|
||||
|
||||
cx.Populate(init as ISymbol, entity);
|
||||
|
||||
return entity;
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates and populates a new entity, but uses a different cache.
|
||||
/// </summary>
|
||||
/// <typeparam name="Type">The symbol type used to construct the entity.</typeparam>
|
||||
/// <typeparam name="Entity">The type of the entity to create.</typeparam>
|
||||
/// <param name="cx">The extractor context.</param>
|
||||
/// <param name="factory">The factory used to construct the entity.</param>
|
||||
/// <param name="init">The initializer for the entity, which may be null.</param>
|
||||
/// <returns>The entity.</returns>
|
||||
public static Entity CreateEntity2<Type, Entity>(this ICachedEntityFactory<Type, Entity> factory, Context cx, Type init)
|
||||
where Entity : ICachedEntity => cx.CreateEntity2(factory, init);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
||||
<DefineConstants>TRACE;DEBUG;DEBUG_LABELS</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.CodeAnalysis" Version="2.8.0" />
|
||||
<PackageReference Include="GitInfo" Version="2.0.18" />
|
||||
|
||||
@@ -30,6 +30,8 @@ namespace Semmle.Extraction
|
||||
get; private set;
|
||||
}
|
||||
|
||||
object ICachedEntity.UnderlyingObject => symbol;
|
||||
|
||||
public abstract IId Id
|
||||
{
|
||||
get;
|
||||
|
||||
@@ -285,7 +285,7 @@ namespace Semmle.Extraction
|
||||
public static string NestPaths(ILogger logger, string outerpath, string innerpath, InnerPathComputation innerPathComputation)
|
||||
{
|
||||
string nested = innerpath;
|
||||
if (outerpath != null || outerpath.Length != 0)
|
||||
if (!string.IsNullOrEmpty(outerpath))
|
||||
{
|
||||
if (!Path.IsPathRooted(innerpath) && innerPathComputation == InnerPathComputation.ABSOLUTE)
|
||||
innerpath = Path.GetFullPath(innerpath);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Dereferenced variable may be null
|
||||
* @description Dereferencing a variable whose value may be 'null' may cause a
|
||||
* 'NullReferenceException'.
|
||||
* @kind problem
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @precision high
|
||||
* @id cs/dereferenced-value-may-be-null
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.Nullness
|
||||
import PathGraph
|
||||
|
||||
from Dereference d, Ssa::SourceVariable v, string msg, Element reason
|
||||
where d.isFirstMaybeNull(v.getAnSsaDefinition(), msg, reason)
|
||||
select d, "Variable $@ may be null here " + msg + ".", v, v.toString(), reason, "this"
|
||||
from Dereference d, PathNode source, PathNode sink, Ssa::SourceVariable v, string msg, Element reason
|
||||
where d.isFirstMaybeNull(v.getAnSsaDefinition(), source, sink, msg, reason)
|
||||
select d, source, sink, "Variable $@ may be null here " + msg + ".", v, v.toString(), reason, "this"
|
||||
|
||||
@@ -20,10 +20,10 @@ import semmle.code.csharp.commons.ComparisonTest
|
||||
class IndexGuard extends ComparisonTest {
|
||||
VariableAccess indexAccess;
|
||||
Variable array;
|
||||
|
||||
|
||||
IndexGuard() {
|
||||
this.getFirstArgument() = indexAccess and
|
||||
this.getSecondArgument() = any(PropertyAccess lengthAccess |
|
||||
this.getSecondArgument() = any(PropertyAccess lengthAccess |
|
||||
lengthAccess.getQualifier() = array.getAnAccess() and
|
||||
lengthAccess.getTarget().hasName("Length")
|
||||
)
|
||||
@@ -50,7 +50,7 @@ from IndexGuard incorrectGuard, Variable array, Variable index, ElementAccess ea
|
||||
where
|
||||
// Look for `index <= array.Length` or `array.Length >= index`
|
||||
incorrectGuard.controls(array, index) and
|
||||
incorrectGuard.isIncorrect() and
|
||||
incorrectGuard.isIncorrect() and
|
||||
// Look for `array[index]`
|
||||
ea.getQualifier() = array.getAnAccess() and
|
||||
ea.getIndex(0) = indexAccess and
|
||||
|
||||
@@ -19,7 +19,7 @@ from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode
|
||||
where
|
||||
c.hasFlowPath(source, sink) and
|
||||
// No global timeout set
|
||||
not exists(RegexGlobalTimeout r) and
|
||||
not exists(RegexGlobalTimeout r) and
|
||||
(
|
||||
sink.getNode() instanceof Sink
|
||||
or
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* Provides a list of NuGet packages with known vulnerabilities.
|
||||
*
|
||||
*
|
||||
* To add a new vulnerability follow the existing pattern.
|
||||
* Create a new class that extends the abstract class `Vulnerability`,
|
||||
* supplying the name and the URL, and override one (or both) of
|
||||
@@ -73,9 +73,9 @@ class MicrosoftAdvisory4021279 extends Vulnerability {
|
||||
|
||||
class CVE_2017_8700 extends Vulnerability {
|
||||
CVE_2017_8700() { this = "CVE-2017-8700" }
|
||||
|
||||
|
||||
override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/279" }
|
||||
|
||||
|
||||
override predicate matchesRange(string name, Version affected, Version fixed) {
|
||||
(
|
||||
name = "Microsoft.AspNetCore.Mvc.Core"
|
||||
@@ -91,9 +91,9 @@ class CVE_2017_8700 extends Vulnerability {
|
||||
|
||||
class CVE_2018_0765 extends Vulnerability {
|
||||
CVE_2018_0765() { this = "CVE-2018-0765" }
|
||||
|
||||
|
||||
override string getUrl() { result = "https://github.com/dotnet/announcements/issues/67" }
|
||||
|
||||
|
||||
override predicate matchesRange(string name, Version affected, Version fixed) {
|
||||
name = "System.Security.Cryptography.Xml" and
|
||||
affected = "0.0.0" and
|
||||
@@ -103,7 +103,7 @@ class CVE_2018_0765 extends Vulnerability {
|
||||
|
||||
class AspNetCore_Mar18 extends Vulnerability {
|
||||
AspNetCore_Mar18() { this = "ASPNETCore-Mar18" }
|
||||
|
||||
|
||||
override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/300" }
|
||||
|
||||
override predicate matchesRange(string name, Version affected, Version fixed) {
|
||||
@@ -125,9 +125,9 @@ class AspNetCore_Mar18 extends Vulnerability {
|
||||
|
||||
class CVE_2018_8409 extends Vulnerability {
|
||||
CVE_2018_8409() { this = "CVE-2018-8409" }
|
||||
|
||||
|
||||
override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/316" }
|
||||
|
||||
|
||||
override predicate matchesRange(string name, Version affected, Version fixed) {
|
||||
name = "System.IO.Pipelines" and affected = "4.5.0" and fixed = "4.5.1"
|
||||
or
|
||||
@@ -138,9 +138,9 @@ class CVE_2018_8409 extends Vulnerability {
|
||||
|
||||
class CVE_2018_8171 extends Vulnerability {
|
||||
CVE_2018_8171() { this = "CVE-2018-8171" }
|
||||
|
||||
|
||||
override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/310" }
|
||||
|
||||
|
||||
override predicate matchesRange(string name, Version affected, Version fixed) {
|
||||
name = "Microsoft.AspNetCore.Identity" and (
|
||||
affected = "1.0.0" and fixed = "1.0.6"
|
||||
@@ -204,7 +204,7 @@ class CVE_2018_8356 extends Vulnerability {
|
||||
|
||||
class ASPNETCore_Jul18 extends Vulnerability {
|
||||
ASPNETCore_Jul18() { this = "ASPNETCore-July18" }
|
||||
|
||||
|
||||
override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/311" }
|
||||
|
||||
override predicate matchesRange(string name, Version affected, Version fixed) {
|
||||
|
||||
@@ -58,7 +58,34 @@ predicate alwaysDefaultToString(ValueOrRefType t) {
|
||||
)
|
||||
}
|
||||
|
||||
from Expr e, ValueOrRefType t
|
||||
where invokesToString(e, t)
|
||||
and alwaysDefaultToString(t)
|
||||
select e, "Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing.", t, t.getName()
|
||||
newtype TDefaultToStringType =
|
||||
TDefaultToStringType0(ValueOrRefType t) { alwaysDefaultToString(t) }
|
||||
|
||||
class DefaultToStringType extends TDefaultToStringType {
|
||||
ValueOrRefType t;
|
||||
|
||||
DefaultToStringType() { this = TDefaultToStringType0(t) }
|
||||
|
||||
ValueOrRefType getType() { result = t }
|
||||
|
||||
string toString() { result = t.toString() }
|
||||
|
||||
// A workaround for generating empty URLs for non-source locations, because qltest
|
||||
// does not support non-source locations
|
||||
string getURL() {
|
||||
exists(Location l |
|
||||
l = t.getLocation() |
|
||||
if l instanceof SourceLocation then
|
||||
exists(string path, int a, int b, int c, int d |
|
||||
l.hasLocationInfo(path, a, b, c, d) |
|
||||
toUrl(path, a, b, c, d, result)
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from Expr e, DefaultToStringType t
|
||||
where invokesToString(e, t.getType())
|
||||
select e, "Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing.", t, t.getType().getName()
|
||||
|
||||
@@ -23,7 +23,6 @@ class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
override Namespace getParent() { result = this.getParentNamespace() }
|
||||
override Namespace getParentNamespace() { parent_namespace(this, result) }
|
||||
override string getName() { namespaces(this,result) }
|
||||
string getUrl() { result="" }
|
||||
override Location getLocation() { none() }
|
||||
}
|
||||
|
||||
|
||||
@@ -100,7 +100,10 @@ class AssignableRead extends AssignableAccess {
|
||||
* - The read of `this.Field` on line 11 is next to the read on line 10.
|
||||
*/
|
||||
AssignableRead getANextRead() {
|
||||
Ssa::Internal::adjacentReadPairSameVar(this, result)
|
||||
forex(ControlFlow::Node cfn |
|
||||
cfn = result.getAControlFlowNode() |
|
||||
Ssa::Internal::adjacentReadPairSameVar(this.getAControlFlowNode(), cfn)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -113,49 +116,6 @@ class AssignableRead extends AssignableAccess {
|
||||
AssignableRead getAReachableRead() {
|
||||
result = this.getANextRead+()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a next uncertain read of the same underlying assignable. That is,
|
||||
* a read that can be reached from this read without passing through any other
|
||||
* reads, and which *may* read the same value. Example:
|
||||
*
|
||||
* ```
|
||||
* int Field;
|
||||
*
|
||||
* void SetField(int i) {
|
||||
* this.Field = i;
|
||||
* Use(this.Field);
|
||||
* if (i > 0)
|
||||
* this.Field = i - 1;
|
||||
* else if (i < 0)
|
||||
* SetField(1);
|
||||
* Use(this.Field);
|
||||
* Use(this.Field);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* - The read of `i` on line 6 is next to the read on line 4.
|
||||
* - The reads of `i` on lines 7 and 8 are next to the read on line 6.
|
||||
* - The read of `this.Field` on line 10 is next to the read on line 5.
|
||||
* (This is the only truly uncertain read.)
|
||||
* - The read of `this.Field` on line 11 is next to the read on line 10.
|
||||
*/
|
||||
deprecated
|
||||
AssignableRead getANextUncertainRead() {
|
||||
Ssa::Internal::adjacentReadPair(this, result)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a next uncertain read of the same underlying assignable. That is,
|
||||
* a read that can be reached from this read, and which *may* read the same
|
||||
* value.
|
||||
*
|
||||
* This is the transitive closure of `getANextUncertainRead()`.
|
||||
*/
|
||||
deprecated
|
||||
AssignableRead getAReachableUncertainRead() {
|
||||
result = this.getANextUncertainRead+()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -484,9 +444,11 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
*/
|
||||
Expr getExpr() { none() }
|
||||
|
||||
/** DEPRECATED: Use `getAControlFlowNode()` instead. */
|
||||
deprecated
|
||||
ControlFlow::Node getControlFlowNode() { result = this.getAControlFlowNode() }
|
||||
/**
|
||||
* Gets the underlying element associated with this definition. This is either
|
||||
* an expression or a parameter.
|
||||
*/
|
||||
Element getElement() { result = this.getExpr() }
|
||||
|
||||
/** Gets the enclosing callable of this definition. */
|
||||
Callable getEnclosingCallable() { result = this.getExpr().getEnclosingCallable() }
|
||||
@@ -543,9 +505,12 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
* `AssignableRead.getANextRead()`.
|
||||
*/
|
||||
AssignableRead getAFirstRead() {
|
||||
exists(Ssa::ExplicitDefinition def |
|
||||
def.getADefinition() = this |
|
||||
result = def.getAFirstRead()
|
||||
forex(ControlFlow::Node cfn |
|
||||
cfn = result.getAControlFlowNode() |
|
||||
exists(Ssa::ExplicitDefinition def |
|
||||
result = def.getAFirstReadAtNode(cfn) |
|
||||
this = def.getADefinition()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -560,56 +525,6 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
result = this.getAFirstRead().getANextRead*()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a first uncertain read of the same underlying assignable. That is,
|
||||
* a read that can be reached from this definition without passing through any
|
||||
* other reads, and which *may* read the value assigned in this definition.
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
* int Field;
|
||||
*
|
||||
* void SetField(int i) {
|
||||
* this.Field = i;
|
||||
* Use(this.Field);
|
||||
* if (i > 0)
|
||||
* this.Field = i - 1;
|
||||
* else if (i < 0)
|
||||
* SetField(1);
|
||||
* Use(this.Field);
|
||||
* Use(this.Field);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* - The read of `i` on line 4 is a first read of the implicit parameter definition
|
||||
* on line 3.
|
||||
* - The read of `this.Field` on line 5 is a first read of the definition on line 4.
|
||||
* - The read of `this.Field` on line 10 is a first read of the definition on
|
||||
* line 7. (This is the only truly uncertain read.)
|
||||
*
|
||||
* Subsequent uncertain reads can be found by following the steps defined by
|
||||
* `AssignableRead.getANextUncertainRead()`.
|
||||
*/
|
||||
deprecated
|
||||
AssignableRead getAFirstUncertainRead() {
|
||||
exists(Ssa::ExplicitDefinition def |
|
||||
def.getADefinition() = this |
|
||||
result = def.getAFirstUncertainRead()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reachable uncertain read of the same underlying assignable. That is,
|
||||
* a read that can be reached from this definition, and which *may* read the
|
||||
* value assigned in this definition.
|
||||
*
|
||||
* This is the equivalent with `getAFirstUncertainRead().getANextUncertainRead*()`.
|
||||
*/
|
||||
deprecated
|
||||
AssignableRead getAReachableUncertainRead() {
|
||||
result = this.getAFirstUncertainRead().getANextUncertainRead*()
|
||||
}
|
||||
|
||||
/** Gets a textual representation of this assignable definition. */
|
||||
string toString() { none() }
|
||||
|
||||
@@ -800,6 +715,8 @@ module AssignableDefinitions {
|
||||
result = p.getCallable().getEntryPoint()
|
||||
}
|
||||
|
||||
override Parameter getElement() { result = p }
|
||||
|
||||
override Callable getEnclosingCallable() {
|
||||
result = p.getCallable()
|
||||
}
|
||||
|
||||
@@ -22,7 +22,10 @@ class Element extends DotNet::Element, @element {
|
||||
* Where an element has multiple locations (for example a source file and an assembly),
|
||||
* gets only the source location.
|
||||
*/
|
||||
override Location getLocation() { result = bestLocation(this) }
|
||||
override Location getLocation() { result = ExprOrStmtParentCached::bestLocation(this) }
|
||||
|
||||
/** Gets the URL of this element. */
|
||||
string getURL() { result = ExprOrStmtParentCached::getURL(this) }
|
||||
|
||||
/** Gets a location of this element, including sources and assemblies. */
|
||||
override Location getALocation() { none() }
|
||||
|
||||
@@ -346,7 +346,7 @@ private int getImplementationSize(ValueOrRefType t, File f) {
|
||||
result = getImplementationSize1(t, f)
|
||||
}
|
||||
|
||||
private cached module Cached {
|
||||
cached module ExprOrStmtParentCached {
|
||||
cached
|
||||
ControlFlowElement getTopLevelChild(ExprOrStmtParent p, int i) {
|
||||
result = p.(MultiImplementationsParent).getBestChild(i)
|
||||
@@ -363,7 +363,7 @@ private cached module Cached {
|
||||
* in `f`.
|
||||
*/
|
||||
cached
|
||||
predicate mustHaveLocationInFileCached(Declaration d, File f) {
|
||||
predicate mustHaveLocationInFile(Declaration d, File f) {
|
||||
exists(MultiImplementationsParent p, ValueOrRefType t |
|
||||
t = getTopLevelDeclaringType(p) and
|
||||
f = p.getBestFile() |
|
||||
@@ -381,7 +381,7 @@ private cached module Cached {
|
||||
* locations, choose only one.
|
||||
*/
|
||||
cached
|
||||
Location bestLocationCached(Element e) {
|
||||
Location bestLocation(Element e) {
|
||||
result = e.getALocation().(SourceLocation) and
|
||||
(mustHaveLocationInFile(e, _) implies mustHaveLocationInFile(e, result.getFile()))
|
||||
or
|
||||
@@ -391,8 +391,17 @@ private cached module Cached {
|
||||
result = min(Location l | l = e.getALocation() | l order by l.getFile().toString())
|
||||
)
|
||||
}
|
||||
}
|
||||
private import Cached
|
||||
|
||||
predicate mustHaveLocationInFile = mustHaveLocationInFileCached/2;
|
||||
predicate bestLocation = bestLocationCached/1;
|
||||
cached
|
||||
string getURL(Element e) {
|
||||
exists(Location l, string path, int a, int b, int c, int d |
|
||||
l = bestLocation(e) |
|
||||
l.hasLocationInfo(path, a, b, c, d) and
|
||||
toUrl(path, a, b, c, d, result)
|
||||
)
|
||||
or
|
||||
not exists(bestLocation(e)) and
|
||||
result = ""
|
||||
}
|
||||
}
|
||||
private import ExprOrStmtParentCached
|
||||
|
||||
@@ -37,24 +37,16 @@ class Location extends @location
|
||||
string toString() { none() }
|
||||
|
||||
/** Gets the start line of this location. */
|
||||
int getStartLine() {
|
||||
locations_default(this,_,result,_,_,_)
|
||||
}
|
||||
final int getStartLine() { this.hasLocationInfo(_, result, _, _, _) }
|
||||
|
||||
/** Gets the end line of this location. */
|
||||
int getEndLine() {
|
||||
locations_default(this,_,_,_,result,_)
|
||||
}
|
||||
final int getEndLine() { this.hasLocationInfo(_, _, _, result, _) }
|
||||
|
||||
/** Gets the start column of this location. */
|
||||
int getStartColumn() {
|
||||
locations_default(this,_,_,result,_,_)
|
||||
}
|
||||
final int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) }
|
||||
|
||||
/** Gets the end column of this location. */
|
||||
int getEndColumn() {
|
||||
locations_default(this,_,_,_,_,result)
|
||||
}
|
||||
final int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,17 +36,6 @@ class Declaration extends DotNet::Declaration, Element, @declaration {
|
||||
result = this.getDeclaringType().getQualifiedName() + "." + this.toStringWithTypes()
|
||||
}
|
||||
|
||||
/** Define URL for declarations with no location. */
|
||||
string getURL() {
|
||||
if exists(this.getLocation()) then
|
||||
exists(string path, int a, int b, int c, int d |
|
||||
this.getLocation().hasLocationInfo(path, a, b, c, d) |
|
||||
toUrl(path, a, b, c, d, result)
|
||||
)
|
||||
else
|
||||
result = ""
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this declaration has been generated by the compiler, for example
|
||||
* implicit constructors or accessors.
|
||||
|
||||
@@ -112,8 +112,12 @@ class Namespace extends DotNet::Namespace, TypeContainer, @namespace {
|
||||
|
||||
override predicate fromLibrary() { not this.fromSource() }
|
||||
|
||||
/** Gets the URL of this namespace (which is empty in this case). */
|
||||
string getURL() { result = "" }
|
||||
/** Gets a declaration of this namespace, if any. */
|
||||
NamespaceDeclaration getADeclaration() { result.getNamespace() = this }
|
||||
|
||||
override Location getALocation() {
|
||||
result = this.getADeclaration().getALocation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,7 +197,7 @@ class NamespaceDeclaration extends Element, @namespace_declaration {
|
||||
*/
|
||||
ValueOrRefType getATypeDeclaration() { parent_namespace_declaration(result, this) }
|
||||
|
||||
override Location getALocation() { none() }
|
||||
override Location getALocation() { namespace_declaration_location(this, result) }
|
||||
|
||||
override string toString() { result = "namespace ... { ... }" }
|
||||
}
|
||||
|
||||
@@ -1190,22 +1190,6 @@ class UsingStmt extends Stmt, @using_stmt {
|
||||
/** Gets a local variable declaration of this `using` statement. */
|
||||
LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) }
|
||||
|
||||
/** DEPRECATED: Use `getVariable(0)` instead. */
|
||||
deprecated
|
||||
LocalVariable getVariable() { result = getVariableDeclExpr().getVariable() }
|
||||
|
||||
/** DEPRECATED: Use `getAVariableDeclExpr()` instead. */
|
||||
deprecated
|
||||
LocalVariableDeclExpr getVariableDeclExpr() { result.getParent() = this }
|
||||
|
||||
/** DEPRECATED: Use `getAnExpr()` instead. */
|
||||
deprecated Expr getInitializer() {
|
||||
if exists(this.getVariableDeclExpr(0)) then
|
||||
result = this.getVariableDeclExpr(0).getInitializer()
|
||||
else
|
||||
result.getParent() = this
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the expression directly used by this `using` statement, if any. For
|
||||
* example, `f` on line 2 in
|
||||
@@ -1389,14 +1373,6 @@ class FixedStmt extends Stmt, @fixed_stmt {
|
||||
/** Gets a local variable declaration of this `fixed` statement. */
|
||||
LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) }
|
||||
|
||||
/** DEPRECATED: Use `getVariable(0)` instead. */
|
||||
deprecated
|
||||
LocalVariable getVariable() { result = getVariableDeclExpr().getVariable() }
|
||||
|
||||
/** DEPRECATED: Use `getVariableDeclExpr(0) instead. */
|
||||
deprecated
|
||||
LocalVariableDeclExpr getVariableDeclExpr() { result.getParent() = this }
|
||||
|
||||
/** Gets the body of this `fixed` statement. */
|
||||
Stmt getBody() { result.getParent() = this }
|
||||
|
||||
@@ -1441,10 +1417,6 @@ class LabeledStmt extends Stmt, @labeled_stmt {
|
||||
and result = this.getParent().getChild(i+1))
|
||||
}
|
||||
|
||||
/** DEPRECATED: Use `getStmt()` instead. */
|
||||
deprecated
|
||||
Stmt getReferredStatement() { result = this.getStmt() }
|
||||
|
||||
/** Gets the label of this statement. */
|
||||
string getLabel() { exprorstmt_name(this, result) }
|
||||
|
||||
|
||||
@@ -134,12 +134,6 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
result.hasName(name)
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `hasMethod()` instead.
|
||||
*/
|
||||
deprecated
|
||||
predicate inheritsMethod(Method m) { this.hasMethod(m) }
|
||||
|
||||
/**
|
||||
* Holds if this type has method `m`, that is, either `m` is declared in this
|
||||
* type, or `m` is inherited by this type.
|
||||
@@ -164,14 +158,6 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
*/
|
||||
predicate hasMethod(Method m) { this.hasMember(m) }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `hasCallable()` instead.
|
||||
*/
|
||||
deprecated
|
||||
predicate inheritsCallable(Callable c) {
|
||||
this.hasCallable(c)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type has callable `c`, that is, either `c` is declared in this
|
||||
* type, or `c` is inherited by this type.
|
||||
@@ -202,14 +188,6 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_
|
||||
hasMember(c.(Accessor).getDeclaration())
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `hasMember()` instead.
|
||||
*/
|
||||
deprecated
|
||||
predicate inheritsMember(Member m) {
|
||||
this.hasMember(m)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this type has member `m`, that is, either `m` is declared in this
|
||||
* type, or `m` is inherited by this type.
|
||||
@@ -751,7 +729,6 @@ class Class extends RefType, @class_type {
|
||||
* ```
|
||||
*/
|
||||
class AnonymousClass extends Class {
|
||||
|
||||
AnonymousClass() { this.getName().matches("<%") }
|
||||
}
|
||||
|
||||
@@ -809,8 +786,7 @@ class DelegateType extends RefType, Parameterizable, @delegate_type {
|
||||
/**
|
||||
* The `null` type. The type of the `null` literal.
|
||||
*/
|
||||
class NullType extends RefType, @null_type {
|
||||
}
|
||||
class NullType extends RefType, @null_type { }
|
||||
|
||||
/**
|
||||
* A nullable type, for example `int?`.
|
||||
@@ -891,6 +867,13 @@ class ArrayType extends DotNet::ArrayType, RefType, @array_type {
|
||||
}
|
||||
|
||||
override Type getChild(int n) { result = getElementType() and n = 0 }
|
||||
|
||||
override Location getALocation() {
|
||||
type_location(this, result)
|
||||
or
|
||||
not type_location(this, _) and
|
||||
result = this.getElementType().getALocation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -78,19 +78,6 @@ class XMLParent extends @xmlparent {
|
||||
result = count(int pos | xmlChars(_,_,this,pos,_,_))
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Internal.
|
||||
*
|
||||
* Append the character sequences of this XML parent from left to right, separated by a space,
|
||||
* up to a specified (zero-based) index.
|
||||
*/
|
||||
deprecated
|
||||
string charsSetUpTo(int n) {
|
||||
(n = 0 and xmlChars(_,result,this,0,_,_)) or
|
||||
(n > 0 and exists(string chars | xmlChars(_,chars,this,n,_,_) |
|
||||
result = this.charsSetUpTo(n-1) + " " + chars))
|
||||
}
|
||||
|
||||
/** Append all the character sequences of this XML parent from left to right, separated by a space. */
|
||||
string allCharactersString() {
|
||||
result = concat(string chars, int pos | xmlChars(_, chars, this, pos, _, _) | chars, " " order by pos)
|
||||
|
||||
@@ -51,6 +51,9 @@ class Assertion extends MethodCall {
|
||||
|
||||
pragma[nomagic]
|
||||
private JoinBlockPredecessor getAPossiblyDominatedPredecessor(JoinBlock jb) {
|
||||
// Only calculate dominance by explicit recursion for split nodes;
|
||||
// all other nodes can use regular CFG dominance
|
||||
this instanceof ControlFlow::Internal::SplitControlFlowElement and
|
||||
exists(BasicBlock bb |
|
||||
bb = this.getAControlFlowNode().getBasicBlock() |
|
||||
result = bb.getASuccessor*()
|
||||
@@ -70,6 +73,22 @@ class Assertion extends MethodCall {
|
||||
)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
private predicate strictlyDominatesSplit(BasicBlock bb) {
|
||||
this.getAControlFlowNode().getBasicBlock().immediatelyDominates(bb)
|
||||
or
|
||||
if bb instanceof JoinBlock then
|
||||
this.isPossiblyDominatedJoinBlock(bb) and
|
||||
forall(BasicBlock pred |
|
||||
pred = this.getAPossiblyDominatedPredecessor(bb) |
|
||||
this.strictlyDominatesSplit(pred)
|
||||
or
|
||||
this.getAControlFlowNode().getBasicBlock() = pred
|
||||
)
|
||||
else
|
||||
this.strictlyDominatesSplit(bb.getAPredecessor())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this assertion strictly dominates basic block `bb`. That is, `bb`
|
||||
* can only be reached from the callable entry point by going via *some* basic
|
||||
@@ -81,18 +100,9 @@ class Assertion extends MethodCall {
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate strictlyDominates(BasicBlock bb) {
|
||||
this.getAControlFlowNode().getBasicBlock().immediatelyDominates(bb)
|
||||
this.strictlyDominatesSplit(bb)
|
||||
or
|
||||
if bb instanceof JoinBlock then
|
||||
this.isPossiblyDominatedJoinBlock(bb) and
|
||||
forall(BasicBlock pred |
|
||||
pred = this.getAPossiblyDominatedPredecessor(bb) |
|
||||
this.strictlyDominates(pred)
|
||||
or
|
||||
this.getAControlFlowNode().getBasicBlock() = pred
|
||||
)
|
||||
else
|
||||
this.strictlyDominates(bb.getAPredecessor())
|
||||
this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -473,6 +473,7 @@ class ConditionBlock extends BasicBlock {
|
||||
* successor of this block, and `succ` can only be reached from
|
||||
* the callable entry point by going via the `s` edge out of this basic block.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate immediatelyControls(BasicBlock succ, ConditionalSuccessor s) {
|
||||
succ = this.getASuccessorByType(s) and
|
||||
forall(BasicBlock pred |
|
||||
|
||||
@@ -79,12 +79,23 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
* `pred` ending with this element, and `pred` is an immediate predecessor
|
||||
* of `succ`.
|
||||
*
|
||||
* This predicate is different from
|
||||
* `this.getAControlFlowNode().getBasicBlock().(ConditionBlock).immediatelyControls(succ, s)`
|
||||
* in that it takes control flow splitting into account.
|
||||
* Moreover, this control flow element corresponds to multiple control flow nodes,
|
||||
* which is why
|
||||
*
|
||||
* ```
|
||||
* exists(ConditionBlock cb |
|
||||
* cb.getLastNode() = this.getAControlFlowNode() |
|
||||
* cb.immediatelyControls(succ, s)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* does not work.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate immediatelyControls(BasicBlock succ, ConditionalSuccessor s) {
|
||||
private predicate immediatelyControlsBlockSplit(BasicBlock succ, ConditionalSuccessor s) {
|
||||
// Only calculate dominance by explicit recursion for split nodes;
|
||||
// all other nodes can use regular CFG dominance
|
||||
this instanceof ControlFlow::Internal::SplitControlFlowElement and
|
||||
exists(ConditionBlock cb |
|
||||
cb.getLastNode() = this.getAControlFlowNode() |
|
||||
succ = cb.getASuccessorByType(s) and
|
||||
@@ -103,7 +114,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
pragma[nomagic]
|
||||
private JoinBlockPredecessor getAPossiblyControlledPredecessor(JoinBlock controlled, ConditionalSuccessor s) {
|
||||
exists(BasicBlock mid |
|
||||
this.immediatelyControls(mid, s) |
|
||||
this.immediatelyControlsBlockSplit(mid, s) |
|
||||
result = mid.getASuccessor*()
|
||||
) and
|
||||
result.getASuccessor() = controlled and
|
||||
@@ -121,19 +132,9 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if basic block `controlled` is controlled by this control flow element
|
||||
* with conditional value `s`. That is, `controlled` can only be reached from
|
||||
* the callable entry point by going via the `s` edge out of *some* basic block
|
||||
* ending with this element.
|
||||
*
|
||||
* This predicate is different from
|
||||
* `this.getAControlFlowNode().getBasicBlock().(ConditionBlock).controls(controlled, s)`
|
||||
* in that it takes control flow splitting into account.
|
||||
*/
|
||||
cached
|
||||
predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) {
|
||||
this.immediatelyControls(controlled, s)
|
||||
private predicate controlsBlockSplit(BasicBlock controlled, ConditionalSuccessor s) {
|
||||
this.immediatelyControlsBlockSplit(controlled, s)
|
||||
or
|
||||
if controlled instanceof JoinBlock then
|
||||
this.isPossiblyControlledJoinBlock(controlled, s) and
|
||||
@@ -142,7 +143,33 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
this.controlsBlock(pred, s)
|
||||
)
|
||||
else
|
||||
this.controlsBlock(controlled.getAPredecessor(), s)
|
||||
this.controlsBlockSplit(controlled.getAPredecessor(), s)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if basic block `controlled` is controlled by this control flow element
|
||||
* with conditional value `s`. That is, `controlled` can only be reached from
|
||||
* the callable entry point by going via the `s` edge out of *some* basic block
|
||||
* ending with this element.
|
||||
*
|
||||
* This predicate is different from
|
||||
*
|
||||
* ```
|
||||
* exists(ConditionBlock cb |
|
||||
* cb.getLastNode() = this.getAControlFlowNode() |
|
||||
* cb.controls(controlled, s)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* as control flow splitting is taken into account.
|
||||
*/
|
||||
predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) {
|
||||
this.controlsBlockSplit(controlled, s)
|
||||
or
|
||||
exists(ConditionBlock cb |
|
||||
cb.getLastNode() = this.getAControlFlowNode() |
|
||||
cb.controls(controlled, s)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -151,8 +178,15 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element {
|
||||
* from the callable entry point by going via the `s` edge out of this element.
|
||||
*
|
||||
* This predicate is different from
|
||||
* `this.getAControlFlowNode().getBasicBlock().(ConditionBlock).controls(controlled.getAControlFlowNode().getBasicBlock(), s)`
|
||||
* in that it takes control flow splitting into account.
|
||||
*
|
||||
* ```
|
||||
* exists(ConditionBlock cb |
|
||||
* cb.getLastNode() = this.getAControlFlowNode() |
|
||||
* cb.controls(controlled.getAControlFlowNode().getBasicBlock(), s)
|
||||
* )
|
||||
* ```
|
||||
*
|
||||
* as control flow splitting is taken into account.
|
||||
*/
|
||||
pragma[inline] // potentially very large predicate, so must be inlined
|
||||
predicate controlsElement(ControlFlowElement controlled, ConditionalSuccessor s) {
|
||||
|
||||
@@ -4198,6 +4198,13 @@ module ControlFlow {
|
||||
}
|
||||
}
|
||||
import Cached
|
||||
|
||||
/** A control flow element that is split into multiple control flow nodes. */
|
||||
class SplitControlFlowElement extends ControlFlowElement {
|
||||
SplitControlFlowElement() {
|
||||
strictcount(this.getAControlFlowNode()) > 1
|
||||
}
|
||||
}
|
||||
}
|
||||
private import Internal
|
||||
}
|
||||
|
||||
@@ -286,7 +286,7 @@ class DereferenceableExpr extends Expr {
|
||||
ie = any(IsTypeExpr ite | ite.getCheckedType() = ite.getExpr().getType()) and
|
||||
branch = false and
|
||||
isNull = true
|
||||
)
|
||||
)
|
||||
)
|
||||
or
|
||||
this.hasNullableType() and
|
||||
@@ -578,8 +578,12 @@ module Internal {
|
||||
*/
|
||||
Expr getNullEquivParent(Expr e) {
|
||||
result = any(QualifiableExpr qe |
|
||||
qe.getQualifier() = e and
|
||||
qe.isConditional() and
|
||||
(
|
||||
e = qe.getQualifier()
|
||||
or
|
||||
e = qe.(ExtensionMethodCall).getArgument(0)
|
||||
) and
|
||||
(
|
||||
// The accessed declaration must have a value type in order
|
||||
// for `only if` to hold
|
||||
@@ -690,7 +694,7 @@ module Internal {
|
||||
predicate preControls(PreBasicBlocks::PreBasicBlock bb, AbstractValue v) {
|
||||
exists(AbstractValue v0, Guard g |
|
||||
g.preControlsDirect(bb, v0) |
|
||||
impliesSteps(g, v0, this, v)
|
||||
preImpliesSteps(g, v0, this, v)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -777,7 +781,7 @@ module Internal {
|
||||
def.nullGuardedReturn(ret, isNull)
|
||||
or
|
||||
exists(NullValue nv |
|
||||
impliesSteps(ret, retVal, def.getARead(), nv) |
|
||||
preImpliesSteps(ret, retVal, def.getARead(), nv) |
|
||||
if nv.isNull() then isNull = true else isNull = false
|
||||
)
|
||||
)
|
||||
@@ -1119,6 +1123,28 @@ module Internal {
|
||||
def = guarded.getAnSsaQualifier()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the assumption that `g1` has abstract value `v1` implies that
|
||||
* `g2` has abstract value `v2`, using one step of reasoning. That is, the
|
||||
* evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`.
|
||||
*
|
||||
* This predicate relies on the control flow graph.
|
||||
*/
|
||||
cached
|
||||
predicate impliesStep(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) {
|
||||
preImpliesStep(g1, v1, g2, v2)
|
||||
or
|
||||
forex(ControlFlow::Node cfn |
|
||||
cfn = g1.getAControlFlowNode() |
|
||||
exists(Ssa::ExplicitDefinition def |
|
||||
def.getADefinition().getSource() = g2 |
|
||||
g1 = def.getAReadAtNode(cfn) and
|
||||
v1 = g1.getAValue() and
|
||||
v2 = v1
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
import Cached
|
||||
|
||||
@@ -1139,9 +1165,11 @@ module Internal {
|
||||
* Holds if the assumption that `g1` has abstract value `v1` implies that
|
||||
* `g2` has abstract value `v2`, using one step of reasoning. That is, the
|
||||
* evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`.
|
||||
*
|
||||
* This predicate does not rely on the control flow graph.
|
||||
*/
|
||||
cached
|
||||
predicate impliesStep(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) {
|
||||
predicate preImpliesStep(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) {
|
||||
g1 = any(BinaryOperation bo |
|
||||
(
|
||||
bo instanceof BitwiseAndExpr or
|
||||
@@ -1189,7 +1217,7 @@ module Internal {
|
||||
g1 = cond and
|
||||
v1 = v.getDualValue() and
|
||||
(
|
||||
// g1 === g2 ? e : ...;
|
||||
// g1 === g2 ? e : ...;
|
||||
g2 = cond.getCondition() and
|
||||
v2 = TBooleanValue(branch.booleanNot())
|
||||
or
|
||||
@@ -1275,6 +1303,26 @@ module Internal {
|
||||
* Holds if the assumption that `g1` has abstract value `v1` implies that
|
||||
* `g2` has abstract value `v2`, using zero or more steps of reasoning. That is,
|
||||
* the evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`.
|
||||
*
|
||||
* This predicate does not rely on the control flow graph.
|
||||
*/
|
||||
predicate preImpliesSteps(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) {
|
||||
g1 = g2 and
|
||||
v1 = v2 and
|
||||
v1 = g1.getAValue()
|
||||
or
|
||||
exists(Expr mid, AbstractValue vMid |
|
||||
preImpliesSteps(g1, v1, mid, vMid) |
|
||||
preImpliesStep(mid, vMid, g2, v2)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the assumption that `g1` has abstract value `v1` implies that
|
||||
* `g2` has abstract value `v2`, using zero or more steps of reasoning. That is,
|
||||
* the evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`.
|
||||
*
|
||||
* This predicate relies on the control flow graph.
|
||||
*/
|
||||
predicate impliesSteps(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) {
|
||||
g1 = g2 and
|
||||
|
||||
@@ -28,6 +28,7 @@ module DataFlow {
|
||||
DotNet::Type getType() { none() }
|
||||
|
||||
/** Gets the enclosing callable of this node. */
|
||||
cached
|
||||
DotNet::Callable getEnclosingCallable() { none() }
|
||||
|
||||
/** Gets a textual representation of this node. */
|
||||
@@ -52,9 +53,19 @@ module DataFlow {
|
||||
|
||||
override DotNet::Callable getEnclosingCallable() { result = expr.getEnclosingCallable() }
|
||||
|
||||
override string toString() { result = expr.toString() }
|
||||
override string toString() {
|
||||
result = expr.(Expr).toString()
|
||||
or
|
||||
expr instanceof CIL::Expr and
|
||||
result = "CIL expression"
|
||||
}
|
||||
|
||||
override Location getLocation() { result = expr.getLocation() }
|
||||
override Location getLocation() {
|
||||
result = expr.(Expr).getLocation()
|
||||
or
|
||||
result.getFile().isPdbSourceFile() and
|
||||
result = expr.(CIL::Expr).getALocation()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +101,7 @@ module DataFlow {
|
||||
localFlowStep*(source, sink)
|
||||
}
|
||||
|
||||
predicate localFlowStep = localFlowStepCached/2;
|
||||
predicate localFlowStep = Internal::LocalFlow::step/2;
|
||||
|
||||
/**
|
||||
* A data flow node augmented with a call context and a configuration. Only
|
||||
@@ -690,12 +701,14 @@ module DataFlow {
|
||||
/**
|
||||
* Provides predicates related to local data flow.
|
||||
*/
|
||||
private module LocalFlow {
|
||||
module LocalFlow {
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
*/
|
||||
predicate localFlowStepNonCached(Node nodeFrom, Node nodeTo) {
|
||||
cached
|
||||
predicate step(Node nodeFrom, Node nodeTo) {
|
||||
forceCachingInSameStage() and
|
||||
localFlowStepExpr(nodeFrom.asExpr(), nodeTo.asExpr())
|
||||
or
|
||||
// Flow from source to SSA definition
|
||||
@@ -1119,6 +1132,8 @@ module DataFlow {
|
||||
* same stage.
|
||||
*/
|
||||
cached module Cached {
|
||||
cached predicate forceCachingInSameStage() { any() }
|
||||
|
||||
cached newtype TNode =
|
||||
TExprNode(DotNet::Expr e)
|
||||
or
|
||||
@@ -1137,14 +1152,6 @@ module DataFlow {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local
|
||||
* (intra-procedural) step.
|
||||
*/
|
||||
cached predicate localFlowStepCached(Node nodeFrom, Node nodeTo) {
|
||||
LocalFlow::localFlowStepNonCached(nodeFrom, nodeTo)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `pred` can flow to `succ`, by jumping from one callable to
|
||||
* another.
|
||||
|
||||
@@ -39,6 +39,8 @@ class MaybeNullExpr extends Expr {
|
||||
this.(AssignExpr).getRValue() instanceof MaybeNullExpr
|
||||
or
|
||||
this.(Cast).getExpr() instanceof MaybeNullExpr
|
||||
or
|
||||
this instanceof AsExpr
|
||||
}
|
||||
}
|
||||
|
||||
@@ -147,6 +149,15 @@ private ControlFlowElement getANullCheck(Ssa::Definition def, SuccessorTypes::Co
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isMaybeNullArgument(Ssa::ExplicitDefinition def, MaybeNullExpr arg) {
|
||||
exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p |
|
||||
pdef = def.getADefinition() |
|
||||
p = pdef.getParameter().getSourceDeclaration() and
|
||||
p.getAnAssignedArgument() = arg and
|
||||
not arg.getEnclosingCallable().getEnclosingCallable*() instanceof TestMethod
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `def` is an SSA definition that may be `null`. */
|
||||
private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) {
|
||||
// A variable compared to `null` might be `null`
|
||||
@@ -154,21 +165,20 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason)
|
||||
de = def.getARead() |
|
||||
reason = de.getANullCheck(_, true) and
|
||||
msg = "as suggested by $@ null check" and
|
||||
not def instanceof Ssa::PseudoDefinition and
|
||||
not de = any(Ssa::PseudoDefinition pdef).getARead() and
|
||||
strictcount(Element e |
|
||||
e = any(Ssa::Definition def0 | de = def0.getARead()).getElement()
|
||||
) = 1 and
|
||||
not nonNullDef(def) and
|
||||
// Don't use a check as reason if there is a `null` assignment
|
||||
not def.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof MaybeNullExpr
|
||||
// or argument
|
||||
not def.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof MaybeNullExpr and
|
||||
not isMaybeNullArgument(def, _)
|
||||
)
|
||||
or
|
||||
// A parameter might be `null` if there is a `null` argument somewhere
|
||||
exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p, MaybeNullExpr arg |
|
||||
pdef = def.(Ssa::ExplicitDefinition).getADefinition() |
|
||||
p = pdef.getParameter().getSourceDeclaration() and
|
||||
p.getAnAssignedArgument() = arg and
|
||||
reason = arg and
|
||||
msg = "because of $@ null argument" and
|
||||
not arg.getEnclosingCallable().getEnclosingCallable*() instanceof TestMethod
|
||||
)
|
||||
isMaybeNullArgument(def, reason) and
|
||||
msg = "because of $@ null argument"
|
||||
or
|
||||
// If the source of a variable is `null` then the variable may be `null`
|
||||
exists(AssignableDefinition adef |
|
||||
@@ -199,12 +209,12 @@ private predicate defNullImpliesStep(Ssa::Definition def1, BasicBlock bb1, Ssa::
|
||||
def1.getSourceVariable() = v
|
||||
|
|
||||
def2.(Ssa::PseudoDefinition).getAnInput() = def1 and
|
||||
def2.definesAt(bb2, _)
|
||||
bb2 = def2.getBasicBlock()
|
||||
or
|
||||
def2 = def1 and
|
||||
not exists(Ssa::PseudoDefinition def |
|
||||
def.getSourceVariable() = v and
|
||||
def.definesAt(bb2, _)
|
||||
bb2 = def.getBasicBlock()
|
||||
)
|
||||
) and
|
||||
def1.isLiveAtEndOfBlock(bb1) and
|
||||
@@ -221,13 +231,12 @@ private predicate defNullImpliesStep(Ssa::Definition def1, BasicBlock bb1, Ssa::
|
||||
* The transitive closure of `defNullImpliesStep()` originating from `defMaybeNull()`.
|
||||
* That is, those basic blocks for which the SSA definition is suspected of being `null`.
|
||||
*/
|
||||
private predicate defMaybeNullInBlock(Ssa::Definition def, Ssa::SourceVariable v, BasicBlock bb) {
|
||||
private predicate defMaybeNullInBlock(Ssa::Definition def, BasicBlock bb) {
|
||||
defMaybeNull(def, _, _) and
|
||||
def.definesAt(bb, _) and
|
||||
v = def.getSourceVariable()
|
||||
bb = def.getBasicBlock()
|
||||
or
|
||||
exists(BasicBlock mid, Ssa::Definition midDef |
|
||||
defMaybeNullInBlock(midDef, v, mid) |
|
||||
defMaybeNullInBlock(midDef, mid) |
|
||||
defNullImpliesStep(midDef, mid, def, bb)
|
||||
)
|
||||
}
|
||||
@@ -239,20 +248,167 @@ private predicate defMaybeNullInBlock(Ssa::Definition def, Ssa::SourceVariable v
|
||||
private predicate nullDerefCandidateVariable(Ssa::SourceVariable v) {
|
||||
exists(Ssa::Definition def, BasicBlock bb |
|
||||
potentialNullDereferenceAt(bb, _, def, _) |
|
||||
defMaybeNullInBlock(def, v, bb)
|
||||
defMaybeNullInBlock(def, bb) and
|
||||
v = def.getSourceVariable()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate defMaybeNullInBlockOrigin(Ssa::Definition origin, Ssa::Definition def, BasicBlock bb) {
|
||||
nullDerefCandidateVariable(def.getSourceVariable()) and
|
||||
defMaybeNull(def, _, _) and
|
||||
def.definesAt(bb, _) and
|
||||
origin = def
|
||||
private predicate succStep(PathNode pred, Ssa::Definition def, BasicBlock bb) {
|
||||
defNullImpliesStep(pred.getSsaDefinition(), pred.getBasicBlock(), def, bb)
|
||||
}
|
||||
|
||||
private predicate succNullArgument(SourcePathNode pred, Ssa::Definition def, BasicBlock bb) {
|
||||
pred = TSourcePathNode(def, _, _, true) and
|
||||
bb = def.getBasicBlock()
|
||||
}
|
||||
|
||||
private predicate succSourceSink(SourcePathNode source, Ssa::Definition def, BasicBlock bb) {
|
||||
source = TSourcePathNode(def, _, _, false) and
|
||||
bb = def.getBasicBlock()
|
||||
}
|
||||
|
||||
private newtype TPathNode =
|
||||
TSourcePathNode(Ssa::Definition def, string msg, Element reason, boolean isNullArgument) {
|
||||
nullDerefCandidateVariable(def.getSourceVariable()) and
|
||||
defMaybeNull(def, msg, reason) and
|
||||
if isMaybeNullArgument(def, reason) then isNullArgument = true else isNullArgument = false
|
||||
}
|
||||
or
|
||||
exists(BasicBlock mid, Ssa::Definition midDef |
|
||||
defMaybeNullInBlockOrigin(origin, midDef, mid) and
|
||||
defNullImpliesStep(midDef, mid, def, bb)
|
||||
)
|
||||
TInternalPathNode(Ssa::Definition def, BasicBlock bb) {
|
||||
succStep(_, def, bb)
|
||||
or
|
||||
succNullArgument(_, def, bb)
|
||||
}
|
||||
or
|
||||
TSinkPathNode(Ssa::Definition def, BasicBlock bb, int i, Dereference d) {
|
||||
potentialNullDereferenceAt(bb, i, def, d) and
|
||||
(
|
||||
succStep(_, def, bb)
|
||||
or
|
||||
succNullArgument(_, def, bb)
|
||||
or
|
||||
succSourceSink(_, def, bb)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* An SSA definition, which may be `null`, augmented with at basic block which can
|
||||
* be reached without passing through a `null` check.
|
||||
*/
|
||||
abstract class PathNode extends TPathNode {
|
||||
/** Gets the SSA definition. */
|
||||
abstract Ssa::Definition getSsaDefinition();
|
||||
|
||||
/** Gets the basic block that can be reached without passing through a `null` check. */
|
||||
abstract BasicBlock getBasicBlock();
|
||||
|
||||
/** Gets another node that can be reached from this node. */
|
||||
abstract PathNode getASuccessor();
|
||||
|
||||
/** Gets a textual representation of this node. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the location of this node. */
|
||||
abstract Location getLocation();
|
||||
}
|
||||
|
||||
private class SourcePathNode extends PathNode, TSourcePathNode {
|
||||
private Ssa::Definition def;
|
||||
private string msg;
|
||||
private Element reason;
|
||||
private boolean isNullArgument;
|
||||
|
||||
SourcePathNode() { this = TSourcePathNode(def, msg, reason, isNullArgument) }
|
||||
|
||||
override Ssa::Definition getSsaDefinition() { result = def }
|
||||
|
||||
override BasicBlock getBasicBlock() {
|
||||
isNullArgument = false and
|
||||
result = def.getBasicBlock()
|
||||
}
|
||||
|
||||
string getMessage() { result = msg }
|
||||
|
||||
Element getReason() { result = reason }
|
||||
|
||||
override PathNode getASuccessor() {
|
||||
succStep(this, result.getSsaDefinition(), result.getBasicBlock())
|
||||
or
|
||||
succNullArgument(this, result.getSsaDefinition(), result.getBasicBlock())
|
||||
or
|
||||
result instanceof SinkPathNode and
|
||||
succSourceSink(this, result.getSsaDefinition(), result.getBasicBlock())
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
if isNullArgument = true then
|
||||
result = reason.toString()
|
||||
else
|
||||
result = def.toString()
|
||||
}
|
||||
|
||||
override Location getLocation() {
|
||||
if isNullArgument = true then
|
||||
result = reason.getLocation()
|
||||
else
|
||||
result = def.getLocation()
|
||||
}
|
||||
}
|
||||
|
||||
private class InternalPathNode extends PathNode, TInternalPathNode {
|
||||
private Ssa::Definition def;
|
||||
private BasicBlock bb;
|
||||
|
||||
InternalPathNode() { this = TInternalPathNode(def, bb) }
|
||||
|
||||
override Ssa::Definition getSsaDefinition() { result = def }
|
||||
|
||||
override BasicBlock getBasicBlock() { result = bb }
|
||||
|
||||
override PathNode getASuccessor() {
|
||||
succStep(this, result.getSsaDefinition(), result.getBasicBlock())
|
||||
}
|
||||
|
||||
override string toString() { result = bb.getFirstNode().toString() }
|
||||
|
||||
override Location getLocation() { result = bb.getFirstNode().getLocation() }
|
||||
}
|
||||
|
||||
private class SinkPathNode extends PathNode, TSinkPathNode {
|
||||
private Ssa::Definition def;
|
||||
private BasicBlock bb;
|
||||
private int i;
|
||||
private Dereference d;
|
||||
|
||||
SinkPathNode() { this = TSinkPathNode(def, bb, i, d) }
|
||||
|
||||
override Ssa::Definition getSsaDefinition() { result = def }
|
||||
|
||||
override BasicBlock getBasicBlock() { result = bb }
|
||||
|
||||
override PathNode getASuccessor() { none() }
|
||||
|
||||
Dereference getDereference() { result = d }
|
||||
|
||||
override string toString() { result = d.toString() }
|
||||
|
||||
override Location getLocation() { result = d.getLocation() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Provides the query predicates needed to include a graph in a path-problem query
|
||||
* for `Dereference::is[First]MaybeNull()`.
|
||||
*/
|
||||
module PathGraph {
|
||||
query predicate nodes(PathNode n) {
|
||||
n.getASuccessor*() instanceof SinkPathNode
|
||||
}
|
||||
|
||||
query predicate edges(PathNode pred, PathNode succ) {
|
||||
nodes(pred) and
|
||||
nodes(succ) and
|
||||
succ = pred.getASuccessor()
|
||||
}
|
||||
}
|
||||
|
||||
private Ssa::Definition getAPseudoInput(Ssa::Definition def) {
|
||||
@@ -267,20 +423,20 @@ private Ssa::Definition getAnUltimateDefinition(Ssa::Definition def) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if SSA definition `def` can reach a read `ar`, without passing
|
||||
* Holds if SSA definition `def` can reach a read at `cfn`, without passing
|
||||
* through an intermediate dereference that always (`always = true`) or
|
||||
* maybe (`always = false`) throws a null reference exception.
|
||||
*/
|
||||
private predicate defReaches(Ssa::Definition def, AssignableRead ar, boolean always) {
|
||||
ar = def.getAFirstRead() and
|
||||
private predicate defReaches(Ssa::Definition def, ControlFlow::Node cfn, boolean always) {
|
||||
exists(def.getAFirstReadAtNode(cfn)) and
|
||||
(always = true or always = false)
|
||||
or
|
||||
exists(AssignableRead mid |
|
||||
exists(ControlFlow::Node mid |
|
||||
defReaches(def, mid, always) |
|
||||
ar = mid.getANextRead() and
|
||||
Ssa::Internal::adjacentReadPairSameVar(mid, cfn) and
|
||||
not mid = any(Dereference d |
|
||||
if always = true then d.isAlwaysNull(def.getSourceVariable()) else d.isMaybeNull(def, _, _)
|
||||
)
|
||||
if always = true then d.isAlwaysNull(def.getSourceVariable()) else d.isMaybeNull(def, _, _, _, _)
|
||||
).getAControlFlowNode()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -372,27 +528,19 @@ class Dereference extends G::DereferenceableExpr {
|
||||
*/
|
||||
predicate isFirstAlwaysNull(Ssa::SourceVariable v) {
|
||||
this.isAlwaysNull(v) and
|
||||
defReaches(v.getAnSsaDefinition(), this, true)
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
private predicate nullDerefCandidate(Ssa::Definition origin) {
|
||||
exists(Ssa::Definition ssa, BasicBlock bb |
|
||||
potentialNullDereferenceAt(bb, _, ssa, this) |
|
||||
defMaybeNullInBlockOrigin(origin, ssa, bb)
|
||||
)
|
||||
defReaches(v.getAnSsaDefinition(), this.getAControlFlowNode(), true)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this expression dereferences SSA definition `def`, which may
|
||||
* be `null`.
|
||||
*/
|
||||
predicate isMaybeNull(Ssa::Definition def, string msg, Element reason) {
|
||||
exists(Ssa::Definition origin, BasicBlock bb |
|
||||
this.nullDerefCandidate(origin) and
|
||||
defMaybeNull(origin, msg, reason) and
|
||||
potentialNullDereferenceAt(bb, _, def, this)
|
||||
) and
|
||||
predicate isMaybeNull(Ssa::Definition def, SourcePathNode source, SinkPathNode sink, string msg, Element reason) {
|
||||
source.getASuccessor*() = sink and
|
||||
msg = source.getMessage() and
|
||||
reason = source.getReason() and
|
||||
def = sink.getSsaDefinition() and
|
||||
this = sink.getDereference() and
|
||||
not this.isAlwaysNull(def.getSourceVariable())
|
||||
}
|
||||
|
||||
@@ -401,8 +549,8 @@ class Dereference extends G::DereferenceableExpr {
|
||||
* be `null`, and this expression can be reached from `def` without passing
|
||||
* through another such dereference.
|
||||
*/
|
||||
predicate isFirstMaybeNull(Ssa::Definition def, string msg, Element reason) {
|
||||
this.isMaybeNull(def, msg, reason) and
|
||||
defReaches(def, this, false)
|
||||
predicate isFirstMaybeNull(Ssa::Definition def, SourcePathNode source, SinkPathNode sink, string msg, Element reason) {
|
||||
this.isMaybeNull(def, source, sink, msg, reason) and
|
||||
defReaches(def, this.getAControlFlowNode(), false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -758,54 +758,18 @@ module Ssa {
|
||||
ssaRefRank(bb2, i2, v, _) = 1
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value defined at non-trivial SSA definition `def` can reach `read`
|
||||
* without passing through any other read, but possibly through pseudo definitions
|
||||
* and uncertain definitions.
|
||||
*/
|
||||
deprecated
|
||||
predicate firstUncertainRead(TrackedDefinition def, AssignableRead read) {
|
||||
firstReadSameVar(def, read)
|
||||
or
|
||||
exists(TrackedVar v, TrackedDefinition redef, BasicBlock b1, int i1, BasicBlock b2, int i2 |
|
||||
redef instanceof UncertainDefinition or redef instanceof PseudoDefinition
|
||||
|
|
||||
adjacentVarRefs(v, b1, i1, b2, i2) and
|
||||
definesAt(def, b1, i1, v) and
|
||||
definesAt(redef, b2, i2, v) and
|
||||
firstUncertainRead(redef, read)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Use `AssignableRead.getANextUncertainRead()` instead.
|
||||
*/
|
||||
deprecated
|
||||
predicate adjacentReadPair(AssignableRead read1, AssignableRead read2) {
|
||||
adjacentReadPairSameVar(read1, read2)
|
||||
or
|
||||
exists(TrackedVar v, TrackedDefinition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
adjacentVarRefs(v, bb1, i1, bb2, i2) and
|
||||
variableRead(bb1, i1, v, read1.getAControlFlowNode(), _) and
|
||||
definesAt(def, bb2, i2, v) and
|
||||
firstUncertainRead(def, read2) |
|
||||
def instanceof UncertainDefinition or
|
||||
def instanceof PseudoDefinition
|
||||
)
|
||||
}
|
||||
|
||||
private cached module Cached {
|
||||
/**
|
||||
* Holds if `read` is a last read of the non-trivial SSA definition `def`.
|
||||
* That is, `read` can reach the end of the enclosing callable, or another
|
||||
* Holds if `cfn` is a last read of the non-trivial SSA definition `def`.
|
||||
* That is, `cfn` can reach the end of the enclosing callable, or another
|
||||
* SSA definition for the underlying source variable, without passing through
|
||||
* another read.
|
||||
*/
|
||||
cached
|
||||
predicate lastRead(TrackedDefinition def, AssignableRead read) {
|
||||
predicate lastRead(TrackedDefinition def, ControlFlow::Node cfn) {
|
||||
exists(TrackedVar v, BasicBlock bb, int i, int rnk |
|
||||
read = def.getARead() and
|
||||
variableRead(bb, i, v, read.getAControlFlowNode(), _) and
|
||||
exists(def.getAReadAtNode(cfn)) and
|
||||
variableRead(bb, i, v, cfn, _) and
|
||||
rnk = ssaRefRank(bb, i, v, SsaRead()) |
|
||||
// Next reference to `v` inside `bb` is a write
|
||||
rnk + 1 = ssaRefRank(bb, _, v, SsaDef())
|
||||
@@ -890,27 +854,29 @@ module Ssa {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value defined at non-trivial SSA definition `def` can reach `read`
|
||||
* without passing through any other read.
|
||||
* Holds if the value defined at non-trivial SSA definition `def` can reach a
|
||||
* read at `cfn`, without passing through any other read.
|
||||
*/
|
||||
cached
|
||||
predicate firstReadSameVar(TrackedDefinition def, AssignableRead read) {
|
||||
predicate firstReadSameVar(TrackedDefinition def, ControlFlow::Node cfn) {
|
||||
exists(TrackedVar v, BasicBlock b1, int i1, BasicBlock b2, int i2 |
|
||||
adjacentVarRefs(v, b1, i1, b2, i2) and
|
||||
definesAt(def, b1, i1, v) and
|
||||
variableRead(b2, i2, v, read.getAControlFlowNode(), _)
|
||||
variableRead(b2, i2, v, cfn, _)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* INTERNAL: Use `AssignableRead.getANextRead()` instead.
|
||||
* Holds if the read at `cfn2` is a read of the same SSA definition as the
|
||||
* read at `cfn1`, and `cfn2` can be reached from `cfn1` without passing
|
||||
* through another read.
|
||||
*/
|
||||
cached
|
||||
predicate adjacentReadPairSameVar(AssignableRead read1, AssignableRead read2) {
|
||||
predicate adjacentReadPairSameVar(ControlFlow::Node cfn1, ControlFlow::Node cfn2) {
|
||||
exists(TrackedVar v, BasicBlock bb1, int i1, BasicBlock bb2, int i2 |
|
||||
adjacentVarRefs(v, bb1, i1, bb2, i2) and
|
||||
variableRead(bb1, i1, v, read1.getAControlFlowNode(), _) and
|
||||
variableRead(bb2, i2, v, read2.getAControlFlowNode(), _)
|
||||
variableRead(bb1, i1, v, cfn1, _) and
|
||||
variableRead(bb2, i2, v, cfn2, _)
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -2110,8 +2076,45 @@ module Ssa {
|
||||
* Subsequent reads can be found by following the steps defined by
|
||||
* `AssignableRead.getANextRead()`.
|
||||
*/
|
||||
AssignableRead getAFirstRead() {
|
||||
firstReadSameVar(this, result)
|
||||
AssignableRead getAFirstRead() { result = this.getAFirstReadAtNode(_) }
|
||||
|
||||
/**
|
||||
* Gets a read of the source variable underlying this SSA definition at
|
||||
* control flow node `cfn` that can be reached from this SSA definition
|
||||
* without passing through any other SSA definition or read. Example:
|
||||
*
|
||||
* ```
|
||||
* int Field;
|
||||
*
|
||||
* void SetField(int i) {
|
||||
* this.Field = i;
|
||||
* Use(this.Field);
|
||||
* if (i > 0)
|
||||
* this.Field = i - 1;
|
||||
* else if (i < 0)
|
||||
* SetField(1);
|
||||
* Use(this.Field);
|
||||
* Use(this.Field);
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* - The read of `i` on line 4 can be reached from the explicit SSA
|
||||
* definition (wrapping an implicit entry definition) on line 3.
|
||||
* - The reads of `i` on lines 6 and 7 are not the first reads of any SSA
|
||||
* definition.
|
||||
* - The read of `this.Field` on line 5 can be reached from the explicit SSA
|
||||
* definition on line 4.
|
||||
* - The read of `this.Field` on line 10 can be reached from the phi node
|
||||
* between lines 9 and 10.
|
||||
* - The read of `this.Field` on line 11 is not the first read of any SSA
|
||||
* definition.
|
||||
*
|
||||
* Subsequent reads can be found by following the steps defined by
|
||||
* `AssignableRead.getANextRead()`.
|
||||
*/
|
||||
AssignableRead getAFirstReadAtNode(ControlFlow::Node cfn) {
|
||||
firstReadSameVar(this, cfn) and
|
||||
result.getAControlFlowNode() = cfn
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2142,15 +2145,13 @@ module Ssa {
|
||||
* - The read of `this.Field` on line 11 is a last read of the phi node
|
||||
* between lines 9 and 10.
|
||||
*/
|
||||
AssignableRead getALastRead() {
|
||||
lastRead(this, result)
|
||||
}
|
||||
AssignableRead getALastRead() { result = this.getALastReadAtNode(_) }
|
||||
|
||||
/**
|
||||
* Gets a first uncertain read of the source variable underlying this
|
||||
* SSA definition. That is, a read that can be reached from this SSA definition
|
||||
* without passing through any other reads or SSA definitions, except for
|
||||
* phi nodes and uncertain updates. Example:
|
||||
* Gets a last read of the source variable underlying this SSA definition at
|
||||
* control flow node `cfn`. That is, a read that can reach the end of the
|
||||
* enclosing callable, or another SSA definition for the source variable,
|
||||
* without passing through any other read. Example:
|
||||
*
|
||||
* ```
|
||||
* int Field;
|
||||
@@ -2167,24 +2168,16 @@ module Ssa {
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* - The read of `i` on line 4 can be reached from the explicit SSA
|
||||
* definition (wrapping an implicit entry definition) on line 3.
|
||||
* - The reads of `i` on lines 6 and 7 are not the first reads of any SSA
|
||||
* definition.
|
||||
* - The read of `this.Field` on line 5 can be reached from the explicit SSA
|
||||
* definition on line 4.
|
||||
* - The read of `this.Field` on line 10 can be reached from the explicit SSA
|
||||
* definition on line 7, the implicit SSA definition on line 9, and the phi
|
||||
* node between lines 9 and 10.
|
||||
* - The read of `this.Field` on line 11 is not the first read of any SSA
|
||||
* definition.
|
||||
*
|
||||
* Subsequent uncertain reads can be found by following the steps defined by
|
||||
* `AssignableRead.getANextUncertainRead()`.
|
||||
* - The reads of `i` on lines 7 and 8 are the last reads for the implicit
|
||||
* parameter definition on line 3.
|
||||
* - The read of `this.Field` on line 5 is a last read of the definition on
|
||||
* line 4.
|
||||
* - The read of `this.Field` on line 11 is a last read of the phi node
|
||||
* between lines 9 and 10.
|
||||
*/
|
||||
deprecated
|
||||
AssignableRead getAFirstUncertainRead() {
|
||||
firstUncertainRead(this, result)
|
||||
AssignableRead getALastReadAtNode(ControlFlow::Node cfn) {
|
||||
lastRead(this, cfn) and
|
||||
result.getAControlFlowNode() = cfn
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2249,6 +2242,21 @@ module Ssa {
|
||||
definesAt(this, bb, i, _)
|
||||
}
|
||||
|
||||
/** Gets the basic block to which this SSA definition belongs. */
|
||||
BasicBlock getBasicBlock() { this.definesAt(result, _) }
|
||||
|
||||
/**
|
||||
* Gets the syntax element associated with this SSA definition, if any.
|
||||
* This is either an expression, for example `x = 0`, a parameter, or a
|
||||
* callable. Pseudo nodes have no associated syntax element.
|
||||
*/
|
||||
Element getElement() {
|
||||
exists(BasicBlock bb, int i |
|
||||
this.definesAt(bb, i) |
|
||||
result = bb.getNode(i).getElement()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this SSA definition assigns to `out`/`ref` parameter `p`, and the
|
||||
* parameter may remain unchanged throughout the rest of the enclosing callable.
|
||||
@@ -2338,6 +2346,8 @@ module Ssa {
|
||||
isCapturedVariableDefinitionFlowOut(this, cdef)
|
||||
}
|
||||
|
||||
override Element getElement() { result = ad.getElement() }
|
||||
|
||||
override string toString() {
|
||||
if this.getADefinition() instanceof AssignableDefinitions::ImplicitParameterDefinition then
|
||||
result = getToStringPrefix(this) + "SSA param(" + this.getSourceVariable() + ")"
|
||||
@@ -2381,6 +2391,8 @@ module Ssa {
|
||||
)
|
||||
}
|
||||
|
||||
override Callable getElement() { result = this.getCallable() }
|
||||
|
||||
override string toString() {
|
||||
if this.getSourceVariable().getAssignable() instanceof LocalScopeVariable then
|
||||
result = getToStringPrefix(this) + "SSA capture def(" + this.getSourceVariable() + ")"
|
||||
@@ -2459,10 +2471,6 @@ module Ssa {
|
||||
)
|
||||
}
|
||||
|
||||
override AssignableRead getAFirstUncertainRead() {
|
||||
result = this.getARead()
|
||||
}
|
||||
|
||||
override string toString() {
|
||||
result = getToStringPrefix(this) + "SSA untracked def(" + getSourceVariable() + ")"
|
||||
}
|
||||
|
||||
@@ -269,13 +269,6 @@ private module Internal {
|
||||
* types for a given expression.
|
||||
*/
|
||||
private module SimpleTypeDataFlow {
|
||||
// A temporary workaround to get the right join-order in `Sink::getASource()`
|
||||
private newtype ExprWrapper = TExprWrapper(Expr e)
|
||||
|
||||
private Expr unwrap(ExprWrapper ew) { ew = TExprWrapper(result) }
|
||||
|
||||
private ExprWrapper wrap(Expr e) { result = TExprWrapper(e) }
|
||||
|
||||
/**
|
||||
* Holds if type `t` may be imprecise, that is, an expression of type `t` may
|
||||
* in fact have a more precise type.
|
||||
@@ -321,34 +314,27 @@ private module Internal {
|
||||
typeMayBeImprecise(succ.getType())
|
||||
}
|
||||
|
||||
private predicate step(ExprWrapper succ, ExprWrapper pred) {
|
||||
stepExpr(unwrap(succ), unwrap(pred))
|
||||
}
|
||||
|
||||
private predicate isSink(ExprWrapper ew) {
|
||||
exists(Expr e |
|
||||
e = unwrap(ew) |
|
||||
e = any(DynamicMemberAccess dma | isSink(wrap(dma))).getQualifier() or
|
||||
e = any(AccessorCall ac).getAnArgument() or
|
||||
e = any(DispatchReflectionOrDynamicCall c).getArgument(_) or
|
||||
e = any(MethodCall mc | mc.getTarget() = any(SystemObjectClass c).getGetTypeMethod()).getQualifier() or
|
||||
e = any(DispatchCallImpl c).getQualifier()
|
||||
)
|
||||
}
|
||||
|
||||
private predicate stepTC(ExprWrapper succ, ExprWrapper pred) =
|
||||
boundedFastTC(step/2, isSink/1)(succ, pred)
|
||||
private predicate stepTC(Expr succ, Expr pred) =
|
||||
fastTC(stepExpr/2)(succ, pred)
|
||||
|
||||
private class Source extends Expr {
|
||||
Source() { not stepExpr(this, _) }
|
||||
}
|
||||
|
||||
private class Sink extends Expr {
|
||||
Sink() { isSink(wrap(this)) }
|
||||
|
||||
Source getASource() {
|
||||
stepTC(wrap(this), wrap(result))
|
||||
Sink() {
|
||||
this = any(DynamicMemberAccess dma | dma instanceof Sink).getQualifier()
|
||||
or
|
||||
this = any(AccessorCall ac).getAnArgument()
|
||||
or
|
||||
this = any(DispatchReflectionOrDynamicCall c).getArgument(_)
|
||||
or
|
||||
this = any(MethodCall mc | mc.getTarget() = any(SystemObjectClass c).getGetTypeMethod()).getQualifier()
|
||||
or
|
||||
this = any(DispatchCallImpl c).getQualifier()
|
||||
}
|
||||
|
||||
Source getASource() { stepTC(this, result) }
|
||||
}
|
||||
|
||||
/** Holds if the expression `e` has an exact type. */
|
||||
@@ -357,10 +343,7 @@ private module Internal {
|
||||
e instanceof BaseAccess
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a source type for expression `e`, using simple data flow. The
|
||||
* expression must be a member of the predicate `isSink()` above.
|
||||
*/
|
||||
/** Gets a source type for expression `e`, using simple data flow. */
|
||||
Type getASourceType(Sink e, boolean isExact) {
|
||||
exists(Source s |
|
||||
s = e.getASource() or
|
||||
|
||||
@@ -128,28 +128,6 @@ class MemberAccess extends Access, QualifiableExpr, @member_access_expr {
|
||||
class AssignableAccess extends Access, @assignable_access_expr {
|
||||
override Assignable getTarget() { none() }
|
||||
|
||||
/**
|
||||
* DEPRECATED: use the class `AssignableRead` instead.
|
||||
*/
|
||||
deprecated predicate isReadAccess() {
|
||||
this instanceof AssignableRead
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: use the class `AssignableWrite` instead.
|
||||
*/
|
||||
deprecated predicate isWriteAccess() {
|
||||
this instanceof AssignableWrite
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: use the classes `AssignableRead` and `AssignableWrite` instead.
|
||||
*/
|
||||
deprecated predicate isReadWriteAccess() {
|
||||
this instanceof AssignableRead and
|
||||
this instanceof AssignableWrite
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this access passes the assignable being accessed as an `out`
|
||||
* argument in a method call.
|
||||
@@ -207,16 +185,6 @@ class VariableRead extends VariableAccess, AssignableRead {
|
||||
override VariableRead getAReachableRead() {
|
||||
result = AssignableRead.super.getAReachableRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override VariableRead getANextUncertainRead() {
|
||||
result = AssignableRead.super.getANextUncertainRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override VariableRead getAReachableUncertainRead() {
|
||||
result = AssignableRead.super.getAReachableUncertainRead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -249,16 +217,6 @@ class LocalScopeVariableRead extends LocalScopeVariableAccess, VariableRead {
|
||||
override LocalScopeVariableRead getAReachableRead() {
|
||||
result = VariableRead.super.getAReachableRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override LocalScopeVariableRead getANextUncertainRead() {
|
||||
result = VariableRead.super.getANextUncertainRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override LocalScopeVariableRead getAReachableUncertainRead() {
|
||||
result = VariableRead.super.getAReachableUncertainRead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,16 +263,6 @@ class ParameterRead extends ParameterAccess, LocalScopeVariableRead {
|
||||
override ParameterRead getAReachableRead() {
|
||||
result = LocalScopeVariableRead.super.getAReachableRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override ParameterRead getANextUncertainRead() {
|
||||
result = LocalScopeVariableRead.super.getANextUncertainRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override ParameterRead getAReachableUncertainRead() {
|
||||
result = LocalScopeVariableRead.super.getAReachableUncertainRead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -372,16 +320,6 @@ class LocalVariableRead extends LocalVariableAccess, LocalScopeVariableRead {
|
||||
override LocalVariableRead getAReachableRead() {
|
||||
result = LocalScopeVariableRead.super.getAReachableRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override LocalVariableRead getANextUncertainRead() {
|
||||
result = LocalScopeVariableRead.super.getANextUncertainRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override LocalVariableRead getAReachableUncertainRead() {
|
||||
result = LocalScopeVariableRead.super.getAReachableUncertainRead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -526,16 +464,6 @@ class PropertyRead extends PropertyAccess, AssignableRead {
|
||||
override PropertyRead getAReachableRead() {
|
||||
result = AssignableRead.super.getAReachableRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override PropertyRead getANextUncertainRead() {
|
||||
result = AssignableRead.super.getANextUncertainRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override PropertyRead getAReachableUncertainRead() {
|
||||
result = AssignableRead.super.getAReachableUncertainRead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -685,16 +613,6 @@ class IndexerRead extends IndexerAccess, AssignableRead {
|
||||
override IndexerRead getAReachableRead() {
|
||||
result = AssignableRead.super.getAReachableRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override IndexerRead getANextUncertainRead() {
|
||||
result = AssignableRead.super.getANextUncertainRead()
|
||||
}
|
||||
|
||||
deprecated
|
||||
override IndexerRead getAReachableUncertainRead() {
|
||||
result = AssignableRead.super.getAReachableUncertainRead()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -275,39 +275,7 @@ class IsExpr extends Expr, @is_expr {
|
||||
*/
|
||||
Expr getExpr() { result = this.getChild(0) }
|
||||
|
||||
/**
|
||||
* Deprecated: Use `IsTypeExpr.getTypeAccess()` instead.
|
||||
* Gets the type access in this `is` expression, for example `string` in
|
||||
* `x is string`.
|
||||
*/
|
||||
deprecated
|
||||
TypeAccess getTypeAccess() { none() }
|
||||
|
||||
/**
|
||||
* Deprecated: Use `IsTypeExpr.getCheckedType()` instead.
|
||||
* Gets the type being accessed in this `is` expression, for example `string`
|
||||
* in `x is string`.
|
||||
*/
|
||||
deprecated
|
||||
Type getCheckedType() { none() }
|
||||
|
||||
override string toString() { result = "... is ..." }
|
||||
|
||||
/**
|
||||
* Deprecated: Use `IsPatternExpr.getVariableDeclExpr()` instead.
|
||||
* Gets the local variable declaration in an `is` pattern expression,
|
||||
* if any. For example `string s` in `x is string s`.
|
||||
*/
|
||||
deprecated
|
||||
LocalVariableDeclExpr getVariableDeclExpr() { none() }
|
||||
|
||||
/**
|
||||
* Deprecated: Use `instanceof IsPatternExpr` instead.
|
||||
* Holds if this `is` expression is an `is` pattern expression, for example
|
||||
* `x is string s`.
|
||||
*/
|
||||
deprecated
|
||||
predicate isPattern() { this instanceof IsPatternExpr }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -322,13 +290,13 @@ class IsTypeExpr extends IsExpr
|
||||
* Gets the type being accessed in this `is` expression, for example `string`
|
||||
* in `x is string`.
|
||||
*/
|
||||
override Type getCheckedType() { result = typeAccess.getTarget() }
|
||||
Type getCheckedType() { result = typeAccess.getTarget() }
|
||||
|
||||
/**
|
||||
* Gets the type access in this `is` expression, for example `string` in
|
||||
* `x is string`.
|
||||
*/
|
||||
override TypeAccess getTypeAccess() { result = typeAccess }
|
||||
TypeAccess getTypeAccess() { result = typeAccess }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -343,7 +311,7 @@ class IsPatternExpr extends IsTypeExpr
|
||||
* Gets the local variable declaration in this `is` pattern expression.
|
||||
* For example `string s` in `x is string s`.
|
||||
*/
|
||||
override LocalVariableDeclExpr getVariableDeclExpr() { result = typeDecl }
|
||||
LocalVariableDeclExpr getVariableDeclExpr() { result = typeDecl }
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,17 +159,11 @@ class InvalidFormatString extends StringLiteral {
|
||||
result = this.getValue().regexpFind(getValidFormatRegex(),0,0).length()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this element is at the specified location.
|
||||
* The location spans column `startcolumn` of line `startline` to
|
||||
* column `endcolumn` of line `endline` in file `filepath`.
|
||||
* For more information, see
|
||||
* [LGTM locations](https://lgtm.com/help/ql/locations).
|
||||
*/
|
||||
predicate hasLocationInfo(string filepath, int startline, int startcolumn, int endline, int endcolumn) {
|
||||
exists(int oldstartcolumn, int padding |
|
||||
override string getURL() {
|
||||
exists(string filepath, int startline, int startcolumn, int endline, int endcolumn, int oldstartcolumn, int padding |
|
||||
this.getLocation().hasLocationInfo(filepath, startline, oldstartcolumn, endline, endcolumn) and
|
||||
startcolumn = padding + oldstartcolumn + getInvalidOffset() |
|
||||
startcolumn = padding + oldstartcolumn + getInvalidOffset() and
|
||||
toUrl(filepath, startline, startcolumn, endline, endcolumn, result) |
|
||||
// Single-line string literal beginning " or @"
|
||||
// Figure out the correct indent.
|
||||
startline = endline and
|
||||
|
||||
@@ -8,7 +8,3 @@ class MicrosoftNamespace extends Namespace {
|
||||
this.hasName("Microsoft")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `Microsoft` namespace. */
|
||||
deprecated
|
||||
MicrosoftNamespace getMicrosoftNamespace() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System` namespace. */
|
||||
deprecated
|
||||
SystemNamespace getSystemNamespace() { any() }
|
||||
|
||||
/** A class in the `System` namespace. */
|
||||
class SystemClass extends Class {
|
||||
SystemClass() {
|
||||
@@ -63,10 +59,6 @@ class SystemActionDelegateType extends SystemDelegateType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Action` delegate type. */
|
||||
deprecated
|
||||
SystemActionDelegateType getSystemActionDelegateType() { any() }
|
||||
|
||||
/** The `System.Action<T1, ..., Tn>` delegate type. */
|
||||
class SystemActionTDelegateType extends SystemUnboundGenericDelegateType {
|
||||
SystemActionTDelegateType() {
|
||||
@@ -74,10 +66,6 @@ class SystemActionTDelegateType extends SystemUnboundGenericDelegateType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets a `System.Action<T1, ..., Tn>` delegate type. */
|
||||
deprecated
|
||||
SystemActionTDelegateType getSystemActionTDelegateType() { any() }
|
||||
|
||||
/** `System.Array` class. */
|
||||
class SystemArrayClass extends SystemClass {
|
||||
SystemArrayClass() {
|
||||
@@ -85,10 +73,6 @@ class SystemArrayClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Array` class. */
|
||||
deprecated
|
||||
SystemArrayClass getSystemArrayClass() { any() }
|
||||
|
||||
/** The `System.Boolean` structure. */
|
||||
class SystemBooleanStruct extends BoolType {
|
||||
/** Gets the `Parse(string)` method. */
|
||||
@@ -120,10 +104,6 @@ class SystemBooleanStruct extends BoolType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Boolean` structure. */
|
||||
deprecated
|
||||
SystemBooleanStruct getSystemBooleanStruct() { any() }
|
||||
|
||||
/** The `System.Convert` class. */
|
||||
class SystemConvertClass extends SystemClass {
|
||||
SystemConvertClass() {
|
||||
@@ -131,10 +111,6 @@ class SystemConvertClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Convert` class. */
|
||||
deprecated
|
||||
SystemConvertClass getSystemConvertClass() { any() }
|
||||
|
||||
/** `System.Delegate` class. */
|
||||
class SystemDelegateClass extends SystemClass {
|
||||
SystemDelegateClass() {
|
||||
@@ -142,10 +118,6 @@ class SystemDelegateClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Delegate` class. */
|
||||
deprecated
|
||||
SystemDelegateClass getSystemDelegateClass() { any() }
|
||||
|
||||
/** The `System.DivideByZeroException` class. */
|
||||
class SystemDivideByZeroExceptionClass extends SystemClass {
|
||||
SystemDivideByZeroExceptionClass() {
|
||||
@@ -153,10 +125,6 @@ class SystemDivideByZeroExceptionClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.DivideByZeroException` class. */
|
||||
deprecated
|
||||
SystemDivideByZeroExceptionClass getSystemDivideByZeroExceptionClass() { any() }
|
||||
|
||||
/** The `System.Enum` class. */
|
||||
class SystemEnumClass extends SystemClass {
|
||||
SystemEnumClass() {
|
||||
@@ -164,10 +132,6 @@ class SystemEnumClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Enum` class. */
|
||||
deprecated
|
||||
SystemEnumClass getSystemEnumClass() { any() }
|
||||
|
||||
/** The `System.Exception` class. */
|
||||
class SystemExceptionClass extends SystemClass {
|
||||
SystemExceptionClass() {
|
||||
@@ -175,10 +139,6 @@ class SystemExceptionClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Exception` class. */
|
||||
deprecated
|
||||
SystemExceptionClass getSystemExceptionClass() { any() }
|
||||
|
||||
/** The `System.Func<T1, ..., Tn, TResult>` delegate type. */
|
||||
class SystemFuncDelegateType extends SystemUnboundGenericDelegateType {
|
||||
SystemFuncDelegateType() {
|
||||
@@ -199,10 +159,6 @@ class SystemFuncDelegateType extends SystemUnboundGenericDelegateType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets a `System.Func<T1, ..., Tn, TResult>` delegate type. */
|
||||
deprecated
|
||||
SystemFuncDelegateType getSystemFuncDelegateType() { any() }
|
||||
|
||||
/** The `System.IComparable` interface. */
|
||||
class SystemIComparableInterface extends SystemInterface {
|
||||
SystemIComparableInterface() {
|
||||
@@ -223,10 +179,6 @@ class SystemIComparableInterface extends SystemInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IComparable` interface. */
|
||||
deprecated
|
||||
SystemIComparableInterface getSystemIComparableInterface() { any() }
|
||||
|
||||
/** The `System.IComparable<T>` interface. */
|
||||
class SystemIComparableTInterface extends SystemUnboundGenericInterface {
|
||||
SystemIComparableTInterface() {
|
||||
@@ -247,10 +199,6 @@ class SystemIComparableTInterface extends SystemUnboundGenericInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IComparable<T>` interface. */
|
||||
deprecated
|
||||
SystemIComparableTInterface getSystemIComparableTInterface() { any() }
|
||||
|
||||
/** The `System.IEquatable<T>` interface. */
|
||||
class SystemIEquatableTInterface extends SystemUnboundGenericInterface {
|
||||
SystemIEquatableTInterface() {
|
||||
@@ -271,10 +219,6 @@ class SystemIEquatableTInterface extends SystemUnboundGenericInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IEquatable<T>` interface. */
|
||||
deprecated
|
||||
SystemIEquatableTInterface getSystemIEquatableTInterface() { any() }
|
||||
|
||||
/** The `System.IFormatProvider` interface. */
|
||||
class SystemIFormatProviderInterface extends SystemInterface {
|
||||
SystemIFormatProviderInterface() {
|
||||
@@ -282,10 +226,6 @@ class SystemIFormatProviderInterface extends SystemInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IFormatProvider` interface. */
|
||||
deprecated
|
||||
SystemIFormatProviderInterface getSystemIFormatProviderInterface() { any() }
|
||||
|
||||
/** The `System.Int32` structure. */
|
||||
class SystemInt32Struct extends IntType {
|
||||
/** Gets the `Parse(string, ...)` method. */
|
||||
@@ -313,10 +253,6 @@ class SystemInt32Struct extends IntType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Int32` structure. */
|
||||
deprecated
|
||||
SystemInt32Struct getSystemInt32Struct() { any() }
|
||||
|
||||
/** The `System.InvalidCastException` class. */
|
||||
class SystemInvalidCastExceptionClass extends SystemClass {
|
||||
SystemInvalidCastExceptionClass() {
|
||||
@@ -324,10 +260,6 @@ class SystemInvalidCastExceptionClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.InvalidCastException` class. */
|
||||
deprecated
|
||||
SystemInvalidCastExceptionClass getSystemInvalidCastExceptionClass() { any() }
|
||||
|
||||
/** The `System.Lazy<T>` class. */
|
||||
class SystemLazyClass extends SystemUnboundGenericClass {
|
||||
SystemLazyClass() {
|
||||
@@ -346,10 +278,6 @@ class SystemLazyClass extends SystemUnboundGenericClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Lazy<T>` class. */
|
||||
deprecated
|
||||
SystemLazyClass getSystemLazyClass() { any() }
|
||||
|
||||
/** The `System.NullReferenceException` class. */
|
||||
class SystemNullReferenceExceptionClass extends SystemClass {
|
||||
SystemNullReferenceExceptionClass() {
|
||||
@@ -357,10 +285,6 @@ class SystemNullReferenceExceptionClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.NullReferenceException` class. */
|
||||
deprecated
|
||||
SystemNullReferenceExceptionClass getSystemNullReferenceExceptionClass() { any() }
|
||||
|
||||
/** The `System.Object` class. */
|
||||
class SystemObjectClass extends SystemClass {
|
||||
SystemObjectClass() {
|
||||
@@ -448,10 +372,6 @@ class SystemObjectClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Object` class. */
|
||||
deprecated
|
||||
SystemObjectClass getSystemObjectClass() { any() }
|
||||
|
||||
/** The `System.OutOfMemoryException` class. */
|
||||
class SystemOutOfMemoryExceptionClass extends SystemClass {
|
||||
SystemOutOfMemoryExceptionClass() {
|
||||
@@ -459,10 +379,6 @@ class SystemOutOfMemoryExceptionClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.OutOfMemoryException` class. */
|
||||
deprecated
|
||||
SystemOutOfMemoryExceptionClass getSystemOutOfMemoryExceptionClass() { any() }
|
||||
|
||||
/** The `System.OverflowException` class. */
|
||||
class SystemOverflowExceptionClass extends SystemClass {
|
||||
SystemOverflowExceptionClass() {
|
||||
@@ -470,10 +386,6 @@ class SystemOverflowExceptionClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.OverflowException` class. */
|
||||
deprecated
|
||||
SystemOverflowExceptionClass getSystemOverflowExceptionClass() { any() }
|
||||
|
||||
/** The `System.Predicate<T>` delegate type. */
|
||||
class SystemPredicateDelegateType extends SystemUnboundGenericDelegateType {
|
||||
SystemPredicateDelegateType() {
|
||||
@@ -483,10 +395,6 @@ class SystemPredicateDelegateType extends SystemUnboundGenericDelegateType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Predicate<T>` delegate type. */
|
||||
deprecated
|
||||
SystemPredicateDelegateType getSystemPredicateDelegateType() { any() }
|
||||
|
||||
/** The `System.String` class. */
|
||||
class SystemStringClass extends StringType {
|
||||
/** Gets the `Equals(object)` method. */
|
||||
@@ -642,10 +550,6 @@ class SystemStringClass extends StringType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.String` class. */
|
||||
deprecated
|
||||
SystemStringClass getSystemStringClass() { any() }
|
||||
|
||||
/** A `ToString()` method. */
|
||||
class ToStringMethod extends Method {
|
||||
ToStringMethod() {
|
||||
@@ -693,10 +597,6 @@ class SystemTypeClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Type` class. */
|
||||
deprecated
|
||||
SystemTypeClass getSystemTypeClass() { any() }
|
||||
|
||||
/** The `System.Uri` class. */
|
||||
class SystemUriClass extends SystemClass {
|
||||
SystemUriClass() {
|
||||
@@ -731,10 +631,6 @@ class SystemUriClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Uri` class. */
|
||||
deprecated
|
||||
SystemUriClass getSystemUriClass() { any() }
|
||||
|
||||
/** The `System.ValueType` class. */
|
||||
class SystemValueTypeClass extends SystemClass {
|
||||
SystemValueTypeClass() {
|
||||
@@ -742,10 +638,6 @@ class SystemValueTypeClass extends SystemClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.ValueType` class. */
|
||||
deprecated
|
||||
SystemValueTypeClass getSystemValueTypeClass() { any() }
|
||||
|
||||
/** The `System.IntPtr` type. */
|
||||
class SystemIntPtrType extends ValueType {
|
||||
SystemIntPtrType() {
|
||||
@@ -755,10 +647,6 @@ class SystemIntPtrType extends ValueType {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IntPtr` type. */
|
||||
deprecated
|
||||
SystemIntPtrType getSystemIntPtrType() { any() }
|
||||
|
||||
/** The `System.IDisposable` interface. */
|
||||
class SystemIDisposableInterface extends SystemInterface {
|
||||
SystemIDisposableInterface() {
|
||||
@@ -777,10 +665,6 @@ class SystemIDisposableInterface extends SystemInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IDisposable` interface. */
|
||||
deprecated
|
||||
SystemIDisposableInterface getSystemIDisposableInterface() { any() }
|
||||
|
||||
/** A method that overrides `int object.GetHashCode()`. */
|
||||
class GetHashCodeMethod extends Method {
|
||||
GetHashCodeMethod() {
|
||||
|
||||
@@ -14,10 +14,6 @@ class MicrosoftOwinNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `Microsoft.Owin` namespace. */
|
||||
deprecated
|
||||
MicrosoftOwinNamespace getMicrosoftOwinNamespace() { any() }
|
||||
|
||||
/** The `Microsoft.Owin.IOwinRequest` class. */
|
||||
class MicrosoftOwinIOwinRequestClass extends Class {
|
||||
MicrosoftOwinIOwinRequestClass() {
|
||||
|
||||
@@ -9,7 +9,3 @@ class SystemCodeDomNamespace extends Namespace {
|
||||
this.hasName("CodeDom")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.CodeDom` namespace. */
|
||||
deprecated
|
||||
SystemCodeDomNamespace getSystemCodeDomNamespace() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemCollectionsNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections` namespace. */
|
||||
deprecated
|
||||
SystemCollectionsNamespace getSystemCollectionsNamespace() { any() }
|
||||
|
||||
/** An interface in the `System.Collections` namespace. */
|
||||
class SystemCollectionsInterface extends Interface {
|
||||
SystemCollectionsInterface() {
|
||||
@@ -43,10 +39,6 @@ class SystemCollectionsIComparerInterface extends SystemCollectionsInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.IComparer` interface. */
|
||||
deprecated
|
||||
SystemCollectionsIComparerInterface getSystemCollectionsIComparerInterface() { any() }
|
||||
|
||||
/** The `System.Collections.IEnumerable` interface. */
|
||||
class SystemCollectionsIEnumerableInterface extends SystemCollectionsInterface {
|
||||
SystemCollectionsIEnumerableInterface() {
|
||||
@@ -54,10 +46,6 @@ class SystemCollectionsIEnumerableInterface extends SystemCollectionsInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.IEnumerable` interface. */
|
||||
deprecated
|
||||
SystemCollectionsIEnumerableInterface getSystemCollectionsIEnumerableInterface() { any() }
|
||||
|
||||
/** The `System.Collections.IEnumerator` interface. */
|
||||
class SystemCollectionsIEnumeratorInterface extends SystemCollectionsInterface {
|
||||
SystemCollectionsIEnumeratorInterface() {
|
||||
@@ -74,10 +62,6 @@ class SystemCollectionsIEnumeratorInterface extends SystemCollectionsInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.IEnumerator` interface. */
|
||||
deprecated
|
||||
SystemCollectionsIEnumeratorInterface getSystemCollectionsIEnumeratorInterface() { any() }
|
||||
|
||||
/** The `System.Collections.ICollection` interface. */
|
||||
class SystemCollectionsICollectionInterface extends SystemCollectionsInterface {
|
||||
SystemCollectionsICollectionInterface() {
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemDataNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Data` namespace. */
|
||||
deprecated
|
||||
SystemDataNamespace getSystemDataNamespace() { any() }
|
||||
|
||||
/** An interface in the `System.Data` namespace. */
|
||||
class SystemDataInterface extends Interface {
|
||||
SystemDataInterface() {
|
||||
@@ -37,10 +33,6 @@ class SystemDataIDbCommandInterface extends SystemDataInterface {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Data.IDbCommand` interface. */
|
||||
deprecated
|
||||
SystemDataIDbCommandInterface getSystemDataIDbCommandInterface() { any() }
|
||||
|
||||
/** The `System.Data.IDbConnection` interface. */
|
||||
class SystemDataIDbConnectionInterface extends SystemDataInterface {
|
||||
SystemDataIDbConnectionInterface() {
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemDiagnosticsNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Diagnostics` namespace. */
|
||||
deprecated
|
||||
SystemDiagnosticsNamespace getSystemDiagnosticsNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Diagnostics` namespace. */
|
||||
class SystemDiagnosticsClass extends Class {
|
||||
SystemDiagnosticsClass() {
|
||||
@@ -40,10 +36,6 @@ class SystemDiagnosticsDebugClass extends SystemDiagnosticsClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Diagnostics.Debug` class. */
|
||||
deprecated
|
||||
SystemDiagnosticsDebugClass getSystemDiagnosticsDebugClass() { any() }
|
||||
|
||||
/** The `System.Diagnostics.ProcessStartInfo` class. */
|
||||
class SystemDiagnosticsProcessStartInfoClass extends SystemDiagnosticsClass {
|
||||
SystemDiagnosticsProcessStartInfoClass() {
|
||||
@@ -73,7 +65,3 @@ class SystemDiagnosticsProcessClass extends SystemDiagnosticsClass {
|
||||
result.getReturnType() instanceof SystemDiagnosticsProcessClass
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Diagnostics.Process` class. */
|
||||
deprecated
|
||||
SystemDiagnosticsProcessClass getSystemDiagnosticsProcessClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemIONamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO` namespace. */
|
||||
deprecated
|
||||
SystemIONamespace getSystemIONamespace() { any() }
|
||||
|
||||
/** A class in the `System.IO` namespace. */
|
||||
class SystemIOClass extends Class {
|
||||
SystemIOClass() {
|
||||
@@ -35,11 +31,6 @@ class SystemIOFileClass extends SystemIOClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO.File` class. */
|
||||
deprecated
|
||||
SystemIOFileClass getSystemIOFileClass() { any() }
|
||||
|
||||
|
||||
/** The `System.IO.FileStream` class. */
|
||||
class SystemIOFileStreamClass extends SystemIOClass {
|
||||
SystemIOFileStreamClass() {
|
||||
@@ -61,10 +52,6 @@ class SystemIOPathClass extends SystemIOClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO.Path` class. */
|
||||
deprecated
|
||||
SystemIOPathClass getSystemIOPathClass() { any() }
|
||||
|
||||
/** The `System.IO.StringReader` class. */
|
||||
class SystemIOStringReaderClass extends SystemIOClass {
|
||||
SystemIOStringReaderClass() {
|
||||
@@ -72,10 +59,6 @@ class SystemIOStringReaderClass extends SystemIOClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO.StringReader` class. */
|
||||
deprecated
|
||||
SystemIOStringReaderClass getSystemIOStringReaderClass() { any() }
|
||||
|
||||
/** The `System.IO.Stream` class. */
|
||||
class SystemIOStreamClass extends SystemIOClass {
|
||||
SystemIOStreamClass() {
|
||||
@@ -123,10 +106,6 @@ class SystemIOStreamClass extends SystemIOClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO.Stream` class. */
|
||||
deprecated
|
||||
SystemIOStreamClass getSystemIOStreamClass() { any() }
|
||||
|
||||
/** The `System.IO.MemoryStream` class. */
|
||||
class SystemIOMemoryStreamClass extends SystemIOClass {
|
||||
SystemIOMemoryStreamClass() {
|
||||
@@ -139,7 +118,3 @@ class SystemIOMemoryStreamClass extends SystemIOClass {
|
||||
result.hasName("ToArray")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO.MemoryStream` class. */
|
||||
deprecated
|
||||
SystemIOMemoryStreamClass getSystemIOMemoryStreamClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemReflectionNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Reflection` namespace. */
|
||||
deprecated
|
||||
SystemReflectionNamespace getSystemReflectionNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Reflection` namespace. */
|
||||
class SystemReflectionClass extends Class {
|
||||
SystemReflectionClass() {
|
||||
@@ -58,17 +54,9 @@ class SystemReflectionMethodBaseClass extends SystemReflectionClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Reflection.MethodBase` class. */
|
||||
deprecated
|
||||
SystemReflectionMethodBaseClass getSystemReflectionMethodBaseClass() { any() }
|
||||
|
||||
/** The `System.Reflection.MethodInfo` class. */
|
||||
class SystemReflectionMethodInfoClass extends SystemReflectionClass {
|
||||
SystemReflectionMethodInfoClass() {
|
||||
this.hasName("MethodInfo")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Reflection.MethodInfo` class. */
|
||||
deprecated
|
||||
SystemReflectionMethodInfoClass getSystemReflectionMethodInfoClass() { any() }
|
||||
|
||||
@@ -9,7 +9,3 @@ class SystemRuntimeNamespace extends Namespace {
|
||||
this.hasName("Runtime")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Runtime` namespace. */
|
||||
deprecated
|
||||
SystemRuntimeNamespace getSystemRuntimeNamespace() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemTextNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Text` namespace. */
|
||||
deprecated
|
||||
SystemTextNamespace getSystemTextNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Text` namespace. */
|
||||
class SystemTextClass extends Class {
|
||||
SystemTextClass() {
|
||||
@@ -33,10 +29,6 @@ class SystemTextStringBuilderClass extends SystemTextClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Text.StringBuilder` class. */
|
||||
deprecated
|
||||
SystemTextStringBuilderClass getSystemTextStringBuilderClass() { any() }
|
||||
|
||||
/** The `System.Text.Encoding` class. */
|
||||
class SystemTextEncodingClass extends SystemTextClass {
|
||||
SystemTextEncodingClass() {
|
||||
@@ -58,7 +50,3 @@ class SystemTextEncodingClass extends SystemTextClass {
|
||||
result = this.getAMethod("GetChars")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Text.Encoding` class. */
|
||||
deprecated
|
||||
SystemTextEncodingClass getSystemTextEncodingClass() { any() }
|
||||
|
||||
@@ -9,7 +9,3 @@ class SystemThreadingNamespace extends Namespace {
|
||||
this.hasName("Threading")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Threading` namespace. */
|
||||
deprecated
|
||||
SystemThreadingNamespace getSystemThreadingNamespace() { any() }
|
||||
|
||||
@@ -11,10 +11,6 @@ class SystemWebNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web` namespace. */
|
||||
deprecated
|
||||
SystemWebNamespace getSystemWebNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Web` namespace. */
|
||||
class SystemWebClass extends Class {
|
||||
SystemWebClass() {
|
||||
@@ -288,19 +284,3 @@ class SystemWebHtmlString extends SystemWebClass {
|
||||
this.hasName("HtmlString")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.HttpRequest` class. */
|
||||
deprecated
|
||||
SystemWebHttpRequestClass getSystemWebHttpRequestClass() { any() }
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.UnvalidatedRequestValues` class. */
|
||||
deprecated
|
||||
SystemWebUnvalidatedRequestValues getSystemWebUnvalidatedRequestValues() { any() }
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.HttpRequestMessage` class. */
|
||||
deprecated
|
||||
SystemWebHttpRequestMessageClass getSystemWebHttpRequestMessageClass() { any() }
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.HttpResponse` class. */
|
||||
deprecated
|
||||
SystemWebHttpResponseClass getSystemWebHttpResponseClass() { any() }
|
||||
|
||||
@@ -18,10 +18,6 @@ class SystemXmlSchemaNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Xml` namespace. */
|
||||
deprecated
|
||||
SystemXmlNamespace getSystemXmlNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Xml` namespace. */
|
||||
class SystemXmlClass extends Class {
|
||||
SystemXmlClass() {
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemCodeDomCompilerNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.CodeDom.Compiler` namespace. */
|
||||
deprecated
|
||||
SystemCodeDomCompilerNamespace getSystemCodeDomCompilerNamespace() { any() }
|
||||
|
||||
/** A reference type in the `System.CodeDom.Compiler` namespace. */
|
||||
class SystemCodeDomCompilerClass extends RefType {
|
||||
SystemCodeDomCompilerClass() {
|
||||
@@ -28,10 +24,6 @@ class SystemCodeDomCompilerGeneratedCodeAttributeClass extends SystemCodeDomComp
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.CodeDom.Compiler.GeneratedCodeAttribute` class. */
|
||||
deprecated
|
||||
SystemCodeDomCompilerGeneratedCodeAttributeClass getSystemCodeDomCompilerGeneratedCodeAttributeClass() { any() }
|
||||
|
||||
/** The `System.CodeDom.Compiler.ICodeCompiler` class. */
|
||||
class SystemCodeDomCompilerICodeCompilerClass extends SystemCodeDomCompilerClass {
|
||||
SystemCodeDomCompilerICodeCompilerClass() {
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemCollectionsGenericNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic` namespace. */
|
||||
deprecated
|
||||
SystemCollectionsGenericNamespace getSystemCollectionsGenericNamespace() { any() }
|
||||
|
||||
/** An unbound generic interface in the `System.Collections.Generic` namespace. */
|
||||
class SystemCollectionsGenericUnboundGenericInterface extends UnboundGenericInterface {
|
||||
SystemCollectionsGenericUnboundGenericInterface() {
|
||||
@@ -50,10 +46,6 @@ class SystemCollectionsGenericIComparerTInterface extends SystemCollectionsGener
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic.IComparer<T>` interface. */
|
||||
deprecated
|
||||
SystemCollectionsGenericIComparerTInterface getSystemCollectionsGenericIComparerTInterface() { any() }
|
||||
|
||||
/** The `System.Collections.Generic.IEqualityComparer<T>` interface. */
|
||||
class SystemCollectionsGenericIEqualityComparerTInterface extends SystemCollectionsGenericUnboundGenericInterface {
|
||||
SystemCollectionsGenericIEqualityComparerTInterface() {
|
||||
@@ -76,10 +68,6 @@ class SystemCollectionsGenericIEqualityComparerTInterface extends SystemCollecti
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic.IEqualityComparer<T>` interface. */
|
||||
deprecated
|
||||
SystemCollectionsGenericIEqualityComparerTInterface getSystemCollectionsGenericIEqualityComparerTInterface() { any() }
|
||||
|
||||
/** The `System.Collections.Generic.IEnumerable<T>` interface. */
|
||||
class SystemCollectionsGenericIEnumerableTInterface extends SystemCollectionsGenericUnboundGenericInterface {
|
||||
SystemCollectionsGenericIEnumerableTInterface() {
|
||||
@@ -89,10 +77,6 @@ class SystemCollectionsGenericIEnumerableTInterface extends SystemCollectionsGen
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic.IEnumerable<T>` interface. */
|
||||
deprecated
|
||||
SystemCollectionsGenericIEnumerableTInterface getSystemCollectionsGenericIEnumerableTInterface() { any() }
|
||||
|
||||
/** The `System.Collections.Generic.IEnumerator<T>` interface. */
|
||||
class SystemCollectionsGenericIEnumeratorInterface extends SystemCollectionsGenericUnboundGenericInterface {
|
||||
SystemCollectionsGenericIEnumeratorInterface() {
|
||||
@@ -111,10 +95,6 @@ class SystemCollectionsGenericIEnumeratorInterface extends SystemCollectionsGene
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic.IEnumerator<T>` interface. */
|
||||
deprecated
|
||||
SystemCollectionsGenericIEnumeratorInterface getSystemCollectionsGenericIEnumeratorInterface() { any() }
|
||||
|
||||
/** The `System.Collections.Generic.IList<T>` interface. */
|
||||
class SystemCollectionsGenericIListTInterface extends SystemCollectionsGenericUnboundGenericInterface {
|
||||
SystemCollectionsGenericIListTInterface() {
|
||||
@@ -124,10 +104,6 @@ class SystemCollectionsGenericIListTInterface extends SystemCollectionsGenericUn
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic.IList<T>` interface. */
|
||||
deprecated
|
||||
SystemCollectionsGenericIListTInterface getSystemCollectionsGenericIListTInterface() { any() }
|
||||
|
||||
/** The `System.Collections.Generic.KeyValuePair<TKey, TValue>` structure. */
|
||||
class SystemCollectionsGenericKeyValuePairStruct extends SystemCollectionsGenericUnboundGenericStruct {
|
||||
SystemCollectionsGenericKeyValuePairStruct() {
|
||||
@@ -155,10 +131,6 @@ class SystemCollectionsGenericKeyValuePairStruct extends SystemCollectionsGeneri
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Generic.KeyValuePair<TKey, TValue>` structure. */
|
||||
deprecated
|
||||
SystemCollectionsGenericKeyValuePairStruct getSystemCollectionsGenericKeyValuePairStruct() { any() }
|
||||
|
||||
/** The `System.Collections.Generic.ICollection<>` interface. */
|
||||
class SystemCollectionsGenericICollectionInterface extends SystemCollectionsGenericUnboundGenericInterface {
|
||||
SystemCollectionsGenericICollectionInterface() {
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemCollectionsSpecializedNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Specialized` namespace. */
|
||||
deprecated
|
||||
SystemCollectionsSpecializedNamespace getSystemCollectionsSpecializedNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Collections.Specialized` namespace. */
|
||||
class SystemCollectionsSpecializedClass extends Class {
|
||||
SystemCollectionsSpecializedClass() {
|
||||
@@ -27,7 +23,3 @@ class SystemCollectionsSpecializedNameValueCollectionClass extends SystemCollect
|
||||
this.hasName("NameValueCollection")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Collections.Specialized.NameValueCollection` class. */
|
||||
deprecated
|
||||
SystemCollectionsSpecializedNameValueCollectionClass getSystemCollectionsSpecializedNameValueCollectionClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemDataSqlClientNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Data.SqlClient` namespace. */
|
||||
deprecated
|
||||
SystemDataSqlClientNamespace getSystemDataSqlClientNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Data.SqlClient` namespace. */
|
||||
class SystemDataSqlClientClass extends Class {
|
||||
SystemDataSqlClientClass() {
|
||||
@@ -28,10 +24,6 @@ class SystemDataSqlClientSqlDataAdapterClass extends SystemDataSqlClientClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Data.SqlClient.SqlDataAdapter` class. */
|
||||
deprecated
|
||||
SystemDataSqlClientSqlDataAdapterClass getSystemDataSqlClientSqlDataAdapterClass() { any() }
|
||||
|
||||
/** The `System.Data.SqlClient.SqlConnection` class. */
|
||||
class SystemDataSqlClientSqlConnectionClass extends SystemDataSqlClientClass {
|
||||
SystemDataSqlClientSqlConnectionClass() {
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemIOCompressionNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.IO` namespace. */
|
||||
deprecated
|
||||
SystemIOCompressionNamespace getSystemIOCompressionNamespace() { any() }
|
||||
|
||||
/** A class in the `System.IO.Compression` namespace. */
|
||||
class SystemIOCompressionClass extends Class {
|
||||
SystemIOCompressionClass() {
|
||||
|
||||
@@ -11,10 +11,6 @@ class SystemRuntimeInteropServicesNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Runtime.InteropServices` namespace. */
|
||||
deprecated
|
||||
SystemRuntimeInteropServicesNamespace getSystemRuntimeInteropServicesNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Runtime.InteropServices` namespace. */
|
||||
class SystemRuntimeInteropServicesClass extends Class {
|
||||
SystemRuntimeInteropServicesClass() {
|
||||
@@ -29,10 +25,6 @@ class SystemRuntimeInteropServicesDllImportAttributeClass extends SystemRuntimeI
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Runtime.InteropServices.DllImportAttribute` class. */
|
||||
deprecated
|
||||
SystemRuntimeInteropServicesDllImportAttributeClass getSystemRuntimeInteropServicesDllImportAttributeClass() { any() }
|
||||
|
||||
/** The `System.Runtime.InteropServices.Marshal` class. */
|
||||
class SystemRuntimeInteropServicesMarshalClass extends SystemRuntimeInteropServicesClass {
|
||||
SystemRuntimeInteropServicesMarshalClass() {
|
||||
@@ -70,17 +62,9 @@ class SystemRuntimeInteropServicesMarshalClass extends SystemRuntimeInteropServi
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Runtime.InteropServices.Marshal` class. */
|
||||
deprecated
|
||||
SystemRuntimeInteropServicesMarshalClass getSystemRuntimeInteropServicesMarshalClass() { any() }
|
||||
|
||||
/** The `System.Runtime.InteropServices.ComImportAttribute` class. */
|
||||
class SystemRuntimeInteropServicesComImportAttributeClass extends SystemRuntimeInteropServicesClass {
|
||||
SystemRuntimeInteropServicesComImportAttributeClass() {
|
||||
this.hasName("ComImportAttribute")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Runtime.InteropServices.ComImportAttribute` class. */
|
||||
deprecated
|
||||
SystemRuntimeInteropServicesComImportAttributeClass getSystemRuntimeInteropServicesComImportAttributeClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemThreadingTasksNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Threading.Tasks` namespace. */
|
||||
deprecated
|
||||
SystemThreadingTasksNamespace getSystemThreadingTasksNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Threading.Tasks` namespace. */
|
||||
class SystemThreadingTasksClass extends Class {
|
||||
SystemThreadingTasksClass() {
|
||||
@@ -35,10 +31,6 @@ class SystemThreadingTasksTaskClass extends SystemThreadingTasksClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Threading.Tasks.Task` class. */
|
||||
deprecated
|
||||
SystemThreadingTasksTaskClass getSystemThreadingTasksTaskClass() { any() }
|
||||
|
||||
/** The `System.Threading.Tasks.Task<T>` class. */
|
||||
class SystemThreadingTasksTaskTClass extends SystemThreadingTasksUnboundGenericClass {
|
||||
SystemThreadingTasksTaskTClass() {
|
||||
@@ -54,7 +46,3 @@ class SystemThreadingTasksTaskTClass extends SystemThreadingTasksUnboundGenericC
|
||||
result.getType() = this.getTypeParameter(0)
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Threading.Tasks.Task<T>` class. */
|
||||
deprecated
|
||||
SystemThreadingTasksTaskTClass getSystemThreadingTasksTaskTClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemWebServicesNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.Services` namespace. */
|
||||
deprecated
|
||||
SystemWebServicesNamespace getSystemWebServicesNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Web.Services` namespace. */
|
||||
class SystemWebServicesClass extends Class {
|
||||
SystemWebServicesClass() {
|
||||
@@ -27,7 +23,3 @@ class SystemWebServicesWebMethodAttributeClass extends SystemWebServicesClass {
|
||||
this.hasName("WebMethodAttribute")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.Services.WebMethodAttribute` class. */
|
||||
deprecated
|
||||
SystemWebServicesWebMethodAttributeClass getSystemWebServicesWebMethodAttributeClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemWebUINamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.UI` namespace. */
|
||||
deprecated
|
||||
SystemWebUINamespace getSystemWebUINamespace() { any() }
|
||||
|
||||
/** A class in the `System.Web.UI` namespace. */
|
||||
class SystemWebUIClass extends Class {
|
||||
SystemWebUIClass() {
|
||||
@@ -28,10 +24,6 @@ class SystemWebUIControlClass extends SystemWebUIClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.UI.Control` class. */
|
||||
deprecated
|
||||
SystemWebUIControlClass getSystemWebUIControlClass() { any() }
|
||||
|
||||
/** The `System.Web.UI.Page` class. */
|
||||
class SystemWebUIPageClass extends SystemWebUIClass {
|
||||
SystemWebUIPageClass() {
|
||||
@@ -75,10 +67,6 @@ class SystemWebUIPageClass extends SystemWebUIClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.UI.Page` class. */
|
||||
deprecated
|
||||
SystemWebUIPageClass getSystemWebUIPageClass() { any() }
|
||||
|
||||
/** The `System.Web.UI.HtmlTextWriter` class. */
|
||||
class SystemWebUIHtmlTextWriterClass extends SystemWebUIClass {
|
||||
SystemWebUIHtmlTextWriterClass() {
|
||||
@@ -116,10 +104,6 @@ class SystemWebUIHtmlTextWriterClass extends SystemWebUIClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.UI.HtmlTextWriter` class. */
|
||||
deprecated
|
||||
SystemWebUIHtmlTextWriterClass getSystemWebUIHtmlTextWriterClass() { any() }
|
||||
|
||||
/** The `System.Web.UI.AttributeCollection` class. */
|
||||
class SystemWebUIAttributeCollectionClass extends SystemWebUIClass {
|
||||
SystemWebUIAttributeCollectionClass() {
|
||||
@@ -139,10 +123,6 @@ class SystemWebUIAttributeCollectionClass extends SystemWebUIClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.UI.AttributeCollection` class. */
|
||||
deprecated
|
||||
SystemWebUIAttributeCollectionClass getSystemWebUIAttributeCollectionClass() { any() }
|
||||
|
||||
/** The `System.Web.UI.ClientScriptManager` class. */
|
||||
class SystemWebUIClientScriptManagerClass extends SystemWebUIClass {
|
||||
SystemWebUIClientScriptManagerClass() {
|
||||
@@ -161,7 +141,3 @@ class SystemWebUIClientScriptManagerClass extends SystemWebUIClass {
|
||||
result.hasName("RegisterClientScriptBlock")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.UI.ClientScriptManager` class. */
|
||||
deprecated
|
||||
SystemWebUIClientScriptManagerClass getSystemWebUIClientScriptManagerClass() { any() }
|
||||
|
||||
@@ -10,10 +10,6 @@ class SystemWebUIWebControlsNamespace extends Namespace {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.UI.WebControls` namespace. */
|
||||
deprecated
|
||||
SystemWebUIWebControlsNamespace getSystemWebUIWebControlsNamespace() { any() }
|
||||
|
||||
/** A class in the `System.Web.UI.WebControls` namespace. */
|
||||
class SystemWebUIWebControlsClass extends Class {
|
||||
SystemWebUIWebControlsClass() {
|
||||
@@ -37,10 +33,6 @@ class SystemWebUIWebControlsTextBoxClass extends SystemWebUIWebControlsClass {
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `System.Web.UI.WebControls.TextBox` class. */
|
||||
deprecated
|
||||
SystemWebUIWebControlsTextBoxClass getSystemWebUIWebControlsTextBoxClass() { any() }
|
||||
|
||||
/** The `System.Web.UI.WebControls.Label` class. */
|
||||
class SystemWebUIWebControlsLabelClass extends SystemWebUIWebControlsClass {
|
||||
SystemWebUIWebControlsLabelClass() {
|
||||
|
||||
@@ -114,7 +114,3 @@ class AssertFailedExceptionClass extends ExceptionClass {
|
||||
this.hasName("AssertFailedException")
|
||||
}
|
||||
}
|
||||
|
||||
/** DEPRECATED. Gets the `Microsoft.VisualStudio.TestTools.UnitTesting.Assert` class. */
|
||||
deprecated
|
||||
VSTestAssertClass getVSTestAssertClass() { any() }
|
||||
|
||||
@@ -80,6 +80,7 @@ class NamedElement extends Element, @dotnet_named_element {
|
||||
}
|
||||
|
||||
/** Gets a unique string label for this element. */
|
||||
cached
|
||||
string getLabel() { none() }
|
||||
|
||||
/** Holds if `other` has the same metadata handle in the same assembly. */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import csharp
|
||||
|
||||
from Expr e, int m
|
||||
where expr_argument(e,m)
|
||||
where expr_argument(e, m)
|
||||
select e, m
|
||||
|
||||
@@ -3,4 +3,3 @@ import semmle.code.asp.AspNet
|
||||
from AspDirective directive, string name, AspAttribute attrib
|
||||
where directive.getAttributeByName(name) = attrib
|
||||
select directive, name, attrib
|
||||
|
||||
|
||||
@@ -3,4 +3,3 @@ import semmle.code.asp.AspNet
|
||||
from AspOpenTag tag, string name, AspAttribute attrib
|
||||
where tag.getAttributeByName(name) = attrib
|
||||
select tag, name, attrib
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import semmle.code.asp.AspNet
|
||||
|
||||
from AspComment comment, string kind
|
||||
where
|
||||
if comment instanceof AspServerComment
|
||||
then kind = "server"
|
||||
else kind = "client"
|
||||
where if comment instanceof AspServerComment then kind = "server" else kind = "client"
|
||||
select comment, comment.getBody(), kind
|
||||
|
||||
@@ -3,4 +3,3 @@ import semmle.code.asp.AspNet
|
||||
from AspDirective directive, string name, AspAttribute attrib
|
||||
where directive.getAttributeByName(name) = attrib
|
||||
select directive, name, attrib
|
||||
|
||||
|
||||
@@ -3,4 +3,3 @@ import semmle.code.asp.AspNet
|
||||
from AspOpenTag tag, string name, AspAttribute attrib
|
||||
where tag.getAttributeByName(name) = attrib
|
||||
select tag, name, attrib
|
||||
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
import semmle.code.asp.AspNet
|
||||
|
||||
from AspComment comment, string kind
|
||||
where
|
||||
if comment instanceof AspServerComment
|
||||
then kind = "server"
|
||||
else kind = "client"
|
||||
where if comment instanceof AspServerComment then kind = "server" else kind = "client"
|
||||
select comment, comment.getBody(), kind
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import csharp
|
||||
|
||||
Version getAVersion()
|
||||
{
|
||||
Version getAVersion() {
|
||||
result = "1.2" or
|
||||
result = "1.2.0" or
|
||||
result = "1.2.0.0" or
|
||||
@@ -15,6 +14,7 @@ Version getAVersion()
|
||||
}
|
||||
|
||||
from Version v1, Version v2
|
||||
where v1 = getAVersion()
|
||||
and v2 = getAVersion()
|
||||
where
|
||||
v1 = getAVersion() and
|
||||
v2 = getAVersion()
|
||||
select v1, v2, v1.compareTo(v2)
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import csharp
|
||||
|
||||
from Version version
|
||||
where version = "1.2.3.4"
|
||||
or version = "2.3.24"
|
||||
or version = "1.2"
|
||||
or version = "xxx"
|
||||
or version = "1.x"
|
||||
or version = "1"
|
||||
or version = ""
|
||||
or version = "1234.56"
|
||||
select version, version.getMajor(), version.getMajorRevision(), version.getMinor(), version.getMinorRevision()
|
||||
where
|
||||
version = "1.2.3.4" or
|
||||
version = "2.3.24" or
|
||||
version = "1.2" or
|
||||
version = "xxx" or
|
||||
version = "1.x" or
|
||||
version = "1" or
|
||||
version = "" or
|
||||
version = "1234.56"
|
||||
select version, version.getMajor(), version.getMajorRevision(), version.getMinor(),
|
||||
version.getMinorRevision()
|
||||
|
||||
@@ -1,41 +1,18 @@
|
||||
import csharp
|
||||
|
||||
class TypeRef extends @typeref
|
||||
{
|
||||
string toString() {
|
||||
hasName(result)
|
||||
}
|
||||
class TypeRef extends @typeref {
|
||||
string toString() { hasName(result) }
|
||||
|
||||
predicate hasName(string name) {
|
||||
typerefs(this, name)
|
||||
}
|
||||
predicate hasName(string name) { typerefs(this, name) }
|
||||
|
||||
Type getType() {
|
||||
typeref_type(this, result)
|
||||
}
|
||||
Type getType() { typeref_type(this, result) }
|
||||
}
|
||||
|
||||
class MissingType extends TypeRef
|
||||
{
|
||||
MissingType() {
|
||||
not exists(getType())
|
||||
}
|
||||
}
|
||||
class MissingType extends TypeRef { MissingType() { not exists(getType()) } }
|
||||
|
||||
from
|
||||
Class class1,
|
||||
MissingType class2,
|
||||
MissingType class3,
|
||||
MissingType class4,
|
||||
MissingType class5,
|
||||
MissingType del2,
|
||||
Field a,
|
||||
Method b,
|
||||
Method c,
|
||||
Method d,
|
||||
Method e,
|
||||
Method f,
|
||||
Method g
|
||||
Class class1, MissingType class2, MissingType class3, MissingType class4, MissingType class5,
|
||||
MissingType del2, Field a, Method b, Method c, Method d, Method e, Method f, Method g
|
||||
where
|
||||
class1.hasQualifiedName("Assembly1.Class1") and
|
||||
class2.hasName("Class2") and
|
||||
@@ -50,10 +27,10 @@ where
|
||||
e.hasName("e") and
|
||||
f.hasName("f") and
|
||||
g.hasName("g") and
|
||||
a.getDeclaringType()=class1 and
|
||||
a.getDeclaringType()=class1 and
|
||||
b.getDeclaringType()=class1 and
|
||||
c.getDeclaringType()=class1 and
|
||||
a.getDeclaringType() = class1 and
|
||||
a.getDeclaringType() = class1 and
|
||||
b.getDeclaringType() = class1 and
|
||||
c.getDeclaringType() = class1 and
|
||||
not exists(c.getParameter(0).getType()) and
|
||||
not exists(a.getType()) and
|
||||
not exists(b.getReturnType()) and
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import csharp
|
||||
|
||||
from Element e, Class c, Method m, Parameter p
|
||||
where c.hasQualifiedName("Locations.Test")
|
||||
and m.getDeclaringType()=c
|
||||
and m.getAParameter()=p
|
||||
and (e=c or e=m or e=p)
|
||||
where
|
||||
c.hasQualifiedName("Locations.Test") and
|
||||
m.getDeclaringType() = c and
|
||||
m.getAParameter() = p and
|
||||
(e = c or e = m or e = p)
|
||||
select e
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import csharp
|
||||
|
||||
from Element e, Assembly a
|
||||
where e.fromSource()
|
||||
and a = e.getALocation()
|
||||
and a.getFullName() = "program, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
where
|
||||
e.fromSource() and
|
||||
a = e.getALocation() and
|
||||
a.getFullName() = "program, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
|
||||
select e
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
import csharp
|
||||
|
||||
from AssignableAccess aa, Assignable a, string s
|
||||
where aa.getTarget() = a
|
||||
and a.fromSource()
|
||||
and (aa instanceof AssignableRead and s = "read" or aa instanceof AssignableWrite and s = "write")
|
||||
where
|
||||
aa.getTarget() = a and
|
||||
a.fromSource() and
|
||||
(
|
||||
aa instanceof AssignableRead and s = "read"
|
||||
or
|
||||
aa instanceof AssignableWrite and s = "write"
|
||||
)
|
||||
select aa, a, s
|
||||
|
||||
@@ -6,7 +6,8 @@ newtype TTargetAccessOption =
|
||||
|
||||
class TargetAccessOption extends TTargetAccessOption {
|
||||
string toString() {
|
||||
result = som().toString() or
|
||||
result = som().toString()
|
||||
or
|
||||
exists(non()) and result = "<none>"
|
||||
}
|
||||
|
||||
@@ -15,19 +16,12 @@ class TargetAccessOption extends TTargetAccessOption {
|
||||
result = non().getLocation()
|
||||
}
|
||||
|
||||
private AssignableAccess som() {
|
||||
this = TTargetAccessSome(result)
|
||||
}
|
||||
private AssignableAccess som() { this = TTargetAccessSome(result) }
|
||||
|
||||
private AssignableDefinition non() {
|
||||
this = TTargetAccessNone(result)
|
||||
}
|
||||
private AssignableDefinition non() { this = TTargetAccessNone(result) }
|
||||
|
||||
predicate fromAssignableDefinition(AssignableDefinition def) {
|
||||
if exists(def.getTargetAccess()) then
|
||||
this.som() = def.getTargetAccess()
|
||||
else
|
||||
this.non() = def
|
||||
if exists(def.getTargetAccess()) then this.som() = def.getTargetAccess() else this.non() = def
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,7 +31,8 @@ newtype TSourceOption =
|
||||
|
||||
class SourceOption extends TSourceOption {
|
||||
string toString() {
|
||||
result = som().toString() or
|
||||
result = som().toString()
|
||||
or
|
||||
exists(non()) and result = "<none>"
|
||||
}
|
||||
|
||||
@@ -46,24 +41,18 @@ class SourceOption extends TSourceOption {
|
||||
result = non().getLocation()
|
||||
}
|
||||
|
||||
private Expr som() {
|
||||
this = TSourceSome(result)
|
||||
}
|
||||
private Expr som() { this = TSourceSome(result) }
|
||||
|
||||
private AssignableDefinition non() {
|
||||
this = TSourceNone(result)
|
||||
}
|
||||
private AssignableDefinition non() { this = TSourceNone(result) }
|
||||
|
||||
predicate fromAssignableDefinition(AssignableDefinition def) {
|
||||
if exists(def.getSource()) then
|
||||
this.som() = def.getSource()
|
||||
else
|
||||
this.non() = def
|
||||
if exists(def.getSource()) then this.som() = def.getSource() else this.non() = def
|
||||
}
|
||||
}
|
||||
|
||||
from AssignableDefinition def, TargetAccessOption access, SourceOption source, string certain
|
||||
where (if def.isCertain() then certain = "certain" else certain = "uncertain")
|
||||
and access.fromAssignableDefinition(def)
|
||||
and source.fromAssignableDefinition(def)
|
||||
where
|
||||
(if def.isCertain() then certain = "certain" else certain = "uncertain") and
|
||||
access.fromAssignableDefinition(def) and
|
||||
source.fromAssignableDefinition(def)
|
||||
select def.getTarget(), def, access, source, certain
|
||||
|
||||
@@ -58,8 +58,6 @@
|
||||
| Assignables.cs:87:10:87:17 | Item1 |
|
||||
| Assignables.cs:87:10:87:17 | Property |
|
||||
| Assignables.cs:87:20:87:26 | Item2 |
|
||||
| Assignables.cs:87:32:87:32 | Item1 |
|
||||
| Assignables.cs:87:35:87:35 | Item2 |
|
||||
| Assignables.cs:88:10:88:10 | Item1 |
|
||||
| Assignables.cs:88:10:88:10 | x |
|
||||
| Assignables.cs:88:13:88:18 | Item2 |
|
||||
@@ -69,13 +67,9 @@
|
||||
| Assignables.cs:88:17:88:17 | x |
|
||||
| Assignables.cs:88:24:88:24 | Item1 |
|
||||
| Assignables.cs:88:27:88:36 | Item2 |
|
||||
| Assignables.cs:88:28:88:32 | Item1 |
|
||||
| Assignables.cs:88:35:88:35 | Item2 |
|
||||
| Assignables.cs:89:10:89:10 | Item1 |
|
||||
| Assignables.cs:89:10:89:10 | b |
|
||||
| Assignables.cs:89:13:89:18 | Item2 |
|
||||
| Assignables.cs:89:24:89:27 | Item1 |
|
||||
| Assignables.cs:89:30:89:35 | Item2 |
|
||||
| Assignables.cs:92:6:92:8 | Item1 |
|
||||
| Assignables.cs:92:11:92:24 | Item2 |
|
||||
| Assignables.cs:92:12:92:15 | Item1 |
|
||||
|
||||
@@ -2,18 +2,19 @@ import csharp
|
||||
|
||||
predicate getExpandedOperatorArgs(Expr e, Expr left, Expr right) {
|
||||
e = any(BinaryArithmeticOperation bo |
|
||||
bo.getLeftOperand() = left and
|
||||
bo.getRightOperand() = right
|
||||
)
|
||||
bo.getLeftOperand() = left and
|
||||
bo.getRightOperand() = right
|
||||
)
|
||||
or
|
||||
e = any(OperatorCall oc |
|
||||
oc.getArgument(0) = left and
|
||||
oc.getArgument(1) = right
|
||||
)
|
||||
oc.getArgument(0) = left and
|
||||
oc.getArgument(1) = right
|
||||
)
|
||||
}
|
||||
|
||||
from AssignOperation ao, AssignExpr ae, Expr op, Expr left, Expr right
|
||||
where ae = ao.getExpandedAssignment()
|
||||
and op = ae.getRValue()
|
||||
and getExpandedOperatorArgs(op, left, right)
|
||||
where
|
||||
ae = ao.getExpandedAssignment() and
|
||||
op = ae.getRValue() and
|
||||
getExpandedOperatorArgs(op, left, right)
|
||||
select ao, ae, ae.getLValue(), op, left, right
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
| async.cs:11:29:11:32 | Main | file://:0:0:0:0 | private |
|
||||
| async.cs:11:29:11:32 | Main | file://:0:0:0:0 | static |
|
||||
| async.cs:22:35:22:57 | PrintContentLengthAsync | file://:0:0:0:0 | async |
|
||||
| async.cs:22:35:22:57 | PrintContentLengthAsync | file://:0:0:0:0 | private |
|
||||
| async.cs:22:35:22:57 | PrintContentLengthAsync | file://:0:0:0:0 | static |
|
||||
| async.cs:28:40:28:57 | ContentLengthAsync | file://:0:0:0:0 | async |
|
||||
| async.cs:28:40:28:57 | ContentLengthAsync | file://:0:0:0:0 | private |
|
||||
| async.cs:28:40:28:57 | ContentLengthAsync | file://:0:0:0:0 | static |
|
||||
| async.cs:38:35:38:47 | AsyncIterator | file://:0:0:0:0 | async |
|
||||
| async.cs:38:35:38:47 | AsyncIterator | file://:0:0:0:0 | private |
|
||||
| async.cs:38:35:38:47 | AsyncIterator | file://:0:0:0:0 | static |
|
||||
| async.cs:50:49:50:57 | OpenAsync | file://:0:0:0:0 | async |
|
||||
| async.cs:50:49:50:57 | OpenAsync | file://:0:0:0:0 | private |
|
||||
| async.cs:50:49:50:57 | OpenAsync | file://:0:0:0:0 | static |
|
||||
| async.cs:11:29:11:32 | Main | | private |
|
||||
| async.cs:11:29:11:32 | Main | | static |
|
||||
| async.cs:22:35:22:57 | PrintContentLengthAsync | | async |
|
||||
| async.cs:22:35:22:57 | PrintContentLengthAsync | | private |
|
||||
| async.cs:22:35:22:57 | PrintContentLengthAsync | | static |
|
||||
| async.cs:28:40:28:57 | ContentLengthAsync | | async |
|
||||
| async.cs:28:40:28:57 | ContentLengthAsync | | private |
|
||||
| async.cs:28:40:28:57 | ContentLengthAsync | | static |
|
||||
| async.cs:38:35:38:47 | AsyncIterator | | async |
|
||||
| async.cs:38:35:38:47 | AsyncIterator | | private |
|
||||
| async.cs:38:35:38:47 | AsyncIterator | | static |
|
||||
| async.cs:50:49:50:57 | OpenAsync | | async |
|
||||
| async.cs:50:49:50:57 | OpenAsync | | private |
|
||||
| async.cs:50:49:50:57 | OpenAsync | | static |
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
/**
|
||||
* @name Test that types, methods, and parameters can have attributes
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
where exists(Attribute a | a.getTarget() instanceof Type)
|
||||
and exists(Attribute a | a.getTarget() instanceof Method)
|
||||
and exists(Attribute a | a.getTarget() instanceof Parameter)
|
||||
where
|
||||
exists(Attribute a | a.getTarget() instanceof Type) and
|
||||
exists(Attribute a | a.getTarget() instanceof Method) and
|
||||
exists(Attribute a | a.getTarget() instanceof Parameter)
|
||||
select 1
|
||||
|
||||
@@ -2,14 +2,12 @@ import csharp
|
||||
import semmle.code.csharp.dataflow.DataFlow::DataFlow
|
||||
|
||||
class FlowConfig extends Configuration {
|
||||
FlowConfig() { this="FlowConfig" }
|
||||
FlowConfig() { this = "FlowConfig" }
|
||||
|
||||
override predicate isSource(Node source) {
|
||||
source.asExpr() instanceof Literal
|
||||
}
|
||||
override predicate isSource(Node source) { source.asExpr() instanceof Literal }
|
||||
|
||||
override predicate isSink(Node sink) {
|
||||
exists(LocalVariable decl | sink.asExpr()=decl.getInitializer())
|
||||
exists(LocalVariable decl | sink.asExpr() = decl.getInitializer())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,14 +2,12 @@ import csharp
|
||||
import semmle.code.csharp.dataflow.TaintTracking
|
||||
|
||||
class FlowConfig extends TaintTracking::Configuration {
|
||||
FlowConfig() { this="FlowConfig" }
|
||||
FlowConfig() { this = "FlowConfig" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof Literal
|
||||
}
|
||||
override predicate isSource(DataFlow::Node source) { source.asExpr() instanceof Literal }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(LocalVariable decl | sink.asExpr()=decl.getInitializer())
|
||||
exists(LocalVariable decl | sink.asExpr() = decl.getInitializer())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,13 +2,13 @@ import cil
|
||||
|
||||
// Used only because native PDBs are only supported on Windows.
|
||||
// They are included as tests but disabled here.
|
||||
predicate filterMethod(CIL::Method m)
|
||||
{
|
||||
predicate filterMethod(CIL::Method m) {
|
||||
m.getDeclaringType().getNamespace().getName() = "EmbeddedPdb" or
|
||||
m.getDeclaringType().getNamespace().getName() = "PortablePdb"
|
||||
}
|
||||
|
||||
from CIL::Instruction instruction, CIL::Location location
|
||||
where location = instruction.getLocation()
|
||||
and filterMethod(instruction.getImplementation().getMethod())
|
||||
where
|
||||
location = instruction.getLocation() and
|
||||
filterMethod(instruction.getImplementation().getMethod())
|
||||
select location.toString(), instruction.toString()
|
||||
|
||||
@@ -2,15 +2,15 @@ import cil
|
||||
|
||||
// Used only because native PDBs are only supported on Windows.
|
||||
// They are included as tests but disabled here.
|
||||
predicate filterMethod(CIL::Method m)
|
||||
{
|
||||
predicate filterMethod(CIL::Method m) {
|
||||
m.getDeclaringType().getNamespace().getName() = "EmbeddedPdb" or
|
||||
m.getDeclaringType().getNamespace().getName() = "PortablePdb"
|
||||
}
|
||||
|
||||
from CIL::Method method, CIL::Location location, boolean primaryLocation
|
||||
where location = method.getALocation()
|
||||
and exists(CIL::Location l | l=method.getALocation() | l.getFile().isPdbSourceFile())
|
||||
and (if location=method.getLocation() then primaryLocation=true else primaryLocation=false)
|
||||
and filterMethod(method)
|
||||
where
|
||||
location = method.getALocation() and
|
||||
exists(CIL::Location l | l = method.getALocation() | l.getFile().isPdbSourceFile()) and
|
||||
(if location = method.getLocation() then primaryLocation = true else primaryLocation = false) and
|
||||
filterMethod(method)
|
||||
select method.toStringWithTypes(), location.toString(), primaryLocation
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* This tests the correct extraction of F<T>, and we should end up with
|
||||
* 2 constructed methods of F<T>.
|
||||
*/
|
||||
|
||||
|
||||
// semmle-extractor-options: --cil
|
||||
|
||||
namespace Methods
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import csharp
|
||||
|
||||
from CommentBlock c, CommentLine l
|
||||
where l.getParent()=c
|
||||
where l.getParent() = c
|
||||
select c, c.getNumLines(), l, l.getText(), l.getRawText(), l.getAQlClass()
|
||||
|
||||
@@ -1,24 +1,18 @@
|
||||
import csharp
|
||||
|
||||
from CommentBlock b, Element e, string s
|
||||
where b.getElement()=e
|
||||
and
|
||||
(
|
||||
e instanceof ConstructedMethod
|
||||
or e instanceof ConstructedClass
|
||||
or e instanceof UnboundGenericClass
|
||||
or e instanceof UnboundGenericMethod
|
||||
)
|
||||
and
|
||||
s = e.getAQlClass()
|
||||
and
|
||||
not s = "SourceDeclarationType"
|
||||
and
|
||||
not s = "SourceDeclarationCallable"
|
||||
and
|
||||
not s = "SourceDeclarationMethod"
|
||||
and
|
||||
not s = "NonConstructedMethod"
|
||||
and
|
||||
not s = "RuntimeInstanceMethod"
|
||||
where
|
||||
b.getElement() = e and
|
||||
(
|
||||
e instanceof ConstructedMethod or
|
||||
e instanceof ConstructedClass or
|
||||
e instanceof UnboundGenericClass or
|
||||
e instanceof UnboundGenericMethod
|
||||
) and
|
||||
s = e.getAQlClass() and
|
||||
not s = "SourceDeclarationType" and
|
||||
not s = "SourceDeclarationCallable" and
|
||||
not s = "SourceDeclarationMethod" and
|
||||
not s = "NonConstructedMethod" and
|
||||
not s = "RuntimeInstanceMethod"
|
||||
select b, e, s
|
||||
|
||||
@@ -3,7 +3,8 @@ import semmle.code.csharp.commons.Disposal
|
||||
import Whitelist
|
||||
|
||||
from CIL::Field field
|
||||
where mayBeDisposed(field)
|
||||
and field.getName().charAt(0) = "_" // Filter the results a little
|
||||
and not whitelistedType(field.getDeclaringType())
|
||||
where
|
||||
mayBeDisposed(field) and
|
||||
field.getName().charAt(0) = "_" and // Filter the results a little
|
||||
not whitelistedType(field.getDeclaringType())
|
||||
select field.getQualifiedName()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user