Merge pull request #723 from Semmle/qlucie/master

Master-to-next merge
This commit is contained in:
Max Schaefer
2019-01-07 07:59:54 +00:00
committed by GitHub
655 changed files with 5480 additions and 4355 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -58,7 +58,7 @@ namespace Semmle.Extraction.CSharp.Entities
}
else
{
Context.ModelError(symbol, "Undhandled accessor kind");
Context.ModelError(symbol, "Unhandled accessor kind");
return;
}

View File

@@ -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");
});
}
}

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -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).

View File

@@ -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;

View File

@@ -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);

View File

@@ -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;
}
}
}

View File

@@ -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)

View File

@@ -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);
}
}
}

View File

@@ -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>
{

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;
}
}
}

View File

@@ -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);
}
}

View File

@@ -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" />

View File

@@ -30,6 +30,8 @@ namespace Semmle.Extraction
get; private set;
}
object ICachedEntity.UnderlyingObject => symbol;
public abstract IId Id
{
get;

View File

@@ -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);

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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) {

View File

@@ -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()

View File

@@ -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() }
}

View File

@@ -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()
}

View File

@@ -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() }

View File

@@ -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

View File

@@ -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) }
}
/**

View File

@@ -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.

View File

@@ -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 ... { ... }" }
}

View File

@@ -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) }

View File

@@ -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()
}
}
/**

View File

@@ -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)

View File

@@ -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)
}
}

View File

@@ -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 |

View File

@@ -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) {

View File

@@ -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
}

View File

@@ -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

View File

@@ -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.

View File

@@ -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)
}
}

View File

@@ -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() + ")"
}

View File

@@ -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

View File

@@ -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()
}
}
/**

View File

@@ -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 }
}
/**

View File

@@ -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

View File

@@ -8,7 +8,3 @@ class MicrosoftNamespace extends Namespace {
this.hasName("Microsoft")
}
}
/** DEPRECATED. Gets the `Microsoft` namespace. */
deprecated
MicrosoftNamespace getMicrosoftNamespace() { any() }

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -9,7 +9,3 @@ class SystemCodeDomNamespace extends Namespace {
this.hasName("CodeDom")
}
}
/** DEPRECATED. Gets the `System.CodeDom` namespace. */
deprecated
SystemCodeDomNamespace getSystemCodeDomNamespace() { any() }

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() }

View File

@@ -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() }

View File

@@ -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() }

View File

@@ -9,7 +9,3 @@ class SystemRuntimeNamespace extends Namespace {
this.hasName("Runtime")
}
}
/** DEPRECATED. Gets the `System.Runtime` namespace. */
deprecated
SystemRuntimeNamespace getSystemRuntimeNamespace() { any() }

View File

@@ -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() }

View File

@@ -9,7 +9,3 @@ class SystemThreadingNamespace extends Namespace {
this.hasName("Threading")
}
}
/** DEPRECATED. Gets the `System.Threading` namespace. */
deprecated
SystemThreadingNamespace getSystemThreadingNamespace() { any() }

View File

@@ -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() }

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() }

View File

@@ -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() {

View File

@@ -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() {

View File

@@ -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() }

View File

@@ -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() }

View File

@@ -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() }

View File

@@ -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() }

View File

@@ -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() {

View File

@@ -114,7 +114,3 @@ class AssertFailedExceptionClass extends ExceptionClass {
this.hasName("AssertFailedException")
}
}
/** DEPRECATED. Gets the `Microsoft.VisualStudio.TestTools.UnitTesting.Assert` class. */
deprecated
VSTestAssertClass getVSTestAssertClass() { any() }

View File

@@ -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. */

View File

@@ -1,5 +1,5 @@
import csharp
from Expr e, int m
where expr_argument(e,m)
where expr_argument(e, m)
select e, m

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 |

View File

@@ -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

View File

@@ -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 |

View File

@@ -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

View File

@@ -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())
}
}

View File

@@ -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())
}
}

View File

@@ -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()

View File

@@ -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

View File

@@ -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

View File

@@ -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()

View File

@@ -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

View File

@@ -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