mirror of
https://github.com/github/codeql.git
synced 2026-06-19 03:41:07 +02:00
Merge branch 'bazookamusic/cwe-1427' of https://github.com/github/codeql into bazookamusic/cwe-1427
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
|
||||
## 0.4.36
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
|
||||
## 0.6.28
|
||||
|
||||
|
||||
@@ -15,4 +15,4 @@
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Restructure and rename types related to operations.
|
||||
compatibility: full
|
||||
@@ -1,5 +1,6 @@
|
||||
using System.IO;
|
||||
using Microsoft.CodeAnalysis;
|
||||
using Microsoft.CodeAnalysis.CSharp;
|
||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||
using Semmle.Extraction.Kinds;
|
||||
|
||||
@@ -8,7 +9,7 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
internal abstract class ElementAccess : Expression<ExpressionSyntax>
|
||||
{
|
||||
protected ElementAccess(ExpressionNodeInfo info, ExpressionSyntax qualifier, BracketedArgumentListSyntax argumentList)
|
||||
: base(info.SetKind(GetKind(info.Context, qualifier)))
|
||||
: base(info.SetKind(GetKind(info.Context, info.Node, qualifier)))
|
||||
{
|
||||
this.qualifier = qualifier;
|
||||
this.argumentList = argumentList;
|
||||
@@ -17,6 +18,125 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private readonly ExpressionSyntax qualifier;
|
||||
private readonly BracketedArgumentListSyntax argumentList;
|
||||
|
||||
|
||||
private ISymbol? GetTargetSymbol()
|
||||
{
|
||||
return Context.GetSymbolInfo(base.Syntax).Symbol;
|
||||
}
|
||||
|
||||
private static void SetExprArgument(TextWriter trapFile, Expression left, Expression right)
|
||||
{
|
||||
trapFile.expr_argument(left, 0);
|
||||
trapFile.expr_argument(right, 0);
|
||||
}
|
||||
|
||||
private Expression MakeZeroFromEndExpression(IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var info = new ExpressionInfo(
|
||||
Context,
|
||||
AnnotatedTypeSymbol.CreateNotAnnotated(Context.Compilation.GetSpecialType(SpecialType.System_Int32)),
|
||||
Location,
|
||||
ExprKind.INDEX,
|
||||
parent,
|
||||
child,
|
||||
isCompilerGenerated: true,
|
||||
null);
|
||||
|
||||
var index = new Expression(info);
|
||||
|
||||
MakeZeroLiteral(index, 0);
|
||||
return index;
|
||||
}
|
||||
|
||||
private Expression MakeZeroLiteral(IExpressionParentEntity parent, int child)
|
||||
{
|
||||
return Literal.CreateGenerated(Context, parent, child, Context.Compilation.GetSpecialType(SpecialType.System_Int32), 0, Location);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// It is assumed that either the input is
|
||||
/// 1. A normal expression that can be used as endpoint (e.g a constant like "3").
|
||||
/// 2. An index expression indicating that we should read from the end (e.g "^1").
|
||||
/// </summary>
|
||||
/// <param name="syntax">The syntax node representing the range endpoint.</param>
|
||||
/// <param name="parent">The parent expression entity.</param>
|
||||
/// <param name="child">The child index within the parent.</param>
|
||||
/// <returns>An expression representing the endpoint of a range to be used in conjunction with a slice operation.</returns>
|
||||
private Expression MakeFromRangeEndpoint(ExpressionSyntax syntax, IExpressionParentEntity parent, int child)
|
||||
{
|
||||
var info = new ExpressionNodeInfo(Context, syntax, parent, child);
|
||||
|
||||
return syntax.Kind() == SyntaxKind.IndexExpression
|
||||
? PrefixUnary.Create(info.SetKind(ExprKind.INDEX))
|
||||
: Factory.Create(info);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the given method is a slice method, which is defined as a method with
|
||||
/// the name "Slice" or "Substring" and two parameters.
|
||||
/// </summary>
|
||||
/// <param name="method">The method symbol to check.</param>
|
||||
/// <returns>True if the method is a slice method; false otherwise.</returns>
|
||||
private bool IsSlice(IMethodSymbol method, out RangeExpressionSyntax? range)
|
||||
{
|
||||
range = null;
|
||||
|
||||
if (argumentList.Arguments.Count == 1)
|
||||
{
|
||||
range = argumentList.Arguments[0].Expression as RangeExpressionSyntax;
|
||||
}
|
||||
|
||||
return (method.Name == "Slice" || method.Name == "Substring")
|
||||
&& method.Parameters.Length == 2;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Populates a slice method call based on the given range.
|
||||
/// Roslyn translates indexer accesses with range expressions in the following way.
|
||||
/// 1. s[a..b] -> s.Slice(a, b - a)
|
||||
/// 2. s[..b] -> s.Slice(0, b)
|
||||
/// 3. s[a..] -> s.Slice(a, s.Length - a)
|
||||
/// 4. s[..] -> s.Slice(0, s.Length)
|
||||
/// However, it is possible that both the qualifier or the index endpoints may contain method calls.
|
||||
/// If we want to translate this accurately, we would need to introduce synthetic statements for qualifier and
|
||||
/// the endpoints, which should then be used in the slice method call.
|
||||
/// To avoid this, we translate as follows.
|
||||
/// 1. s[a..b] -> s.Slice(a, b)
|
||||
/// 2. s[..b] -> s.Slice(0, b)
|
||||
/// 3. s[a..] -> s.Slice(a, ^0)
|
||||
/// 4. s[..] -> s.Slice(0, ^0)
|
||||
///
|
||||
/// Even though index expressions can't technically be used in this way, they signal that we
|
||||
/// could perceive ^b as "length - b".
|
||||
///
|
||||
/// Call arguments are only populated when a range expression is directly available in
|
||||
/// the list of arguments.
|
||||
/// This means that cases like below are not handled.
|
||||
/// System.Range x = 1..3;
|
||||
/// s[x]
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trap file to write to.</param>
|
||||
/// <param name="slice">The slice method symbol.</param>
|
||||
/// <param name="range">The range expression syntax.</param>
|
||||
private void PopulateSlice(TextWriter trapFile, IMethodSymbol slice, RangeExpressionSyntax? range)
|
||||
{
|
||||
if (range is not null)
|
||||
{
|
||||
// Populate the call arguments
|
||||
var left = range.LeftOperand is ExpressionSyntax lsyntax
|
||||
? MakeFromRangeEndpoint(lsyntax, this, 0)
|
||||
: MakeZeroLiteral(this, 0);
|
||||
|
||||
var right = range.RightOperand is ExpressionSyntax rsyntax
|
||||
? MakeFromRangeEndpoint(rsyntax, this, 1)
|
||||
: MakeZeroFromEndExpression(this, 1);
|
||||
|
||||
SetExprArgument(trapFile, left, right);
|
||||
}
|
||||
trapFile.expr_call(this, Method.Create(Context, slice));
|
||||
}
|
||||
|
||||
protected override void PopulateExpression(TextWriter trapFile)
|
||||
{
|
||||
if (Kind == ExprKind.POINTER_INDIRECTION)
|
||||
@@ -30,11 +150,19 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
else
|
||||
{
|
||||
Create(Context, qualifier, this, -1);
|
||||
|
||||
var target = GetTargetSymbol();
|
||||
if (target is IMethodSymbol method && IsSlice(method, out var range))
|
||||
{
|
||||
// When an indexer on a span or string is used in conjunction with a range expression, the compiler translates
|
||||
// this into a call to the "Slice" or "Substring" method.
|
||||
// In this case, we want to populate a slice/substring method call instead of an indexer access.
|
||||
PopulateSlice(trapFile, method, range);
|
||||
return;
|
||||
}
|
||||
|
||||
PopulateArguments(trapFile, argumentList, 0);
|
||||
|
||||
var symbolInfo = Context.GetSymbolInfo(base.Syntax);
|
||||
|
||||
if (symbolInfo.Symbol is IPropertySymbol indexer)
|
||||
if (target is IPropertySymbol { IsIndexer: true } indexer)
|
||||
{
|
||||
trapFile.expr_access(this, Indexer.Create(Context, indexer));
|
||||
}
|
||||
@@ -46,8 +174,11 @@ namespace Semmle.Extraction.CSharp.Entities.Expressions
|
||||
private static bool IsArray(ITypeSymbol symbol) =>
|
||||
symbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Array || symbol.IsInlineArray();
|
||||
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax qualifier)
|
||||
private static ExprKind GetKind(Context cx, ExpressionSyntax syntax, ExpressionSyntax qualifier)
|
||||
{
|
||||
if (cx.GetSymbolInfo(syntax).Symbol is IMethodSymbol)
|
||||
return ExprKind.METHOD_INVOCATION;
|
||||
|
||||
var qualifierType = cx.GetType(qualifier);
|
||||
|
||||
// This is a compilation error, so make a guess and continue.
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved extraction of range-access expressions on spans and strings (for example, `a[0..3]`). These expressions are now extracted as `Slice` (span) or `Substring` (string) calls.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Improved property and indexer call target resolution for partially overridden properties and indexers.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: majorAnalysis
|
||||
---
|
||||
* Added Razor Page handler method parameters (e.g., `OnGet`, `OnPost`, `OnPostAsync`) as remote flow sources, enabling security queries such as `cs/sql-injection` to detect vulnerabilities in `PageModel` subclasses.
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: breaking
|
||||
---
|
||||
* Renamed types related to *operation* expressions. The QL classes `BinaryArithmeticOperation`, `BinaryBitwiseOperation`, and `BinaryLogicalOperation` now include compound assignments; for example, `BinaryArithmeticOperation` now includes `a += b`.
|
||||
@@ -50,15 +50,15 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio
|
||||
|
|
||||
add instanceof AddOperation and
|
||||
e1.getAChild*() = add.getAnOperand() and
|
||||
e1 instanceof BinaryBitwiseOperation and
|
||||
e2 = e1.(BinaryBitwiseOperation).getLeftOperand() and
|
||||
e1 instanceof BinaryBitwiseExpr and
|
||||
e2 = e1.(BinaryBitwiseExpr).getLeftOperand() and
|
||||
v = addAssign.getTargetVariable() and
|
||||
addAssign.getAChild*() = add and
|
||||
(xor instanceof BitwiseXorExpr or xor instanceof AssignXorExpr) and
|
||||
addAssign.getControlFlowNode().getASuccessor*() = xor.getControlFlowNode() and
|
||||
xorAssign.getAChild*() = xor and
|
||||
v = xorAssign.getTargetVariable() and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseOperation) and
|
||||
(notOp instanceof UnaryBitwiseOperation or notOp instanceof AssignBitwiseExpr) and
|
||||
xor.getControlFlowNode().getASuccessor*() = notOp.getControlFlowNode() and
|
||||
notAssign.getAChild*() = notOp and
|
||||
v = notAssign.getTargetVariable() and
|
||||
|
||||
@@ -290,7 +290,7 @@ module AssignableInternal {
|
||||
newtype TAssignableDefinition =
|
||||
TAssignmentDefinition(Assignment a) {
|
||||
not a.getLeftOperand() instanceof TupleExpr and
|
||||
not a instanceof AssignCallOperation and
|
||||
not a instanceof AssignCallExpr and
|
||||
not a instanceof AssignCoalesceExpr
|
||||
} or
|
||||
TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or
|
||||
@@ -324,7 +324,7 @@ module AssignableInternal {
|
||||
TAddressOfDefinition(AddressOfExpr aoe) or
|
||||
TPatternDefinition(TopLevelPatternDecl tlpd) or
|
||||
TAssignOperationDefinition(AssignOperation ao) {
|
||||
ao instanceof AssignCallOperation and not ao instanceof CompoundAssignmentOperatorCall
|
||||
ao instanceof AssignCallExpr and not ao instanceof CompoundAssignmentOperatorCall
|
||||
or
|
||||
ao instanceof AssignCoalesceExpr
|
||||
}
|
||||
|
||||
@@ -57,6 +57,28 @@ class DeclarationWithGetSetAccessors extends DeclarationWithAccessors, TopLevelE
|
||||
/** Gets the `set` accessor of this declaration, if any. */
|
||||
Setter getSetter() { result = this.getAnAccessor() }
|
||||
|
||||
/** Gets the target accessor of this declaration when used in a read context, if any. */
|
||||
Accessor getReadTarget() {
|
||||
result = this.getGetter()
|
||||
or
|
||||
not exists(this.getGetter()) and
|
||||
result = this.getOverridee().getReadTarget()
|
||||
}
|
||||
|
||||
/** Gets the target accessor of this declaration when used in a write context, if any. */
|
||||
Accessor getWriteTarget() {
|
||||
result = this.getSetter()
|
||||
or
|
||||
not exists(this.getSetter()) and
|
||||
result = this.getOverridee().getWriteTarget()
|
||||
or
|
||||
result =
|
||||
any(Getter g |
|
||||
g = this.getReadTarget() and
|
||||
g.getAnnotatedReturnType().isRef()
|
||||
)
|
||||
}
|
||||
|
||||
override DeclarationWithGetSetAccessors getOverridee() {
|
||||
result = DeclarationWithAccessors.super.getOverridee()
|
||||
}
|
||||
|
||||
@@ -912,18 +912,17 @@ module Internal {
|
||||
)
|
||||
or
|
||||
// In C#, `null + 1` has type `int?` with value `null`
|
||||
exists(BinaryOperation bo, Expr o |
|
||||
bo instanceof BinaryArithmeticOperation or
|
||||
bo instanceof AssignArithmeticOperation
|
||||
|
|
||||
result = bo and
|
||||
bo.getAnOperand() = e and
|
||||
bo.getAnOperand() = o and
|
||||
// The other operand must be provably non-null in order
|
||||
// for `only if` to hold
|
||||
nonNullValueImplied(o) and
|
||||
e != o
|
||||
)
|
||||
result =
|
||||
any(BinaryArithmeticOperation bao |
|
||||
exists(Expr o |
|
||||
bao.getAnOperand() = e and
|
||||
bao.getAnOperand() = o and
|
||||
// The other operand must be provably non-null in order
|
||||
// for `only if` to hold
|
||||
nonNullValueImplied(o) and
|
||||
e != o
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -934,10 +933,10 @@ module Internal {
|
||||
any(QualifiableExpr qe |
|
||||
qe.isConditional() and
|
||||
result = qe.getQualifier()
|
||||
) or
|
||||
)
|
||||
or
|
||||
// In C#, `null + 1` has type `int?` with value `null`
|
||||
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand()) or
|
||||
e = any(AssignArithmeticOperation aao | result = aao.getAnOperand())
|
||||
e = any(BinaryArithmeticOperation bao | result = bao.getAnOperand())
|
||||
}
|
||||
|
||||
deprecated predicate isGuard(Expr e, GuardValue val) {
|
||||
|
||||
@@ -124,9 +124,7 @@ private module Internal {
|
||||
TDispatchDynamicOperatorCall(DynamicOperatorCall doc) or
|
||||
TDispatchDynamicMemberAccess(DynamicMemberAccess dma) or
|
||||
TDispatchDynamicElementAccess(DynamicElementAccess dea) or
|
||||
TDispatchDynamicEventAccess(
|
||||
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
|
||||
) {
|
||||
TDispatchDynamicEventAccess(AssignArithmeticExpr aao, DynamicMemberAccess dma, string name) {
|
||||
isPotentialEventCall(aao, dma, name)
|
||||
} or
|
||||
TDispatchDynamicObjectCreation(DynamicObjectCreation doc) or
|
||||
@@ -230,7 +228,7 @@ private module Internal {
|
||||
* accessor.
|
||||
*/
|
||||
private predicate isPotentialEventCall(
|
||||
AssignArithmeticOperation aao, DynamicMemberAccess dma, string name
|
||||
AssignArithmeticExpr aao, DynamicMemberAccess dma, string name
|
||||
) {
|
||||
aao instanceof DynamicOperatorCall and
|
||||
dma = aao.getLeftOperand() and
|
||||
@@ -1397,9 +1395,7 @@ private module Internal {
|
||||
private class DispatchDynamicEventAccess extends DispatchReflectionOrDynamicCall,
|
||||
TDispatchDynamicEventAccess
|
||||
{
|
||||
override AssignArithmeticOperation getCall() {
|
||||
this = TDispatchDynamicEventAccess(result, _, _)
|
||||
}
|
||||
override AssignArithmeticExpr getCall() { this = TDispatchDynamicEventAccess(result, _, _) }
|
||||
|
||||
override string getName() { this = TDispatchDynamicEventAccess(_, _, result) }
|
||||
|
||||
|
||||
@@ -11,19 +11,27 @@ import Expr
|
||||
* (`UnaryArithmeticOperation`) or a binary arithmetic operation
|
||||
* (`BinaryArithmeticOperation`).
|
||||
*/
|
||||
class ArithmeticOperation extends Operation, @arith_op_expr {
|
||||
class ArithmeticOperation extends Operation, @arith_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary arithmetic operation. Either a unary minus operation
|
||||
* (`UnaryMinusExpr`), a unary plus operation (`UnaryPlusExpr`),
|
||||
* or a mutator operation (`MutatorOperation`).
|
||||
* A binary arithmetic operation. Either a binary arithmetic expression (`BinaryArithmeticExpr`) or
|
||||
* an arithmetic assignment expression (`AssignArithmeticExpr`).
|
||||
*/
|
||||
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_op_expr { }
|
||||
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary minus operation, for example `-x`.
|
||||
* A unary arithmetic operation. Either a unary minus expression
|
||||
* (`UnaryMinusExpr`), a unary plus expression (`UnaryPlusExpr`),
|
||||
* or a mutator operation (`MutatorOperation`).
|
||||
*/
|
||||
class UnaryArithmeticOperation extends ArithmeticOperation, UnaryOperation, @un_arith_operation { }
|
||||
|
||||
/**
|
||||
* A unary minus expression, for example `-x`.
|
||||
*/
|
||||
class UnaryMinusExpr extends UnaryArithmeticOperation, @minus_expr {
|
||||
override string getOperator() { result = "-" }
|
||||
@@ -32,7 +40,7 @@ class UnaryMinusExpr extends UnaryArithmeticOperation, @minus_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary plus operation, for example `+x`.
|
||||
* A unary plus expression, for example `+x`.
|
||||
*/
|
||||
class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
|
||||
override string getOperator() { result = "+" }
|
||||
@@ -44,40 +52,40 @@ class UnaryPlusExpr extends UnaryArithmeticOperation, @plus_expr {
|
||||
* A mutator operation. Either an increment operation (`IncrementOperation`)
|
||||
* or a decrement operation (`DecrementOperation`).
|
||||
*/
|
||||
class MutatorOperation extends UnaryArithmeticOperation, @mut_op_expr { }
|
||||
class MutatorOperation extends UnaryArithmeticOperation, @mut_operation { }
|
||||
|
||||
/**
|
||||
* An increment operation. Either a postfix increment operation
|
||||
* (`PostIncrExpr`) or a prefix increment operation (`PreIncrExpr`).
|
||||
* An increment operation. Either a postfix increment expression
|
||||
* (`PostIncrExpr`) or a prefix increment expression (`PreIncrExpr`).
|
||||
*/
|
||||
class IncrementOperation extends MutatorOperation, @incr_op_expr {
|
||||
class IncrementOperation extends MutatorOperation, @incr_operation {
|
||||
override string getOperator() { result = "++" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A decrement operation. Either a postfix decrement operation
|
||||
* (`PostDecrExpr`) or a prefix decrement operation (`PreDecrExpr`).
|
||||
* A decrement operation. Either a postfix decrement expression
|
||||
* (`PostDecrExpr`) or a prefix decrement expression (`PreDecrExpr`).
|
||||
*/
|
||||
class DecrementOperation extends MutatorOperation, @decr_op_expr {
|
||||
class DecrementOperation extends MutatorOperation, @decr_operation {
|
||||
override string getOperator() { result = "--" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A prefix increment operation, for example `++x`.
|
||||
* A prefix increment expression, for example `++x`.
|
||||
*/
|
||||
class PreIncrExpr extends IncrementOperation, @pre_incr_expr {
|
||||
override string getAPrimaryQlClass() { result = "PreIncrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A prefix decrement operation, for example `--x`.
|
||||
* A prefix decrement expression, for example `--x`.
|
||||
*/
|
||||
class PreDecrExpr extends DecrementOperation, @pre_decr_expr {
|
||||
override string getAPrimaryQlClass() { result = "PreDecrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A postfix increment operation, for example `x++`.
|
||||
* A postfix increment expression, for example `x++`.
|
||||
*/
|
||||
class PostIncrExpr extends IncrementOperation, @post_incr_expr {
|
||||
override string toString() { result = "..." + this.getOperator() }
|
||||
@@ -86,7 +94,7 @@ class PostIncrExpr extends IncrementOperation, @post_incr_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A postfix decrement operation, for example `x--`.
|
||||
* A postfix decrement expression, for example `x--`.
|
||||
*/
|
||||
class PostDecrExpr extends DecrementOperation, @post_decr_expr {
|
||||
override string toString() { result = "..." + this.getOperator() }
|
||||
@@ -95,55 +103,84 @@ class PostDecrExpr extends DecrementOperation, @post_decr_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary arithmetic operation. Either an addition operation
|
||||
* (`AddExpr`), a subtraction operation (`SubExpr`), a multiplication
|
||||
* operation (`MulExpr`), a division operation (`DivExpr`), or a
|
||||
* remainder operation (`RemExpr`).
|
||||
* An addition operation, either `x + y` or `x += y`.
|
||||
*/
|
||||
class BinaryArithmeticOperation extends ArithmeticOperation, BinaryOperation, @bin_arith_op_expr {
|
||||
override string getOperator() { none() }
|
||||
class AddOperation extends BinaryArithmeticOperation, @add_operation { }
|
||||
|
||||
/**
|
||||
* A subtraction operation, either `x - y` or `x -= y`.
|
||||
*/
|
||||
class SubOperation extends BinaryArithmeticOperation, @sub_operation { }
|
||||
|
||||
/**
|
||||
* A multiplication operation, either `x * y` or `x *= y`.
|
||||
*/
|
||||
class MulOperation extends BinaryArithmeticOperation, @mul_operation { }
|
||||
|
||||
/**
|
||||
* A division operation, either `x / y` or `x /= y`.
|
||||
*/
|
||||
class DivOperation extends BinaryArithmeticOperation, @div_operation {
|
||||
/** Gets the numerator of this division operation. */
|
||||
Expr getNumerator() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An addition operation, for example `x + y`.
|
||||
* A remainder operation, either `x % y` or `x %= y`.
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticOperation, AddOperation, @add_expr {
|
||||
class RemOperation extends BinaryArithmeticOperation, @rem_operation { }
|
||||
|
||||
/**
|
||||
* A binary arithmetic expression. Either an addition expression
|
||||
* (`AddExpr`), a subtraction expression (`SubExpr`), a multiplication
|
||||
* expression (`MulExpr`), a division expression (`DivExpr`), or a
|
||||
* remainder expression (`RemExpr`).
|
||||
*/
|
||||
class BinaryArithmeticExpr extends BinaryArithmeticOperation, @bin_arith_expr { }
|
||||
|
||||
/**
|
||||
* An addition expression, for example `x + y`.
|
||||
*/
|
||||
class AddExpr extends BinaryArithmeticExpr, AddOperation, @add_expr {
|
||||
override string getOperator() { result = "+" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AddExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subtraction operation, for example `x - y`.
|
||||
* A subtraction expression, for example `x - y`.
|
||||
*/
|
||||
class SubExpr extends BinaryArithmeticOperation, SubOperation, @sub_expr {
|
||||
class SubExpr extends BinaryArithmeticExpr, SubOperation, @sub_expr {
|
||||
override string getOperator() { result = "-" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "SubExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A multiplication operation, for example `x * y`.
|
||||
* A multiplication expression, for example `x * y`.
|
||||
*/
|
||||
class MulExpr extends BinaryArithmeticOperation, MulOperation, @mul_expr {
|
||||
class MulExpr extends BinaryArithmeticExpr, MulOperation, @mul_expr {
|
||||
override string getOperator() { result = "*" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "MulExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A division operation, for example `x / y`.
|
||||
* A division expression, for example `x / y`.
|
||||
*/
|
||||
class DivExpr extends BinaryArithmeticOperation, DivOperation, @div_expr {
|
||||
class DivExpr extends BinaryArithmeticExpr, DivOperation, @div_expr {
|
||||
override string getOperator() { result = "/" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "DivExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder operation, for example `x % y`.
|
||||
* A remainder expression, for example `x % y`.
|
||||
*/
|
||||
class RemExpr extends BinaryArithmeticOperation, RemOperation, @rem_expr {
|
||||
class RemExpr extends BinaryArithmeticExpr, RemOperation, @rem_expr {
|
||||
override string getOperator() { result = "%" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RemExpr" }
|
||||
|
||||
@@ -72,9 +72,9 @@ class AssignExpr extends Assignment, @simple_assign_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* An assignment operation. Either an arithmetic assignment operation
|
||||
* (`AssignArithmeticOperation`), a bitwise assignment operation
|
||||
* (`AssignBitwiseOperation`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* An assignment operation. Either an arithmetic assignment expression
|
||||
* (`AssignArithmeticExpr`), a bitwise assignment expression
|
||||
* (`AssignBitwiseExpr`), an event assignment (`AddOrRemoveEventExpr`), or
|
||||
* a null-coalescing assignment (`AssignCoalesceExpr`).
|
||||
*/
|
||||
class AssignOperation extends Assignment, @assign_op_expr {
|
||||
@@ -94,134 +94,147 @@ class AssignOperation extends Assignment, @assign_op_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A compound assignment operation that invokes an operator.
|
||||
* A compound assignment expression that invokes an operator.
|
||||
*
|
||||
* (1) `x += y` invokes the compound assignment operator `+=` (if it exists).
|
||||
* (2) `x += y` invokes the operator `+` and assigns `x + y` to `x`.
|
||||
*
|
||||
* Either an arithmetic assignment operation (`AssignArithmeticOperation`) or a bitwise
|
||||
* assignment operation (`AssignBitwiseOperation`).
|
||||
* Either an arithmetic assignment expression (`AssignArithmeticExpr`) or a bitwise
|
||||
* assignment expression (`AssignBitwiseExpr`).
|
||||
*/
|
||||
class AssignCallOperation extends AssignOperation, OperatorCall, QualifiableExpr,
|
||||
@assign_op_call_expr
|
||||
{
|
||||
class AssignCallExpr extends AssignOperation, OperatorCall, QualifiableExpr, @assign_op_call_expr {
|
||||
override string toString() { result = AssignOperation.super.toString() }
|
||||
}
|
||||
|
||||
/**
|
||||
* An arithmetic assignment operation. Either an addition assignment operation
|
||||
* (`AssignAddExpr`), a subtraction assignment operation (`AssignSubExpr`), a
|
||||
* multiplication assignment operation (`AssignMulExpr`), a division assignment
|
||||
* operation (`AssignDivExpr`), or a remainder assignment operation
|
||||
* (`AssignRemExpr`).
|
||||
* DEPRECATED: Use `AssignCallExpr` instead.
|
||||
*/
|
||||
class AssignArithmeticOperation extends AssignCallOperation, @assign_arith_expr { }
|
||||
deprecated class AssignCallOperation = AssignCallExpr;
|
||||
|
||||
/**
|
||||
* An addition assignment operation, for example `x += y`.
|
||||
* An arithmetic assignment expression. Either an addition assignment expression
|
||||
* (`AssignAddExpr`), a subtraction assignment expression (`AssignSubExpr`), a
|
||||
* multiplication assignment expression (`AssignMulExpr`), a division assignment
|
||||
* expression (`AssignDivExpr`), or a remainder assignment expression
|
||||
* (`AssignRemExpr`).
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticOperation, AddOperation, @assign_add_expr {
|
||||
class AssignArithmeticExpr extends AssignCallExpr, @assign_arith_expr { }
|
||||
|
||||
/**
|
||||
* DEPRECATED: Use `AssignArithmeticExpr` instead.
|
||||
*/
|
||||
deprecated class AssignArithmeticOperation = AssignArithmeticExpr;
|
||||
|
||||
/**
|
||||
* An addition assignment expression, for example `x += y`.
|
||||
*/
|
||||
class AssignAddExpr extends AssignArithmeticExpr, AddOperation, @assign_add_expr {
|
||||
override string getOperator() { result = "+=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignAddExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A subtraction assignment operation, for example `x -= y`.
|
||||
* A subtraction assignment expression, for example `x -= y`.
|
||||
*/
|
||||
class AssignSubExpr extends AssignArithmeticOperation, SubOperation, @assign_sub_expr {
|
||||
class AssignSubExpr extends AssignArithmeticExpr, SubOperation, @assign_sub_expr {
|
||||
override string getOperator() { result = "-=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignSubExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An multiplication assignment operation, for example `x *= y`.
|
||||
* A multiplication assignment expression, for example `x *= y`.
|
||||
*/
|
||||
class AssignMulExpr extends AssignArithmeticOperation, MulOperation, @assign_mul_expr {
|
||||
class AssignMulExpr extends AssignArithmeticExpr, MulOperation, @assign_mul_expr {
|
||||
override string getOperator() { result = "*=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignMulExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An division assignment operation, for example `x /= y`.
|
||||
* A division assignment expression, for example `x /= y`.
|
||||
*/
|
||||
class AssignDivExpr extends AssignArithmeticOperation, DivOperation, @assign_div_expr {
|
||||
class AssignDivExpr extends AssignArithmeticExpr, DivOperation, @assign_div_expr {
|
||||
override string getOperator() { result = "/=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignDivExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder assignment operation, for example `x %= y`.
|
||||
* A remainder assignment expression, for example `x %= y`.
|
||||
*/
|
||||
class AssignRemExpr extends AssignArithmeticOperation, RemOperation, @assign_rem_expr {
|
||||
class AssignRemExpr extends AssignArithmeticExpr, RemOperation, @assign_rem_expr {
|
||||
override string getOperator() { result = "%=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignRemExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise assignment operation. Either a bitwise-and assignment
|
||||
* operation (`AssignAndExpr`), a bitwise-or assignment
|
||||
* operation (`AssignOrExpr`), a bitwise exclusive-or assignment
|
||||
* operation (`AssignXorExpr`), a left-shift assignment
|
||||
* operation (`AssignLeftShiftExpr`), or a right-shift assignment
|
||||
* operation (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* operation (`AssignUnsignedRightShiftExpr`).
|
||||
* A bitwise assignment expression. Either a bitwise-and assignment
|
||||
* expression (`AssignAndExpr`), a bitwise-or assignment
|
||||
* expression (`AssignOrExpr`), a bitwise exclusive-or assignment
|
||||
* expression (`AssignXorExpr`), a left-shift assignment
|
||||
* expression (`AssignLeftShiftExpr`), or a right-shift assignment
|
||||
* expression (`AssignRightShiftExpr`), or an unsigned right-shift assignment
|
||||
* expression (`AssignUnsignedRightShiftExpr`).
|
||||
*/
|
||||
class AssignBitwiseOperation extends AssignCallOperation, @assign_bitwise_expr { }
|
||||
class AssignBitwiseExpr extends AssignCallExpr, @assign_bitwise_expr { }
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment operation, for example `x &= y`.
|
||||
* DEPRECATED: Use `AssignBitwiseExpr` instead.
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseOperation, BitwiseAndOperation, @assign_and_expr {
|
||||
deprecated class AssignBitwiseOperation = AssignBitwiseExpr;
|
||||
|
||||
/**
|
||||
* A bitwise-and assignment expression, for example `x &= y`.
|
||||
*/
|
||||
class AssignAndExpr extends AssignBitwiseExpr, BitwiseAndOperation, @assign_and_expr {
|
||||
override string getOperator() { result = "&=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignAndExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-or assignment operation, for example `x |= y`.
|
||||
* A bitwise-or assignment expression, for example `x |= y`.
|
||||
*/
|
||||
class AssignOrExpr extends AssignBitwiseOperation, BitwiseOrOperation, @assign_or_expr {
|
||||
class AssignOrExpr extends AssignBitwiseExpr, BitwiseOrOperation, @assign_or_expr {
|
||||
override string getOperator() { result = "|=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignOrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or assignment operation, for example `x ^= y`.
|
||||
* A bitwise exclusive-or assignment expression, for example `x ^= y`.
|
||||
*/
|
||||
class AssignXorExpr extends AssignBitwiseOperation, BitwiseXorOperation, @assign_xor_expr {
|
||||
class AssignXorExpr extends AssignBitwiseExpr, BitwiseXorOperation, @assign_xor_expr {
|
||||
override string getOperator() { result = "^=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignXorExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A left-shift assignment operation, for example `x <<= y`.
|
||||
* A left-shift assignment expression, for example `x <<= y`.
|
||||
*/
|
||||
class AssignLeftShiftExpr extends AssignBitwiseOperation, LeftShiftOperation, @assign_lshift_expr {
|
||||
class AssignLeftShiftExpr extends AssignBitwiseExpr, LeftShiftOperation, @assign_lshift_expr {
|
||||
override string getOperator() { result = "<<=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignLeftShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A right-shift assignment operation, for example `x >>= y`.
|
||||
* A right-shift assignment expression, for example `x >>= y`.
|
||||
*/
|
||||
class AssignRightShiftExpr extends AssignBitwiseOperation, RightShiftOperation, @assign_rshift_expr {
|
||||
class AssignRightShiftExpr extends AssignBitwiseExpr, RightShiftOperation, @assign_rshift_expr {
|
||||
override string getOperator() { result = ">>=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unsigned right-shift assignment operation, for example `x >>>= y`.
|
||||
* An unsigned right-shift assignment expression, for example `x >>>= y`.
|
||||
*/
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseOperation, UnsignedRightShiftOperation,
|
||||
class AssignUnsignedRightShiftExpr extends AssignBitwiseExpr, UnsignedRightShiftOperation,
|
||||
@assign_urshift_expr
|
||||
{
|
||||
override string getOperator() { result = ">>>=" }
|
||||
@@ -297,10 +310,10 @@ class RemoveEventExpr extends AddOrRemoveEventExpr, @remove_event_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing assignment operation, for example `x ??= y`.
|
||||
* A null-coalescing assignment expression, for example `x ??= y`.
|
||||
*/
|
||||
class AssignCoalesceExpr extends AssignOperation, NullCoalescingOperation, @assign_coalesce_expr {
|
||||
override string toString() { result = "... ??= ..." }
|
||||
override string getOperator() { result = "??=" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "AssignCoalesceExpr" }
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ import Expr
|
||||
* A bitwise operation. Either a unary bitwise operation (`UnaryBitwiseOperation`)
|
||||
* or a binary bitwise operation (`BinaryBitwiseOperation`).
|
||||
*/
|
||||
class BitwiseOperation extends Operation, @bit_expr { }
|
||||
class BitwiseOperation extends Operation, @bit_operation { }
|
||||
|
||||
/**
|
||||
* A unary bitwise operation, that is, a bitwise complement operation
|
||||
* (`ComplementExpr`).
|
||||
*/
|
||||
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_op_expr { }
|
||||
class UnaryBitwiseOperation extends BitwiseOperation, UnaryOperation, @un_bit_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise complement operation, for example `~x`.
|
||||
* A bitwise complement expression, for example `~x`.
|
||||
*/
|
||||
class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
|
||||
override string getOperator() { result = "~" }
|
||||
@@ -28,67 +28,101 @@ class ComplementExpr extends UnaryBitwiseOperation, @bit_not_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A binary bitwise operation. Either a bitwise-and operation
|
||||
* (`BitwiseAndExpr`), a bitwise-or operation (`BitwiseOrExpr`),
|
||||
* a bitwise exclusive-or operation (`BitwiseXorExpr`), a left-shift
|
||||
* operation (`LeftShiftExpr`), a right-shift operation (`RightShiftExpr`),
|
||||
* or an unsigned right-shift operation (`UnsignedRightShiftExpr`).
|
||||
* A binary bitwise operation. Either a binary bitwise expression (`BinaryBitwiseExpr`) or
|
||||
* a bitwise assignment expression (`AssignBitwiseExpr`).
|
||||
*/
|
||||
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_op_expr {
|
||||
class BinaryBitwiseOperation extends BitwiseOperation, BinaryOperation, @bin_bit_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A left-shift operation, for example `x << y`.
|
||||
* A bitwise-and operation, either `x & y` or `x &= y`.
|
||||
*/
|
||||
class LeftShiftExpr extends BinaryBitwiseOperation, LeftShiftOperation, @lshift_expr {
|
||||
class BitwiseAndOperation extends BinaryBitwiseOperation, @and_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, either `x | y` or `x |= y`.
|
||||
*/
|
||||
class BitwiseOrOperation extends BinaryBitwiseOperation, @or_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`.
|
||||
*/
|
||||
class BitwiseXorOperation extends BinaryBitwiseOperation, @xor_operation { }
|
||||
|
||||
/**
|
||||
* A left-shift operation, either `x << y` or `x <<= y`.
|
||||
*/
|
||||
class LeftShiftOperation extends BinaryBitwiseOperation, @lshift_operation { }
|
||||
|
||||
/**
|
||||
* A right-shift operation, either `x >> y` or `x >>= y`.
|
||||
*/
|
||||
class RightShiftOperation extends BinaryBitwiseOperation, @rshift_operation { }
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, either `x >>> y` or `x >>>= y`.
|
||||
*/
|
||||
class UnsignedRightShiftOperation extends BinaryBitwiseOperation, @urshift_operation { }
|
||||
|
||||
/**
|
||||
* A binary bitwise expression. Either a bitwise-and expression
|
||||
* (`BitwiseAndExpr`), a bitwise-or expression (`BitwiseOrExpr`),
|
||||
* a bitwise exclusive-or expression (`BitwiseXorExpr`), a left-shift
|
||||
* expression (`LeftShiftExpr`), a right-shift expression (`RightShiftExpr`),
|
||||
* or an unsigned right-shift expression (`UnsignedRightShiftExpr`).
|
||||
*/
|
||||
class BinaryBitwiseExpr extends BinaryBitwiseOperation, @bin_bit_expr { }
|
||||
|
||||
/**
|
||||
* A left-shift expression, for example `x << y`.
|
||||
*/
|
||||
class LeftShiftExpr extends BinaryBitwiseExpr, LeftShiftOperation, @lshift_expr {
|
||||
override string getOperator() { result = "<<" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "LeftShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A right-shift operation, for example `x >> y`.
|
||||
* A right-shift expression, for example `x >> y`.
|
||||
*/
|
||||
class RightShiftExpr extends BinaryBitwiseOperation, RightShiftOperation, @rshift_expr {
|
||||
class RightShiftExpr extends BinaryBitwiseExpr, RightShiftOperation, @rshift_expr {
|
||||
override string getOperator() { result = ">>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "RightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, for example `x >>> y`.
|
||||
* An unsigned right-shift expression, for example `x >>> y`.
|
||||
*/
|
||||
class UnsignedRightShiftExpr extends BinaryBitwiseOperation, UnsignedRightShiftOperation,
|
||||
@urshift_expr
|
||||
{
|
||||
class UnsignedRightShiftExpr extends BinaryBitwiseExpr, UnsignedRightShiftOperation, @urshift_expr {
|
||||
override string getOperator() { result = ">>>" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "UnsignedRightShiftExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-and operation, for example `x & y`.
|
||||
* A bitwise-and expression, for example `x & y`.
|
||||
*/
|
||||
class BitwiseAndExpr extends BinaryBitwiseOperation, BitwiseAndOperation, @bit_and_expr {
|
||||
class BitwiseAndExpr extends BinaryBitwiseExpr, BitwiseAndOperation, @bit_and_expr {
|
||||
override string getOperator() { result = "&" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseAndExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, for example `x | y`.
|
||||
* A bitwise-or expression, for example `x | y`.
|
||||
*/
|
||||
class BitwiseOrExpr extends BinaryBitwiseOperation, BitwiseOrOperation, @bit_or_expr {
|
||||
class BitwiseOrExpr extends BinaryBitwiseExpr, BitwiseOrOperation, @bit_or_expr {
|
||||
override string getOperator() { result = "|" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseOrExpr" }
|
||||
}
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, for example `x ^ y`.
|
||||
* A bitwise exclusive-or expression, for example `x ^ y`.
|
||||
*/
|
||||
class BitwiseXorExpr extends BinaryBitwiseOperation, BitwiseXorOperation, @bit_xor_expr {
|
||||
class BitwiseXorExpr extends BinaryBitwiseExpr, BitwiseXorOperation, @bit_xor_expr {
|
||||
override string getOperator() { result = "^" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "BitwiseXorExpr" }
|
||||
|
||||
@@ -609,7 +609,7 @@ class InstanceMutatorOperatorCall extends MutatorOperatorCall {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class CompoundAssignmentOperatorCall extends AssignCallOperation {
|
||||
class CompoundAssignmentOperatorCall extends AssignCallExpr {
|
||||
CompoundAssignmentOperatorCall() { this.getTarget() instanceof CompoundAssignmentOperator }
|
||||
|
||||
override Expr getArgument(int i) { result = this.getChildExpr(i + 1) and i >= 0 }
|
||||
@@ -762,20 +762,12 @@ class AccessorCall extends Call, QualifiableExpr, @call_access_expr {
|
||||
*/
|
||||
class PropertyCall extends AccessorCall, PropertyAccessExpr {
|
||||
override Accessor getReadTarget() {
|
||||
this instanceof AssignableRead and result = this.getProperty().getGetter()
|
||||
this instanceof AssignableRead and result = this.getProperty().getReadTarget()
|
||||
}
|
||||
|
||||
override Accessor getWriteTarget() {
|
||||
this instanceof AssignableWrite and
|
||||
exists(Property p | p = this.getProperty() |
|
||||
result = p.getSetter()
|
||||
or
|
||||
result =
|
||||
any(Getter g |
|
||||
g = p.getGetter() and
|
||||
g.getAnnotatedReturnType().isRef()
|
||||
)
|
||||
)
|
||||
result = this.getProperty().getWriteTarget()
|
||||
}
|
||||
|
||||
override Expr getArgument(int i) {
|
||||
@@ -806,20 +798,12 @@ class PropertyCall extends AccessorCall, PropertyAccessExpr {
|
||||
*/
|
||||
class IndexerCall extends AccessorCall, IndexerAccessExpr {
|
||||
override Accessor getReadTarget() {
|
||||
this instanceof AssignableRead and result = this.getIndexer().getGetter()
|
||||
this instanceof AssignableRead and result = this.getIndexer().getReadTarget()
|
||||
}
|
||||
|
||||
override Accessor getWriteTarget() {
|
||||
this instanceof AssignableWrite and
|
||||
exists(Indexer i | i = this.getIndexer() |
|
||||
result = i.getSetter()
|
||||
or
|
||||
result =
|
||||
any(Getter g |
|
||||
g = i.getGetter() and
|
||||
g.getAnnotatedReturnType().isRef()
|
||||
)
|
||||
)
|
||||
result = this.getIndexer().getWriteTarget()
|
||||
}
|
||||
|
||||
override Expr getArgument(int i) {
|
||||
|
||||
@@ -14,7 +14,6 @@ import Creation
|
||||
import Dynamic
|
||||
import Literal
|
||||
import LogicalOperation
|
||||
import Operation
|
||||
import semmle.code.csharp.controlflow.ControlFlowElement
|
||||
import semmle.code.csharp.Location
|
||||
import semmle.code.csharp.Stmt
|
||||
@@ -212,7 +211,7 @@ class LocalConstantDeclExpr extends LocalVariableDeclExpr {
|
||||
* (`UnaryOperation`), a binary operation (`BinaryOperation`), or a
|
||||
* ternary operation (`TernaryOperation`).
|
||||
*/
|
||||
class Operation extends Expr, @op_expr {
|
||||
class Operation extends Expr, @operation_expr {
|
||||
/** Gets the name of the operator in this operation. */
|
||||
string getOperator() { none() }
|
||||
|
||||
@@ -227,7 +226,7 @@ class Operation extends Expr, @op_expr {
|
||||
* indirection operation (`PointerIndirectionExpr`), an address-of operation
|
||||
* (`AddressOfExpr`), or a unary logical operation (`UnaryLogicalOperation`).
|
||||
*/
|
||||
class UnaryOperation extends Operation, @un_op {
|
||||
class UnaryOperation extends Operation, @un_operation {
|
||||
/** Gets the operand of this unary operation. */
|
||||
Expr getOperand() { result = this.getChild(0) }
|
||||
|
||||
@@ -241,7 +240,7 @@ class UnaryOperation extends Operation, @un_op {
|
||||
* a binary logical operation (`BinaryLogicalOperation`), or an
|
||||
* assignment (`Assignment`).
|
||||
*/
|
||||
class BinaryOperation extends Operation, @bin_op {
|
||||
class BinaryOperation extends Operation, @bin_operation {
|
||||
/** Gets the left operand of this binary operation. */
|
||||
Expr getLeftOperand() { result = this.getChild(0) }
|
||||
|
||||
@@ -264,7 +263,7 @@ class BinaryOperation extends Operation, @bin_op {
|
||||
* A ternary operation, that is, a ternary conditional operation
|
||||
* (`ConditionalExpr`).
|
||||
*/
|
||||
class TernaryOperation extends Operation, @ternary_op { }
|
||||
class TernaryOperation extends Operation, @ternary_operation { }
|
||||
|
||||
/**
|
||||
* A parenthesized expression, for example `(2 + 3)` in
|
||||
|
||||
@@ -11,14 +11,14 @@ import Expr
|
||||
* a binary logical operation (`BinaryLogicalOperation`), or a ternary logical
|
||||
* operation (`TernaryLogicalOperation`).
|
||||
*/
|
||||
class LogicalOperation extends Operation, @log_expr {
|
||||
class LogicalOperation extends Operation, @log_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A unary logical operation, that is, a logical 'not' (`LogicalNotExpr`).
|
||||
*/
|
||||
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_op_expr { }
|
||||
class UnaryLogicalOperation extends LogicalOperation, UnaryOperation, @un_log_operation { }
|
||||
|
||||
/**
|
||||
* A logical 'not', for example `!String.IsNullOrEmpty(s)`.
|
||||
@@ -31,10 +31,10 @@ class LogicalNotExpr extends UnaryLogicalOperation, @log_not_expr {
|
||||
|
||||
/**
|
||||
* A binary logical operation. Either a logical 'and' (`LogicalAndExpr`),
|
||||
* a logical 'or' (`LogicalAndExpr`), or a null-coalescing operation
|
||||
* (`NullCoalescingExpr`).
|
||||
* a logical 'or' (`LogicalOrExpr`), or a null-coalescing operation
|
||||
* (`NullCoalescingOperation`).
|
||||
*/
|
||||
class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_op_expr {
|
||||
class BinaryLogicalOperation extends LogicalOperation, BinaryOperation, @bin_log_operation {
|
||||
override string getOperator() { none() }
|
||||
}
|
||||
|
||||
@@ -57,7 +57,12 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr {
|
||||
}
|
||||
|
||||
/**
|
||||
* A null-coalescing operation, for example `s ?? ""` on line 2 in
|
||||
* A null-coalescing operation, either `x ?? y` or `x ??= y`.
|
||||
*/
|
||||
class NullCoalescingOperation extends BinaryLogicalOperation, @null_coalescing_operation { }
|
||||
|
||||
/**
|
||||
* A null-coalescing expression, for example `s ?? ""` on line 2 in
|
||||
*
|
||||
* ```csharp
|
||||
* string NonNullOrEmpty(string s) {
|
||||
@@ -65,9 +70,7 @@ class LogicalOrExpr extends BinaryLogicalOperation, @log_or_expr {
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation,
|
||||
@null_coalescing_expr
|
||||
{
|
||||
class NullCoalescingExpr extends NullCoalescingOperation, @null_coalescing_expr {
|
||||
override string getOperator() { result = "??" }
|
||||
|
||||
override string getAPrimaryQlClass() { result = "NullCoalescingExpr" }
|
||||
@@ -77,7 +80,7 @@ class NullCoalescingExpr extends BinaryLogicalOperation, NullCoalescingOperation
|
||||
* A ternary logical operation, that is, a ternary conditional expression
|
||||
* (`ConditionalExpr`).
|
||||
*/
|
||||
class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_op_expr { }
|
||||
class TernaryLogicalOperation extends LogicalOperation, TernaryOperation, @ternary_log_operation { }
|
||||
|
||||
/**
|
||||
* A conditional expression, for example `s != null ? s.Length : -1`
|
||||
|
||||
@@ -1,71 +1,6 @@
|
||||
/**
|
||||
* Provides classes for operations that also have compound assignment forms.
|
||||
*/
|
||||
deprecated module;
|
||||
|
||||
import Expr
|
||||
|
||||
/**
|
||||
* An addition operation, either `x + y` or `x += y`.
|
||||
*/
|
||||
class AddOperation extends BinaryOperation, @add_operation { }
|
||||
|
||||
/**
|
||||
* A subtraction operation, either `x - y` or `x -= y`.
|
||||
*/
|
||||
class SubOperation extends BinaryOperation, @sub_operation { }
|
||||
|
||||
/**
|
||||
* A multiplication operation, either `x * y` or `x *= y`.
|
||||
*/
|
||||
class MulOperation extends BinaryOperation, @mul_operation { }
|
||||
|
||||
/**
|
||||
* A division operation, either `x / y` or `x /= y`.
|
||||
*/
|
||||
class DivOperation extends BinaryOperation, @div_operation {
|
||||
/** Gets the numerator of this division operation. */
|
||||
Expr getNumerator() { result = this.getLeftOperand() }
|
||||
|
||||
/** Gets the denominator of this division operation. */
|
||||
Expr getDenominator() { result = this.getRightOperand() }
|
||||
}
|
||||
|
||||
/**
|
||||
* A remainder operation, either `x % y` or `x %= y`.
|
||||
*/
|
||||
class RemOperation extends BinaryOperation, @rem_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-and operation, either `x & y` or `x &= y`.
|
||||
*/
|
||||
class BitwiseAndOperation extends BinaryOperation, @and_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise-or operation, either `x | y` or `x |= y`.
|
||||
*/
|
||||
class BitwiseOrOperation extends BinaryOperation, @or_operation { }
|
||||
|
||||
/**
|
||||
* A bitwise exclusive-or operation, either `x ^ y` or `x ^= y`.
|
||||
*/
|
||||
class BitwiseXorOperation extends BinaryOperation, @xor_operation { }
|
||||
|
||||
/**
|
||||
* A left-shift operation, either `x << y` or `x <<= y`.
|
||||
*/
|
||||
class LeftShiftOperation extends BinaryOperation, @lshift_operation { }
|
||||
|
||||
/**
|
||||
* A right-shift operation, either `x >> y` or `x >>= y`.
|
||||
*/
|
||||
class RightShiftOperation extends BinaryOperation, @rshift_operation { }
|
||||
|
||||
/**
|
||||
* An unsigned right-shift operation, either `x >>> y` or `x >>>= y`.
|
||||
*/
|
||||
class UnsignedRightShiftOperation extends BinaryOperation, @urshift_operation { }
|
||||
|
||||
/**
|
||||
* A null-coalescing operation, either `x ?? y` or `x ??= y`.
|
||||
*/
|
||||
class NullCoalescingOperation extends BinaryOperation, @null_coalescing_operation { }
|
||||
|
||||
@@ -13,6 +13,7 @@ private import semmle.code.csharp.frameworks.system.web.ui.WebControls
|
||||
private import semmle.code.csharp.frameworks.WCF
|
||||
private import semmle.code.csharp.frameworks.microsoft.Owin
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
private import semmle.code.csharp.frameworks.Razor
|
||||
private import semmle.code.csharp.dataflow.internal.ExternalFlow
|
||||
private import semmle.code.csharp.security.dataflow.flowsources.FlowSources
|
||||
|
||||
@@ -314,6 +315,22 @@ class AspNetCoreActionMethodParameter extends AspNetCoreRemoteFlowSource, DataFl
|
||||
override string getSourceType() { result = "ASP.NET Core MVC action method parameter" }
|
||||
}
|
||||
|
||||
/** A parameter to a Razor Page handler method, viewed as a source of remote user input. */
|
||||
class AspNetCorePageHandlerMethodParameter extends AspNetCoreRemoteFlowSource,
|
||||
DataFlow::ParameterNode
|
||||
{
|
||||
AspNetCorePageHandlerMethodParameter() {
|
||||
exists(Parameter p |
|
||||
p = this.getParameter() and
|
||||
p.fromSource()
|
||||
|
|
||||
p = any(PageModelClass pm).getAHandlerMethod().getAParameter()
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = "ASP.NET Core Razor Page handler method parameter" }
|
||||
}
|
||||
|
||||
private class ExternalRemoteFlowSource extends RemoteFlowSource {
|
||||
ExternalRemoteFlowSource() { sourceNode(this, "remote") }
|
||||
|
||||
|
||||
@@ -1254,33 +1254,39 @@ case @expr.kind of
|
||||
|
||||
@delegate_creation_expr = @explicit_delegate_creation_expr | @implicit_delegate_creation_expr;
|
||||
|
||||
@bin_arith_op_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
|
||||
@incr_op_expr = @pre_incr_expr | @post_incr_expr;
|
||||
@decr_op_expr = @pre_decr_expr | @post_decr_expr;
|
||||
@mut_op_expr = @incr_op_expr | @decr_op_expr;
|
||||
@un_arith_op_expr = @plus_expr | @minus_expr | @mut_op_expr;
|
||||
@arith_op_expr = @bin_arith_op_expr | @un_arith_op_expr;
|
||||
@bin_arith_expr = @mul_expr | @div_expr | @rem_expr | @add_expr | @sub_expr;
|
||||
@bin_arith_operation = @mul_operation | @div_operation | @rem_operation | @add_operation | @sub_operation;
|
||||
|
||||
@ternary_log_op_expr = @conditional_expr;
|
||||
@bin_log_op_expr = @log_and_expr | @log_or_expr | @null_coalescing_expr;
|
||||
@un_log_op_expr = @log_not_expr;
|
||||
@log_expr = @un_log_op_expr | @bin_log_op_expr | @ternary_log_op_expr;
|
||||
@incr_operation = @pre_incr_expr | @post_incr_expr;
|
||||
@decr_operation = @pre_decr_expr | @post_decr_expr;
|
||||
@mut_operation = @incr_operation | @decr_operation;
|
||||
@un_arith_operation = @plus_expr | @minus_expr | @mut_operation;
|
||||
@arith_operation = @bin_arith_operation | @un_arith_operation;
|
||||
|
||||
@bin_bit_op_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
|
||||
| @rshift_expr | @urshift_expr;
|
||||
@un_bit_op_expr = @bit_not_expr;
|
||||
@bit_expr = @un_bit_op_expr | @bin_bit_op_expr;
|
||||
@ternary_log_operation = @conditional_expr;
|
||||
@bin_log_operation = @log_and_expr | @log_or_expr | @null_coalescing_operation;
|
||||
@un_log_operation = @log_not_expr;
|
||||
@log_operation = @un_log_operation | @bin_log_operation | @ternary_log_operation;
|
||||
|
||||
@bin_bit_expr = @bit_and_expr | @bit_or_expr | @bit_xor_expr | @lshift_expr
|
||||
| @rshift_expr | @urshift_expr;
|
||||
@bin_bit_operation = @and_operation | @or_operation | @xor_operation | @lshift_operation
|
||||
| @rshift_operation | @urshift_operation;
|
||||
@un_bit_expr = @bit_not_expr;
|
||||
@un_bit_operation = @un_bit_expr;
|
||||
@bit_expr = @un_bit_expr | @bin_bit_expr;
|
||||
@bit_operation = @un_bit_operation | @bin_bit_operation;
|
||||
|
||||
@equality_op_expr = @eq_expr | @ne_expr;
|
||||
@rel_op_expr = @gt_expr | @lt_expr| @ge_expr | @le_expr;
|
||||
@comp_expr = @equality_op_expr | @rel_op_expr;
|
||||
|
||||
@op_expr = @un_op | @bin_op | @ternary_op;
|
||||
@operation_expr = @un_operation | @bin_operation | @ternary_operation;
|
||||
|
||||
@ternary_op = @ternary_log_op_expr;
|
||||
@bin_op = @assign_expr | @bin_arith_op_expr | @bin_log_op_expr | @bin_bit_op_expr | @comp_expr;
|
||||
@un_op = @un_arith_op_expr | @un_log_op_expr | @un_bit_op_expr | @sizeof_expr
|
||||
| @pointer_indirection_expr | @address_of_expr;
|
||||
@ternary_operation = @ternary_log_operation;
|
||||
@bin_operation = @assign_expr | @bin_arith_operation | @bin_log_operation | @bin_bit_operation | @comp_expr;
|
||||
@un_operation = @un_arith_operation | @un_log_operation | @un_bit_operation | @sizeof_expr
|
||||
| @pointer_indirection_expr | @address_of_expr;
|
||||
|
||||
@anonymous_function_expr = @lambda_expr | @anonymous_method_expr;
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Restructure and rename types related to operations.
|
||||
compatibility: full
|
||||
@@ -63,7 +63,7 @@ module CallTargetStats implements StatsSig {
|
||||
|
||||
additional predicate isNotOkCall(Call c) {
|
||||
not exists(c.getTarget()) and
|
||||
not c instanceof DelegateCall and
|
||||
not c instanceof DelegateLikeCall and
|
||||
not c instanceof DynamicExpr and
|
||||
not isNoSetterPropertyCallInConstructor(c) and
|
||||
not isNoSetterPropertyInitialization(c) and
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
binarybitwise
|
||||
| Operators.cs:7:18:7:25 | ... >>> ... | Operators.cs:7:18:7:19 | access to local variable x1 | Operators.cs:7:25:7:25 | 2 | >>> | UnsignedRightShiftExpr |
|
||||
| Operators.cs:10:18:10:25 | ... >>> ... | Operators.cs:10:18:10:19 | access to local variable y1 | Operators.cs:10:25:10:25 | 3 | >>> | UnsignedRightShiftExpr |
|
||||
| Operators.cs:13:9:13:16 | ... >>>= ... | Operators.cs:13:9:13:9 | access to local variable z | Operators.cs:13:16:13:16 | 5 | >>>= | AssignUnsignedRightShiftExpr |
|
||||
assignbitwise
|
||||
| Operators.cs:13:9:13:16 | ... >>>= ... | Operators.cs:13:9:13:9 | access to local variable z | Operators.cs:13:16:13:16 | 5 | >>>= | AssignUnsignedRightShiftExpr |
|
||||
userdefined
|
||||
|
||||
@@ -11,7 +11,7 @@ query predicate binarybitwise(
|
||||
}
|
||||
|
||||
query predicate assignbitwise(
|
||||
AssignBitwiseOperation op, Expr left, Expr right, string name, string qlclass
|
||||
AssignBitwiseExpr op, Expr left, Expr right, string name, string qlclass
|
||||
) {
|
||||
op.getFile().getStem() = "Operators" and
|
||||
left = op.getLeftOperand() and
|
||||
|
||||
@@ -442,4 +442,31 @@ namespace My.Qltest
|
||||
|
||||
static void Sink(object o) { }
|
||||
}
|
||||
|
||||
// Test operator overloads
|
||||
public class N
|
||||
{
|
||||
public void operator +=(N y) => throw null;
|
||||
|
||||
public void operator checked +=(N y) => throw null;
|
||||
|
||||
public void M1(N n)
|
||||
{
|
||||
var n0 = new N();
|
||||
n += n0;
|
||||
Sink(n);
|
||||
}
|
||||
|
||||
public void M2(N n)
|
||||
{
|
||||
var n0 = new N();
|
||||
checked
|
||||
{
|
||||
n += n0;
|
||||
}
|
||||
Sink(n);
|
||||
}
|
||||
|
||||
static void Sink(object o) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,14 +32,16 @@ models
|
||||
| 31 | Summary: My.Qltest; Library; false; GetValue; (); ; Argument[this].SyntheticField[X]; ReturnValue; value; dfc-generated |
|
||||
| 32 | Summary: My.Qltest; Library; false; MixedFlowArgs; (System.Object,System.Object); ; Argument[1]; ReturnValue; value; manual |
|
||||
| 33 | Summary: My.Qltest; Library; false; SetValue; (System.Object); ; Argument[0]; Argument[this].SyntheticField[X]; value; dfc-generated |
|
||||
| 34 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; Method1; (System.Object); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 35 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; StaticMethod1; (System.Object); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 36 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; get_Property1; (System.Object); ; Argument[0].SyntheticField[TestExtensions.Property1]; ReturnValue; value; manual |
|
||||
| 37 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; set_Property1; (System.Object,System.Object); ; Argument[1]; Argument[0].SyntheticField[TestExtensions.Property1]; value; manual |
|
||||
| 38 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; GenericMethod1; (T); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 39 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; GenericStaticMethod1; (T); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 40 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; get_GenericProperty1; (T); ; Argument[0].SyntheticField[TestExtensions.GenericProperty1]; ReturnValue; value; manual |
|
||||
| 41 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; set_GenericProperty1; (T,T); ; Argument[1]; Argument[0].SyntheticField[TestExtensions.GenericProperty1]; value; manual |
|
||||
| 34 | Summary: My.Qltest; N; false; op_AdditionAssignment; (My.Qltest.N); ; Argument[0]; Argument[this]; taint; manual |
|
||||
| 35 | Summary: My.Qltest; N; false; op_CheckedAdditionAssignment; (My.Qltest.N); ; Argument[0]; Argument[this]; taint; manual |
|
||||
| 36 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; Method1; (System.Object); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 37 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; StaticMethod1; (System.Object); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 38 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; get_Property1; (System.Object); ; Argument[0].SyntheticField[TestExtensions.Property1]; ReturnValue; value; manual |
|
||||
| 39 | Summary: My.Qltest; TestExtensions+extension(System.Object); false; set_Property1; (System.Object,System.Object); ; Argument[1]; Argument[0].SyntheticField[TestExtensions.Property1]; value; manual |
|
||||
| 40 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; GenericMethod1; (T); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 41 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; GenericStaticMethod1; (T); ; Argument[0]; ReturnValue; value; manual |
|
||||
| 42 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; get_GenericProperty1; (T); ; Argument[0].SyntheticField[TestExtensions.GenericProperty1]; ReturnValue; value; manual |
|
||||
| 43 | Summary: My.Qltest; TestExtensions+extension(T)<T>; false; set_GenericProperty1; (T,T); ; Argument[1]; Argument[0].SyntheticField[TestExtensions.GenericProperty1]; value; manual |
|
||||
edges
|
||||
| ExternalFlow.cs:9:20:9:23 | access to local variable arg1 : Object | ExternalFlow.cs:10:29:10:32 | access to local variable arg1 : Object | provenance | |
|
||||
| ExternalFlow.cs:9:27:9:38 | object creation of type Object : Object | ExternalFlow.cs:9:20:9:23 | access to local variable arg1 : Object | provenance | |
|
||||
@@ -162,69 +164,77 @@ edges
|
||||
| ExternalFlow.cs:373:17:373:19 | access to local variable obj : Object | ExternalFlow.cs:377:45:377:47 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:373:23:373:34 | object creation of type Object : Object | ExternalFlow.cs:373:17:373:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:374:17:374:18 | access to local variable o1 : Object | ExternalFlow.cs:375:18:375:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:374:22:374:24 | access to local variable obj : Object | ExternalFlow.cs:374:22:374:34 | call to method Method1 : Object | provenance | MaD:34 |
|
||||
| ExternalFlow.cs:374:22:374:24 | access to local variable obj : Object | ExternalFlow.cs:374:22:374:34 | call to method Method1 : Object | provenance | MaD:36 |
|
||||
| ExternalFlow.cs:374:22:374:34 | call to method Method1 : Object | ExternalFlow.cs:374:17:374:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:377:17:377:18 | access to local variable o2 : Object | ExternalFlow.cs:378:18:378:19 | access to local variable o2 | provenance | |
|
||||
| ExternalFlow.cs:377:22:377:48 | call to method Method1 : Object | ExternalFlow.cs:377:17:377:18 | access to local variable o2 : Object | provenance | |
|
||||
| ExternalFlow.cs:377:45:377:47 | access to local variable obj : Object | ExternalFlow.cs:377:22:377:48 | call to method Method1 : Object | provenance | MaD:34 |
|
||||
| ExternalFlow.cs:377:45:377:47 | access to local variable obj : Object | ExternalFlow.cs:377:22:377:48 | call to method Method1 : Object | provenance | MaD:36 |
|
||||
| ExternalFlow.cs:383:17:383:19 | access to local variable obj : Object | ExternalFlow.cs:384:43:384:45 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:383:17:383:19 | access to local variable obj : Object | ExternalFlow.cs:387:51:387:53 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:383:23:383:34 | object creation of type Object : Object | ExternalFlow.cs:383:17:383:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:384:17:384:18 | access to local variable o1 : Object | ExternalFlow.cs:385:18:385:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:384:22:384:46 | call to method StaticMethod1 : Object | ExternalFlow.cs:384:17:384:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:384:43:384:45 | access to local variable obj : Object | ExternalFlow.cs:384:22:384:46 | call to method StaticMethod1 : Object | provenance | MaD:35 |
|
||||
| ExternalFlow.cs:384:43:384:45 | access to local variable obj : Object | ExternalFlow.cs:384:22:384:46 | call to method StaticMethod1 : Object | provenance | MaD:37 |
|
||||
| ExternalFlow.cs:387:17:387:18 | access to local variable o2 : Object | ExternalFlow.cs:388:18:388:19 | access to local variable o2 | provenance | |
|
||||
| ExternalFlow.cs:387:22:387:54 | call to method StaticMethod1 : Object | ExternalFlow.cs:387:17:387:18 | access to local variable o2 : Object | provenance | |
|
||||
| ExternalFlow.cs:387:51:387:53 | access to local variable obj : Object | ExternalFlow.cs:387:22:387:54 | call to method StaticMethod1 : Object | provenance | MaD:35 |
|
||||
| ExternalFlow.cs:387:51:387:53 | access to local variable obj : Object | ExternalFlow.cs:387:22:387:54 | call to method StaticMethod1 : Object | provenance | MaD:37 |
|
||||
| ExternalFlow.cs:393:17:393:19 | access to local variable obj : Object | ExternalFlow.cs:394:27:394:29 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:393:23:393:34 | object creation of type Object : Object | ExternalFlow.cs:393:17:393:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:394:13:394:13 | [post] access to parameter o : Object [synthetic TestExtensions.Property1] : Object | ExternalFlow.cs:395:22:395:22 | access to parameter o : Object [synthetic TestExtensions.Property1] : Object | provenance | |
|
||||
| ExternalFlow.cs:394:27:394:29 | access to local variable obj : Object | ExternalFlow.cs:394:13:394:13 | [post] access to parameter o : Object [synthetic TestExtensions.Property1] : Object | provenance | MaD:37 |
|
||||
| ExternalFlow.cs:394:27:394:29 | access to local variable obj : Object | ExternalFlow.cs:394:13:394:13 | [post] access to parameter o : Object [synthetic TestExtensions.Property1] : Object | provenance | MaD:39 |
|
||||
| ExternalFlow.cs:395:17:395:18 | access to local variable o1 : Object | ExternalFlow.cs:396:18:396:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:395:22:395:22 | access to parameter o : Object [synthetic TestExtensions.Property1] : Object | ExternalFlow.cs:395:22:395:32 | access to property Property1 : Object | provenance | MaD:36 |
|
||||
| ExternalFlow.cs:395:22:395:22 | access to parameter o : Object [synthetic TestExtensions.Property1] : Object | ExternalFlow.cs:395:22:395:32 | access to property Property1 : Object | provenance | MaD:38 |
|
||||
| ExternalFlow.cs:395:22:395:32 | access to property Property1 : Object | ExternalFlow.cs:395:17:395:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:401:17:401:19 | access to local variable obj : Object | ExternalFlow.cs:402:45:402:47 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:401:23:401:34 | object creation of type Object : Object | ExternalFlow.cs:401:17:401:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:402:42:402:42 | [post] access to parameter o : Object [synthetic TestExtensions.Property1] : Object | ExternalFlow.cs:403:51:403:51 | access to parameter o : Object [synthetic TestExtensions.Property1] : Object | provenance | |
|
||||
| ExternalFlow.cs:402:45:402:47 | access to local variable obj : Object | ExternalFlow.cs:402:42:402:42 | [post] access to parameter o : Object [synthetic TestExtensions.Property1] : Object | provenance | MaD:37 |
|
||||
| ExternalFlow.cs:402:45:402:47 | access to local variable obj : Object | ExternalFlow.cs:402:42:402:42 | [post] access to parameter o : Object [synthetic TestExtensions.Property1] : Object | provenance | MaD:39 |
|
||||
| ExternalFlow.cs:403:17:403:18 | access to local variable o1 : Object | ExternalFlow.cs:404:18:404:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:403:22:403:52 | call to extension accessor get_Property1 : Object | ExternalFlow.cs:403:17:403:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:403:51:403:51 | access to parameter o : Object [synthetic TestExtensions.Property1] : Object | ExternalFlow.cs:403:22:403:52 | call to extension accessor get_Property1 : Object | provenance | MaD:36 |
|
||||
| ExternalFlow.cs:403:51:403:51 | access to parameter o : Object [synthetic TestExtensions.Property1] : Object | ExternalFlow.cs:403:22:403:52 | call to extension accessor get_Property1 : Object | provenance | MaD:38 |
|
||||
| ExternalFlow.cs:409:17:409:19 | access to local variable obj : Object | ExternalFlow.cs:410:22:410:24 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:409:17:409:19 | access to local variable obj : Object | ExternalFlow.cs:413:52:413:54 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:409:23:409:34 | object creation of type Object : Object | ExternalFlow.cs:409:17:409:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:410:17:410:18 | access to local variable o1 : Object | ExternalFlow.cs:411:18:411:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:410:22:410:24 | access to local variable obj : Object | ExternalFlow.cs:410:22:410:41 | call to method GenericMethod1 : Object | provenance | MaD:38 |
|
||||
| ExternalFlow.cs:410:22:410:24 | access to local variable obj : Object | ExternalFlow.cs:410:22:410:41 | call to method GenericMethod1 : Object | provenance | MaD:40 |
|
||||
| ExternalFlow.cs:410:22:410:41 | call to method GenericMethod1 : Object | ExternalFlow.cs:410:17:410:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:413:17:413:18 | access to local variable o2 : Object | ExternalFlow.cs:414:18:414:19 | access to local variable o2 | provenance | |
|
||||
| ExternalFlow.cs:413:22:413:55 | call to method GenericMethod1 : Object | ExternalFlow.cs:413:17:413:18 | access to local variable o2 : Object | provenance | |
|
||||
| ExternalFlow.cs:413:52:413:54 | access to local variable obj : Object | ExternalFlow.cs:413:22:413:55 | call to method GenericMethod1 : Object | provenance | MaD:38 |
|
||||
| ExternalFlow.cs:413:52:413:54 | access to local variable obj : Object | ExternalFlow.cs:413:22:413:55 | call to method GenericMethod1 : Object | provenance | MaD:40 |
|
||||
| ExternalFlow.cs:419:17:419:19 | access to local variable obj : Object | ExternalFlow.cs:420:50:420:52 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:419:17:419:19 | access to local variable obj : Object | ExternalFlow.cs:423:58:423:60 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:419:23:419:34 | object creation of type Object : Object | ExternalFlow.cs:419:17:419:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:420:17:420:18 | access to local variable o1 : Object | ExternalFlow.cs:421:18:421:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:420:22:420:53 | call to method GenericStaticMethod1 : Object | ExternalFlow.cs:420:17:420:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:420:50:420:52 | access to local variable obj : Object | ExternalFlow.cs:420:22:420:53 | call to method GenericStaticMethod1 : Object | provenance | MaD:39 |
|
||||
| ExternalFlow.cs:420:50:420:52 | access to local variable obj : Object | ExternalFlow.cs:420:22:420:53 | call to method GenericStaticMethod1 : Object | provenance | MaD:41 |
|
||||
| ExternalFlow.cs:423:17:423:18 | access to local variable o2 : Object | ExternalFlow.cs:424:18:424:19 | access to local variable o2 | provenance | |
|
||||
| ExternalFlow.cs:423:22:423:61 | call to method GenericStaticMethod1 : Object | ExternalFlow.cs:423:17:423:18 | access to local variable o2 : Object | provenance | |
|
||||
| ExternalFlow.cs:423:58:423:60 | access to local variable obj : Object | ExternalFlow.cs:423:22:423:61 | call to method GenericStaticMethod1 : Object | provenance | MaD:39 |
|
||||
| ExternalFlow.cs:423:58:423:60 | access to local variable obj : Object | ExternalFlow.cs:423:22:423:61 | call to method GenericStaticMethod1 : Object | provenance | MaD:41 |
|
||||
| ExternalFlow.cs:429:17:429:19 | access to local variable obj : Object | ExternalFlow.cs:430:34:430:36 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:429:23:429:34 | object creation of type Object : Object | ExternalFlow.cs:429:17:429:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:430:13:430:13 | [post] access to parameter o : Object [property GenericProperty1] : Object | ExternalFlow.cs:431:22:431:22 | access to parameter o : Object [property GenericProperty1] : Object | provenance | |
|
||||
| ExternalFlow.cs:430:13:430:13 | [post] access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | ExternalFlow.cs:431:22:431:22 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | provenance | |
|
||||
| ExternalFlow.cs:430:34:430:36 | access to local variable obj : Object | ExternalFlow.cs:430:13:430:13 | [post] access to parameter o : Object [property GenericProperty1] : Object | provenance | |
|
||||
| ExternalFlow.cs:430:34:430:36 | access to local variable obj : Object | ExternalFlow.cs:430:13:430:13 | [post] access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | provenance | MaD:41 |
|
||||
| ExternalFlow.cs:430:34:430:36 | access to local variable obj : Object | ExternalFlow.cs:430:13:430:13 | [post] access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | provenance | MaD:43 |
|
||||
| ExternalFlow.cs:431:17:431:18 | access to local variable o1 : Object | ExternalFlow.cs:432:18:432:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:431:22:431:22 | access to parameter o : Object [property GenericProperty1] : Object | ExternalFlow.cs:431:22:431:39 | access to property GenericProperty1 : Object | provenance | |
|
||||
| ExternalFlow.cs:431:22:431:22 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | ExternalFlow.cs:431:22:431:39 | access to property GenericProperty1 : Object | provenance | MaD:40 |
|
||||
| ExternalFlow.cs:431:22:431:22 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | ExternalFlow.cs:431:22:431:39 | access to property GenericProperty1 : Object | provenance | MaD:42 |
|
||||
| ExternalFlow.cs:431:22:431:39 | access to property GenericProperty1 : Object | ExternalFlow.cs:431:17:431:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:437:17:437:19 | access to local variable obj : Object | ExternalFlow.cs:438:52:438:54 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:437:23:437:34 | object creation of type Object : Object | ExternalFlow.cs:437:17:437:19 | access to local variable obj : Object | provenance | |
|
||||
| ExternalFlow.cs:438:49:438:49 | [post] access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | ExternalFlow.cs:439:58:439:58 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | provenance | |
|
||||
| ExternalFlow.cs:438:52:438:54 | access to local variable obj : Object | ExternalFlow.cs:438:49:438:49 | [post] access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | provenance | MaD:41 |
|
||||
| ExternalFlow.cs:438:52:438:54 | access to local variable obj : Object | ExternalFlow.cs:438:49:438:49 | [post] access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | provenance | MaD:43 |
|
||||
| ExternalFlow.cs:439:17:439:18 | access to local variable o1 : Object | ExternalFlow.cs:440:18:440:19 | access to local variable o1 | provenance | |
|
||||
| ExternalFlow.cs:439:22:439:59 | call to extension accessor get_GenericProperty1 : Object | ExternalFlow.cs:439:17:439:18 | access to local variable o1 : Object | provenance | |
|
||||
| ExternalFlow.cs:439:58:439:58 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | ExternalFlow.cs:439:22:439:59 | call to extension accessor get_GenericProperty1 : Object | provenance | MaD:40 |
|
||||
| ExternalFlow.cs:439:58:439:58 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | ExternalFlow.cs:439:22:439:59 | call to extension accessor get_GenericProperty1 : Object | provenance | MaD:42 |
|
||||
| ExternalFlow.cs:455:17:455:18 | access to local variable n0 : N | ExternalFlow.cs:456:18:456:19 | access to local variable n0 : N | provenance | |
|
||||
| ExternalFlow.cs:455:22:455:28 | object creation of type N : N | ExternalFlow.cs:455:17:455:18 | access to local variable n0 : N | provenance | |
|
||||
| ExternalFlow.cs:456:13:456:13 | [post] access to parameter n : N | ExternalFlow.cs:457:18:457:18 | access to parameter n | provenance | |
|
||||
| ExternalFlow.cs:456:18:456:19 | access to local variable n0 : N | ExternalFlow.cs:456:13:456:13 | [post] access to parameter n : N | provenance | MaD:34 |
|
||||
| ExternalFlow.cs:462:17:462:18 | access to local variable n0 : N | ExternalFlow.cs:465:22:465:23 | access to local variable n0 : N | provenance | |
|
||||
| ExternalFlow.cs:462:22:462:28 | object creation of type N : N | ExternalFlow.cs:462:17:462:18 | access to local variable n0 : N | provenance | |
|
||||
| ExternalFlow.cs:465:17:465:17 | [post] access to parameter n : N | ExternalFlow.cs:467:18:467:18 | access to parameter n | provenance | |
|
||||
| ExternalFlow.cs:465:22:465:23 | access to local variable n0 : N | ExternalFlow.cs:465:17:465:17 | [post] access to parameter n : N | provenance | MaD:35 |
|
||||
nodes
|
||||
| ExternalFlow.cs:9:20:9:23 | access to local variable arg1 : Object | semmle.label | access to local variable arg1 : Object |
|
||||
| ExternalFlow.cs:9:27:9:38 | object creation of type Object : Object | semmle.label | object creation of type Object : Object |
|
||||
@@ -443,6 +453,16 @@ nodes
|
||||
| ExternalFlow.cs:439:22:439:59 | call to extension accessor get_GenericProperty1 : Object | semmle.label | call to extension accessor get_GenericProperty1 : Object |
|
||||
| ExternalFlow.cs:439:58:439:58 | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object | semmle.label | access to parameter o : Object [synthetic TestExtensions.GenericProperty1] : Object |
|
||||
| ExternalFlow.cs:440:18:440:19 | access to local variable o1 | semmle.label | access to local variable o1 |
|
||||
| ExternalFlow.cs:455:17:455:18 | access to local variable n0 : N | semmle.label | access to local variable n0 : N |
|
||||
| ExternalFlow.cs:455:22:455:28 | object creation of type N : N | semmle.label | object creation of type N : N |
|
||||
| ExternalFlow.cs:456:13:456:13 | [post] access to parameter n : N | semmle.label | [post] access to parameter n : N |
|
||||
| ExternalFlow.cs:456:18:456:19 | access to local variable n0 : N | semmle.label | access to local variable n0 : N |
|
||||
| ExternalFlow.cs:457:18:457:18 | access to parameter n | semmle.label | access to parameter n |
|
||||
| ExternalFlow.cs:462:17:462:18 | access to local variable n0 : N | semmle.label | access to local variable n0 : N |
|
||||
| ExternalFlow.cs:462:22:462:28 | object creation of type N : N | semmle.label | object creation of type N : N |
|
||||
| ExternalFlow.cs:465:17:465:17 | [post] access to parameter n : N | semmle.label | [post] access to parameter n : N |
|
||||
| ExternalFlow.cs:465:22:465:23 | access to local variable n0 : N | semmle.label | access to local variable n0 : N |
|
||||
| ExternalFlow.cs:467:18:467:18 | access to parameter n | semmle.label | access to parameter n |
|
||||
subpaths
|
||||
| ExternalFlow.cs:84:29:84:32 | access to local variable objs : null [element] : Object | ExternalFlow.cs:84:35:84:35 | o : Object | ExternalFlow.cs:84:40:84:40 | access to parameter o : Object | ExternalFlow.cs:84:25:84:41 | call to method Map<Object,Object> : T[] [element] : Object |
|
||||
invalidModelRow
|
||||
@@ -489,3 +509,5 @@ invalidModelRow
|
||||
| ExternalFlow.cs:424:18:424:19 | access to local variable o2 | ExternalFlow.cs:419:23:419:34 | object creation of type Object : Object | ExternalFlow.cs:424:18:424:19 | access to local variable o2 | $@ | ExternalFlow.cs:419:23:419:34 | object creation of type Object : Object | object creation of type Object : Object |
|
||||
| ExternalFlow.cs:432:18:432:19 | access to local variable o1 | ExternalFlow.cs:429:23:429:34 | object creation of type Object : Object | ExternalFlow.cs:432:18:432:19 | access to local variable o1 | $@ | ExternalFlow.cs:429:23:429:34 | object creation of type Object : Object | object creation of type Object : Object |
|
||||
| ExternalFlow.cs:440:18:440:19 | access to local variable o1 | ExternalFlow.cs:437:23:437:34 | object creation of type Object : Object | ExternalFlow.cs:440:18:440:19 | access to local variable o1 | $@ | ExternalFlow.cs:437:23:437:34 | object creation of type Object : Object | object creation of type Object : Object |
|
||||
| ExternalFlow.cs:457:18:457:18 | access to parameter n | ExternalFlow.cs:455:22:455:28 | object creation of type N : N | ExternalFlow.cs:457:18:457:18 | access to parameter n | $@ | ExternalFlow.cs:455:22:455:28 | object creation of type N : N | object creation of type N : N |
|
||||
| ExternalFlow.cs:467:18:467:18 | access to parameter n | ExternalFlow.cs:462:22:462:28 | object creation of type N : N | ExternalFlow.cs:467:18:467:18 | access to parameter n | $@ | ExternalFlow.cs:462:22:462:28 | object creation of type N : N | object creation of type N : N |
|
||||
|
||||
@@ -53,6 +53,8 @@ extensions:
|
||||
- ["My.Qltest", "TestExtensions+extension(T)<T>", false, "GenericStaticMethod1", "(T)", "", "Argument[0]", "ReturnValue", "value", "manual"]
|
||||
- ["My.Qltest", "TestExtensions+extension(T)<T>", false, "get_GenericProperty1", "(T)", "", "Argument[0].SyntheticField[TestExtensions.GenericProperty1]", "ReturnValue", "value", "manual"]
|
||||
- ["My.Qltest", "TestExtensions+extension(T)<T>", false, "set_GenericProperty1", "(T,T)", "", "Argument[1]", "Argument[0].SyntheticField[TestExtensions.GenericProperty1]", "value", "manual"]
|
||||
- ["My.Qltest", "N", false, "op_AdditionAssignment", "(My.Qltest.N)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
- ["My.Qltest", "N", false, "op_CheckedAdditionAssignment", "(My.Qltest.N)", "", "Argument[0]", "Argument[this]", "taint", "manual"]
|
||||
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
|
||||
@@ -63,4 +63,32 @@ namespace Testing
|
||||
{
|
||||
public void MyActionMethod(string param) { }
|
||||
}
|
||||
|
||||
// Razor Page handler tests
|
||||
public class MyPageModel : Microsoft.AspNetCore.Mvc.RazorPages.PageModel
|
||||
{
|
||||
// Handler method parameters are remote flow sources
|
||||
public void OnGet(string id) { }
|
||||
|
||||
public void OnPost(string command, int count) { }
|
||||
|
||||
public void OnPostAsync(string data) { }
|
||||
|
||||
public void OnPut(string value) { }
|
||||
|
||||
public void OnDelete(string itemId) { }
|
||||
|
||||
// Not a handler method — does not start with "On", so not a flow source
|
||||
public void GetUser(string userId) { }
|
||||
|
||||
// Excluded by [NonHandler] attribute, so not a flow source
|
||||
[Microsoft.AspNetCore.Mvc.RazorPages.NonHandlerAttribute]
|
||||
public void OnGetNonHandler(string param) { }
|
||||
}
|
||||
|
||||
// Subclass of a PageModel subclass
|
||||
public class DerivedPageModel : MyPageModel
|
||||
{
|
||||
public void OnPost(string derivedParam) { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,3 +14,10 @@ remoteFlowSources
|
||||
| AspRemoteFlowSource.cs:54:69:54:82 | mapDeleteParam |
|
||||
| AspRemoteFlowSource.cs:56:41:56:44 | item |
|
||||
| AspRemoteFlowSource.cs:64:43:64:47 | param |
|
||||
| AspRemoteFlowSource.cs:71:34:71:35 | id |
|
||||
| AspRemoteFlowSource.cs:73:35:73:41 | command |
|
||||
| AspRemoteFlowSource.cs:73:48:73:52 | count |
|
||||
| AspRemoteFlowSource.cs:75:40:75:43 | data |
|
||||
| AspRemoteFlowSource.cs:77:34:77:38 | value |
|
||||
| AspRemoteFlowSource.cs:79:37:79:42 | itemId |
|
||||
| AspRemoteFlowSource.cs:92:35:92:46 | derivedParam |
|
||||
|
||||
@@ -293,3 +293,69 @@ properties.cs:
|
||||
# 160| 0: [LocalVariableAccess] access to local variable x
|
||||
# 160| 1: [PropertyCall] access to property Prop
|
||||
# 160| -1: [LocalVariableAccess] access to local variable s
|
||||
# 164| 13: [Class] BaseClass
|
||||
# 166| 6: [Property] Value
|
||||
# 166| -1: [TypeMention] int
|
||||
# 168| 3: [Getter] get_Value
|
||||
# 168| 4: [BlockStmt] {...}
|
||||
# 168| 0: [ReturnStmt] return ...;
|
||||
# 168| 0: [FieldAccess] access to field Value.field
|
||||
# 169| 4: [Setter] set_Value
|
||||
#-----| 2: (Parameters)
|
||||
# 169| 0: [Parameter] value
|
||||
# 169| 4: [BlockStmt] {...}
|
||||
# 169| 0: [ExprStmt] ...;
|
||||
# 169| 0: [AssignExpr] ... = ...
|
||||
# 169| 0: [FieldAccess] access to field Value.field
|
||||
# 169| 1: [ParameterAccess] access to parameter value
|
||||
# 166| 7: [Field] Value.field
|
||||
# 173| 14: [Class] DerivedClass1
|
||||
#-----| 3: (Base types)
|
||||
# 173| 0: [TypeMention] BaseClass
|
||||
# 175| 6: [Property] Value
|
||||
# 175| -1: [TypeMention] int
|
||||
# 177| 3: [Getter] get_Value
|
||||
# 177| 4: [BlockStmt] {...}
|
||||
# 177| 0: [ReturnStmt] return ...;
|
||||
# 177| 0: [IntLiteral] 20
|
||||
# 181| 15: [Class] DerivedClass2
|
||||
#-----| 3: (Base types)
|
||||
# 181| 0: [TypeMention] BaseClass
|
||||
# 183| 16: [Class] TestPartialPropertyOverride
|
||||
# 185| 6: [Method] M
|
||||
# 185| -1: [TypeMention] Void
|
||||
# 186| 4: [BlockStmt] {...}
|
||||
# 187| 0: [LocalVariableDeclStmt] ... ...;
|
||||
# 187| 0: [LocalVariableDeclAndInitExpr] DerivedClass1 d1 = ...
|
||||
# 187| -1: [TypeMention] DerivedClass1
|
||||
# 187| 0: [LocalVariableAccess] access to local variable d1
|
||||
# 187| 1: [ObjectCreation] object creation of type DerivedClass1
|
||||
# 187| 0: [TypeMention] DerivedClass1
|
||||
# 188| 1: [ExprStmt] ...;
|
||||
# 188| 0: [AssignExpr] ... = ...
|
||||
# 188| 0: [PropertyCall] access to property Value
|
||||
# 188| -1: [LocalVariableAccess] access to local variable d1
|
||||
# 188| 1: [IntLiteral] 11
|
||||
# 189| 2: [LocalVariableDeclStmt] ... ...;
|
||||
# 189| 0: [LocalVariableDeclAndInitExpr] Int32 test1 = ...
|
||||
# 189| -1: [TypeMention] int
|
||||
# 189| 0: [LocalVariableAccess] access to local variable test1
|
||||
# 189| 1: [PropertyCall] access to property Value
|
||||
# 189| -1: [LocalVariableAccess] access to local variable d1
|
||||
# 191| 3: [LocalVariableDeclStmt] ... ...;
|
||||
# 191| 0: [LocalVariableDeclAndInitExpr] DerivedClass2 d2 = ...
|
||||
# 191| -1: [TypeMention] DerivedClass2
|
||||
# 191| 0: [LocalVariableAccess] access to local variable d2
|
||||
# 191| 1: [ObjectCreation] object creation of type DerivedClass2
|
||||
# 191| 0: [TypeMention] DerivedClass2
|
||||
# 192| 4: [ExprStmt] ...;
|
||||
# 192| 0: [AssignExpr] ... = ...
|
||||
# 192| 0: [PropertyCall] access to property Value
|
||||
# 192| -1: [LocalVariableAccess] access to local variable d2
|
||||
# 192| 1: [IntLiteral] 12
|
||||
# 193| 5: [LocalVariableDeclStmt] ... ...;
|
||||
# 193| 0: [LocalVariableDeclAndInitExpr] Int32 test2 = ...
|
||||
# 193| -1: [TypeMention] int
|
||||
# 193| 0: [LocalVariableAccess] access to local variable test2
|
||||
# 193| 1: [PropertyCall] access to property Value
|
||||
# 193| -1: [LocalVariableAccess] access to local variable d2
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
| Prop.field |
|
||||
| Value.field |
|
||||
| caption |
|
||||
| next |
|
||||
| x |
|
||||
|
||||
@@ -6,3 +6,7 @@
|
||||
| properties.cs:71:28:71:28 | Y | properties.cs:83:39:83:44 | access to property Y | properties.cs:74:13:74:15 | set_Y |
|
||||
| properties.cs:146:24:146:27 | Prop | properties.cs:159:13:159:18 | access to property Prop | properties.cs:148:13:148:15 | get_Prop |
|
||||
| properties.cs:146:24:146:27 | Prop | properties.cs:160:21:160:26 | access to property Prop | properties.cs:148:13:148:15 | get_Prop |
|
||||
| properties.cs:166:28:166:32 | Value | properties.cs:192:13:192:20 | access to property Value | properties.cs:169:13:169:15 | set_Value |
|
||||
| properties.cs:166:28:166:32 | Value | properties.cs:193:25:193:32 | access to property Value | properties.cs:168:13:168:15 | get_Value |
|
||||
| properties.cs:175:29:175:33 | Value | properties.cs:188:13:188:20 | access to property Value | properties.cs:169:13:169:15 | set_Value |
|
||||
| properties.cs:175:29:175:33 | Value | properties.cs:189:25:189:32 | access to property Value | properties.cs:177:13:177:15 | get_Value |
|
||||
|
||||
@@ -160,4 +160,37 @@ namespace Properties
|
||||
var x = s.Prop;
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseClass
|
||||
{
|
||||
public virtual int Value
|
||||
{
|
||||
get { return field; }
|
||||
set { field = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public class DerivedClass1 : BaseClass
|
||||
{
|
||||
public override int Value
|
||||
{
|
||||
get { return 20; }
|
||||
}
|
||||
}
|
||||
|
||||
public class DerivedClass2 : BaseClass { }
|
||||
|
||||
public class TestPartialPropertyOverride
|
||||
{
|
||||
public void M()
|
||||
{
|
||||
var d1 = new DerivedClass1();
|
||||
d1.Value = 11;
|
||||
var test1 = d1.Value;
|
||||
|
||||
var d2 = new DerivedClass2();
|
||||
d2.Value = 12;
|
||||
var test2 = d2.Value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
csharp/ql/test/library-tests/spans/Slice.cs
Normal file
29
csharp/ql/test/library-tests/spans/Slice.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
using System;
|
||||
|
||||
public class C
|
||||
{
|
||||
public void M(int a, int b)
|
||||
{
|
||||
var s = "hello world";
|
||||
var sub1 = s[1..a];
|
||||
var sub2 = s[..2];
|
||||
var sub3 = s[3..];
|
||||
var sub4 = s[..^4];
|
||||
var sub5 = s[a..^b];
|
||||
var sub6 = s[..];
|
||||
|
||||
Range range = 1..a;
|
||||
var sub7 = s[range];
|
||||
|
||||
Span<int> sp = null;
|
||||
var slice1 = sp[5..a];
|
||||
var slice2 = sp[..6];
|
||||
var slice3 = sp[7..];
|
||||
var slice4 = sp[..^8];
|
||||
var slice5 = sp[a..^b];
|
||||
var slice6 = sp[..];
|
||||
|
||||
Range range2 = 1..a;
|
||||
var slice7 = sp[range2];
|
||||
}
|
||||
}
|
||||
41
csharp/ql/test/library-tests/spans/slice.expected
Normal file
41
csharp/ql/test/library-tests/spans/slice.expected
Normal file
@@ -0,0 +1,41 @@
|
||||
methodArguments
|
||||
| Slice.cs:8:20:8:26 | call to method Substring | Substring(int, int) | 0 | 1 |
|
||||
| Slice.cs:8:20:8:26 | call to method Substring | Substring(int, int) | 1 | access to parameter a |
|
||||
| Slice.cs:9:20:9:25 | call to method Substring | Substring(int, int) | 0 | 0 |
|
||||
| Slice.cs:9:20:9:25 | call to method Substring | Substring(int, int) | 1 | 2 |
|
||||
| Slice.cs:10:20:10:25 | call to method Substring | Substring(int, int) | 0 | 3 |
|
||||
| Slice.cs:10:20:10:25 | call to method Substring | Substring(int, int) | 1 | ^0 |
|
||||
| Slice.cs:11:20:11:26 | call to method Substring | Substring(int, int) | 0 | 0 |
|
||||
| Slice.cs:11:20:11:26 | call to method Substring | Substring(int, int) | 1 | ^4 |
|
||||
| Slice.cs:12:20:12:27 | call to method Substring | Substring(int, int) | 0 | access to parameter a |
|
||||
| Slice.cs:12:20:12:27 | call to method Substring | Substring(int, int) | 1 | ^access to parameter b |
|
||||
| Slice.cs:13:20:13:24 | call to method Substring | Substring(int, int) | 0 | 0 |
|
||||
| Slice.cs:13:20:13:24 | call to method Substring | Substring(int, int) | 1 | ^0 |
|
||||
| Slice.cs:19:22:19:29 | call to method Slice | Slice(int, int) | 0 | 5 |
|
||||
| Slice.cs:19:22:19:29 | call to method Slice | Slice(int, int) | 1 | access to parameter a |
|
||||
| Slice.cs:20:22:20:28 | call to method Slice | Slice(int, int) | 0 | 0 |
|
||||
| Slice.cs:20:22:20:28 | call to method Slice | Slice(int, int) | 1 | 6 |
|
||||
| Slice.cs:21:22:21:28 | call to method Slice | Slice(int, int) | 0 | 7 |
|
||||
| Slice.cs:21:22:21:28 | call to method Slice | Slice(int, int) | 1 | ^0 |
|
||||
| Slice.cs:22:22:22:29 | call to method Slice | Slice(int, int) | 0 | 0 |
|
||||
| Slice.cs:22:22:22:29 | call to method Slice | Slice(int, int) | 1 | ^8 |
|
||||
| Slice.cs:23:22:23:30 | call to method Slice | Slice(int, int) | 0 | access to parameter a |
|
||||
| Slice.cs:23:22:23:30 | call to method Slice | Slice(int, int) | 1 | ^access to parameter b |
|
||||
| Slice.cs:24:22:24:27 | call to method Slice | Slice(int, int) | 0 | 0 |
|
||||
| Slice.cs:24:22:24:27 | call to method Slice | Slice(int, int) | 1 | ^0 |
|
||||
methodCalls
|
||||
| Slice.cs:3:14:3:14 | call to method <object initializer> | <object initializer>() |
|
||||
| Slice.cs:8:20:8:26 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:9:20:9:25 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:10:20:10:25 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:11:20:11:26 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:12:20:12:27 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:13:20:13:24 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:16:20:16:27 | call to method Substring | Substring(int, int) |
|
||||
| Slice.cs:19:22:19:29 | call to method Slice | Slice(int, int) |
|
||||
| Slice.cs:20:22:20:28 | call to method Slice | Slice(int, int) |
|
||||
| Slice.cs:21:22:21:28 | call to method Slice | Slice(int, int) |
|
||||
| Slice.cs:22:22:22:29 | call to method Slice | Slice(int, int) |
|
||||
| Slice.cs:23:22:23:30 | call to method Slice | Slice(int, int) |
|
||||
| Slice.cs:24:22:24:27 | call to method Slice | Slice(int, int) |
|
||||
| Slice.cs:27:22:27:31 | call to method Slice | Slice(int, int) |
|
||||
17
csharp/ql/test/library-tests/spans/slice.ql
Normal file
17
csharp/ql/test/library-tests/spans/slice.ql
Normal file
@@ -0,0 +1,17 @@
|
||||
import csharp
|
||||
|
||||
private string printExpr(Expr e) {
|
||||
e = any(IndexExpr index | result = "^" + index.getExpr().toString())
|
||||
or
|
||||
not e instanceof IndexExpr and
|
||||
result = e.toString()
|
||||
}
|
||||
|
||||
query predicate methodArguments(MethodCall mc, string target, int i, string arg) {
|
||||
target = mc.getTarget().toStringWithTypes() and
|
||||
arg = printExpr(mc.getArgument(i))
|
||||
}
|
||||
|
||||
query predicate methodCalls(MethodCall mc, string target) {
|
||||
target = mc.getTarget().toStringWithTypes()
|
||||
}
|
||||
@@ -1,2 +0,0 @@
|
||||
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
|
||||
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
|
||||
|
||||
@@ -7,7 +7,5 @@
|
||||
| Quality.cs:20:13:20:23 | access to property MyProperty6 | Call without target $@. | Quality.cs:20:13:20:23 | access to property MyProperty6 | access to property MyProperty6 |
|
||||
| Quality.cs:23:9:23:14 | access to event Event1 | Call without target $@. | Quality.cs:23:9:23:14 | access to event Event1 | access to event Event1 |
|
||||
| Quality.cs:23:9:23:30 | delegate call | Call without target $@. | Quality.cs:23:9:23:30 | delegate call | delegate call |
|
||||
| Quality.cs:26:19:26:26 | access to indexer | Call without target $@. | Quality.cs:26:19:26:26 | access to indexer | access to indexer |
|
||||
| Quality.cs:29:21:29:27 | access to indexer | Call without target $@. | Quality.cs:29:21:29:27 | access to indexer | access to indexer |
|
||||
| Quality.cs:38:16:38:26 | access to property MyProperty2 | Call without target $@. | Quality.cs:38:16:38:26 | access to property MyProperty2 | access to property MyProperty2 |
|
||||
| Quality.cs:50:20:50:26 | object creation of type T | Call without target $@. | Quality.cs:50:20:50:26 | object creation of type T | object creation of type T |
|
||||
|
||||
@@ -23,10 +23,10 @@ public class Test
|
||||
Event1.Invoke(this, 5);
|
||||
|
||||
var str = "abcd";
|
||||
var sub = str[..3]; // TODO: this is not an indexer call, but rather a `str.Substring(0, 3)` call.
|
||||
var sub = str[..3];
|
||||
|
||||
Span<int> sp = null;
|
||||
var slice = sp[..3]; // TODO: this is not an indexer call, but rather a `sp.Slice(0, 3)` call.
|
||||
var slice = sp[..3];
|
||||
|
||||
Span<byte> guidBytes = stackalloc byte[16];
|
||||
guidBytes[08] = 1;
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true"})
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java, gradle_8_3):
|
||||
def test(codeql, java, gradle_8_3, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java, gradle_8_3):
|
||||
def test(codeql, java, gradle_8_3, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
# gradlew has been rigged to stall for a long time by trying to fetch from a black-hole IP.
|
||||
# We should find the timeout logic fires and buildless aborts the Gradle run quickly.
|
||||
codeql.database.create(
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java, gradle_8_3):
|
||||
def test(codeql, java, gradle_8_3, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -3,7 +3,7 @@ import os
|
||||
import runs_on
|
||||
|
||||
|
||||
def test(codeql, java, cwd):
|
||||
def test(codeql, java, cwd, check_diagnostics_java):
|
||||
# This serves the "repo" directory on https://locahost:4443
|
||||
command = ["python3", "../server.py"]
|
||||
if runs_on.github_actions and runs_on.posix:
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import os.path
|
||||
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(build_mode = "none",
|
||||
_env={
|
||||
"_JAVA_OPTIONS": "-Duser.home=" + os.path.join(os.getcwd(), "home-dir-with-maven-settings")
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import os.path
|
||||
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(build_mode = "none",
|
||||
_env={
|
||||
"_JAVA_OPTIONS": "-Duser.home=" + os.path.join(os.getcwd(), "empty-home"),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
# mvnw has been rigged to stall for a long time by trying to fetch from a black-hole IP. We should find the timeout logic fires and buildless aborts the Maven run quickly.
|
||||
codeql.database.create(
|
||||
build_mode="none",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import os
|
||||
import os.path
|
||||
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(build_mode = "none",
|
||||
_env={
|
||||
"_JAVA_OPTIONS": "-Duser.home=" + os.path.join(os.getcwd(), "empty-home")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java, codeql_mitm_proxy, gradle_8_3):
|
||||
def test(codeql, java, codeql_mitm_proxy, gradle_8_3, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, java, codeql_mitm_proxy):
|
||||
def test(codeql, java, codeql_mitm_proxy, check_diagnostics_java):
|
||||
codeql.database.create(
|
||||
_env={
|
||||
"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true",
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
def test(codeql, use_java_11, java, actions_toolchains_file):
|
||||
def test(codeql, use_java_11, java, actions_toolchains_file, check_diagnostics_java):
|
||||
# The version of gradle used doesn't work on java 17
|
||||
codeql.database.create(
|
||||
_env={
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
def test(codeql, java):
|
||||
def test(codeql, java, check_diagnostics_java):
|
||||
codeql.database.create(_env={"CODEQL_EXTRACTOR_JAVA_OPTION_BUILDLESS": "true"})
|
||||
|
||||
@@ -72,6 +72,35 @@ module FlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
}
|
||||
}
|
||||
|
||||
private class FlowNodeElement extends Element {
|
||||
FlowNodeElement() {
|
||||
this instanceof Field or
|
||||
this instanceof Expr or
|
||||
this instanceof Method
|
||||
}
|
||||
}
|
||||
|
||||
private predicate id(FlowNodeElement x, FlowNodeElement y) { x = y }
|
||||
|
||||
private predicate idOf(FlowNodeElement x, int y) = equivalenceRelation(id/2)(x, y)
|
||||
|
||||
int getFlowNodeId(FlowNode n) {
|
||||
n =
|
||||
rank[result](FlowNode n0, int a, int b |
|
||||
a = 0 and
|
||||
idOf(n0.asField(), b)
|
||||
or
|
||||
// no case for `n0.asSsa()`; here we rely on the built-in location-based ranking
|
||||
a = 1 and
|
||||
idOf(n0.asExpr(), b)
|
||||
or
|
||||
a = 2 and
|
||||
idOf(n0.asMethod(), b)
|
||||
|
|
||||
n0 order by a, b
|
||||
)
|
||||
}
|
||||
|
||||
private SrcCallable viableCallable_v1(Call c) {
|
||||
result = viableImpl_v1(c)
|
||||
or
|
||||
@@ -165,6 +194,8 @@ private module Input implements TypeFlowInput<Location> {
|
||||
|
||||
class TypeFlowNode = FlowNode;
|
||||
|
||||
predicate getTypeFlowNodeId = FlowStepsInput::getFlowNodeId/1;
|
||||
|
||||
predicate isExcludedFromNullAnalysis = FlowStepsInput::isExcludedFromNullAnalysis/1;
|
||||
|
||||
class Type = RefType;
|
||||
|
||||
@@ -170,6 +170,8 @@ private class EmptyCollectionConstructor extends Constructor {
|
||||
private module CollectionFlowStepsInput implements UniversalFlow::UniversalFlowInput<Location> {
|
||||
import FlowStepsInput
|
||||
|
||||
predicate getFlowNodeId = FlowStepsInput::getFlowNodeId/1;
|
||||
|
||||
/**
|
||||
* Holds if `n2` is a collection/array/constant whose value(s) are
|
||||
* determined completely from the range of `n1` nodes.
|
||||
|
||||
@@ -331,7 +331,7 @@ public class B {
|
||||
x = new Object();
|
||||
}
|
||||
if(y instanceof String) {
|
||||
x.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
}
|
||||
}
|
||||
|
||||
@@ -341,7 +341,7 @@ public class B {
|
||||
x = new Object();
|
||||
}
|
||||
if(!(y instanceof String)) {
|
||||
x.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
}
|
||||
}
|
||||
|
||||
@@ -351,7 +351,7 @@ public class B {
|
||||
x = new Object();
|
||||
}
|
||||
if(y == z) {
|
||||
x.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
}
|
||||
|
||||
Object x2 = null;
|
||||
@@ -359,7 +359,7 @@ public class B {
|
||||
x2 = new Object();
|
||||
}
|
||||
if(y != z) {
|
||||
x2.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x2.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
}
|
||||
|
||||
Object x3 = null;
|
||||
@@ -367,7 +367,7 @@ public class B {
|
||||
x3 = new Object();
|
||||
}
|
||||
if(!(y == z)) {
|
||||
x3.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x3.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
}
|
||||
}
|
||||
|
||||
@@ -462,7 +462,7 @@ public class B {
|
||||
cur = a[i];
|
||||
if (!prev) {
|
||||
// correctly guarded by !cur from the _previous_ iteration
|
||||
x.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
} else {
|
||||
x = new Object();
|
||||
}
|
||||
@@ -484,7 +484,7 @@ public class B {
|
||||
t = new Object();
|
||||
}
|
||||
// correctly guarded by t: null -> String -> Object
|
||||
x.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
x.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -573,7 +573,7 @@ public class B {
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
s.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
s.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // Spurious NPE - false positive
|
||||
// CFG reachability does not distinguish abrupt successors
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ public class C {
|
||||
long[][] a2 = null;
|
||||
boolean haveA2 = ix < len && (a2 = a1[ix]) != null;
|
||||
long[] a3 = null;
|
||||
final boolean haveA3 = haveA2 && (a3 = a2[ix]) != null; // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
if (haveA3) a3[0] = 0; // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
final boolean haveA3 = haveA2 && (a3 = a2[ix]) != null; // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
if (haveA3) a3[0] = 0; // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
}
|
||||
|
||||
public void ex2(boolean x, boolean y) {
|
||||
@@ -18,7 +18,7 @@ public class C {
|
||||
s2 = (s1 == null) ? null : "";
|
||||
}
|
||||
if (s2 != null)
|
||||
s1.hashCode(); // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
s1.hashCode(); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
}
|
||||
|
||||
public void ex3(List<String> ss) {
|
||||
@@ -48,7 +48,7 @@ public class C {
|
||||
slice = new ArrayList<>();
|
||||
result.add(slice);
|
||||
}
|
||||
slice.add(str); // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
slice.add(str); // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
++index;
|
||||
iter.remove();
|
||||
}
|
||||
@@ -141,7 +141,7 @@ public class C {
|
||||
public void ex10(int[] a) {
|
||||
int n = a == null ? 0 : a.length;
|
||||
for (int i = 0; i < n; i++) {
|
||||
int x = a[i]; // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
int x = a[i]; // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
if (x > 7)
|
||||
a = new int[n];
|
||||
}
|
||||
@@ -216,7 +216,7 @@ public class C {
|
||||
if (o1 == o2) {
|
||||
return;
|
||||
}
|
||||
if (o1.equals(o2)) { // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
if (o1.equals(o2)) { // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ public class C {
|
||||
public static void ex16(C c) {
|
||||
int[] xs = c.getFoo16() != null ? new int[5] : null;
|
||||
if (c.getFoo16() != null) {
|
||||
xs[0]++; // $ Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
xs[0]++; // $ SPURIOUS: Alert[java/dereferenced-value-may-be-null] // NPE - false positive
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,25 +11,25 @@ class UseBraces
|
||||
{
|
||||
int x = 0, y;
|
||||
int[] branches = new int[10];
|
||||
|
||||
|
||||
// If-then statement
|
||||
|
||||
|
||||
if(1==1)
|
||||
{
|
||||
f();
|
||||
}
|
||||
g(); // No alert
|
||||
|
||||
if(1==1)
|
||||
|
||||
if(1==1)
|
||||
f();
|
||||
g(); // No alert
|
||||
|
||||
|
||||
if(1==1)
|
||||
f(); // $ Alert
|
||||
g(); // Alert
|
||||
|
||||
g();
|
||||
|
||||
if(1==1)
|
||||
f(); g(); // $ Alert // Alert
|
||||
f(); g(); // $ Alert
|
||||
|
||||
// If-then-else statement
|
||||
|
||||
@@ -41,29 +41,29 @@ class UseBraces
|
||||
{
|
||||
g();
|
||||
}
|
||||
|
||||
|
||||
g(); // No alert
|
||||
|
||||
|
||||
if(1==2)
|
||||
f();
|
||||
else
|
||||
g();
|
||||
f(); // No alert
|
||||
|
||||
|
||||
if(true)
|
||||
{
|
||||
f();
|
||||
}
|
||||
else
|
||||
f(); // $ Alert
|
||||
g(); // Alert
|
||||
|
||||
g();
|
||||
|
||||
if(true)
|
||||
{
|
||||
f();
|
||||
}
|
||||
else
|
||||
f(); g(); // $ Alert // Alert
|
||||
f(); g(); // $ Alert
|
||||
|
||||
// While statement
|
||||
|
||||
@@ -80,44 +80,44 @@ class UseBraces
|
||||
|
||||
while(bb )
|
||||
f(); // $ Alert
|
||||
g(); // Alert
|
||||
g();
|
||||
g(); // No alert
|
||||
|
||||
while(bb )
|
||||
f(); g(); // $ Alert // Alert
|
||||
f(); g(); // $ Alert
|
||||
|
||||
|
||||
while(bb)
|
||||
if (x != 0) x = 1;
|
||||
|
||||
// Do-while statement
|
||||
|
||||
|
||||
do
|
||||
f();
|
||||
while(false);
|
||||
g(); // No alert
|
||||
|
||||
|
||||
// For statement
|
||||
for(int i=0; i<10; ++i)
|
||||
{
|
||||
f();
|
||||
}
|
||||
g();
|
||||
|
||||
|
||||
for(int i=0; i<10; ++i)
|
||||
f();
|
||||
g();
|
||||
|
||||
|
||||
for(int i=0; i<10; ++i)
|
||||
f(); // $ Alert
|
||||
g(); // Alert
|
||||
g();
|
||||
|
||||
for(int i=0; i<10; ++i)
|
||||
f(); g(); // $ Alert // Alert
|
||||
f(); g(); // $ Alert
|
||||
|
||||
|
||||
|
||||
// Foreach statement
|
||||
|
||||
|
||||
for( int b : branches)
|
||||
x += b;
|
||||
f();
|
||||
@@ -130,42 +130,42 @@ class UseBraces
|
||||
|
||||
for( int b : branches)
|
||||
f(); // $ Alert
|
||||
g(); // Alert
|
||||
g();
|
||||
|
||||
for( int b : branches)
|
||||
f(); g(); // $ Alert // Alert
|
||||
f(); g(); // $ Alert
|
||||
|
||||
// Nested ifs
|
||||
if( true )
|
||||
if(false)
|
||||
f();
|
||||
g(); // No alert
|
||||
|
||||
|
||||
if( true )
|
||||
if(false) // $ Alert
|
||||
f();
|
||||
g(); // Alert
|
||||
|
||||
g();
|
||||
|
||||
if( true )
|
||||
;
|
||||
else
|
||||
else
|
||||
if (false)
|
||||
f();
|
||||
g(); // No alert
|
||||
|
||||
if( true )
|
||||
;
|
||||
else
|
||||
else
|
||||
if (false)
|
||||
f();
|
||||
g(); // false negative
|
||||
g(); // $ MISSING: Alert // false negative
|
||||
|
||||
if( true )
|
||||
;
|
||||
else if (false)
|
||||
f(); // $ Alert
|
||||
g(); // Alert
|
||||
|
||||
g();
|
||||
|
||||
// Nested combinations
|
||||
if (true)
|
||||
while (x<10)
|
||||
@@ -175,7 +175,7 @@ class UseBraces
|
||||
if (true)
|
||||
while (x<10) // $ Alert
|
||||
f();
|
||||
g(); // Alert
|
||||
g();
|
||||
|
||||
while (x<10)
|
||||
if (true)
|
||||
@@ -185,7 +185,7 @@ class UseBraces
|
||||
while (x<10)
|
||||
if (true) // $ Alert
|
||||
f();
|
||||
g(); // Alert
|
||||
g();
|
||||
|
||||
if (true)
|
||||
f();
|
||||
|
||||
@@ -62,10 +62,10 @@ public class ResponseSplitting extends HttpServlet {
|
||||
response.setHeader("h", t.replace('\n', ' ').replace('\r', ' '));
|
||||
|
||||
// FALSE NEGATIVE: replace only some line breaks
|
||||
response.setHeader("h", t.replace('\n', ' '));
|
||||
response.setHeader("h", t.replace('\n', ' ')); // $ MISSING: Alert
|
||||
|
||||
// FALSE NEGATIVE: replace only some line breaks
|
||||
response.setHeader("h", t.replaceAll("\r", ""));
|
||||
response.setHeader("h", t.replaceAll("\r", "")); // $ MISSING: Alert
|
||||
|
||||
// GOOD: replace all linebreaks with a simple regex
|
||||
response.setHeader("h", t.replaceAll("\n", "").replaceAll("\r", ""));
|
||||
|
||||
@@ -78,7 +78,7 @@ public class ArithmeticTainted {
|
||||
// FALSE NEGATIVE: stillTainted could still be very large, even
|
||||
// after
|
||||
// it has had arithmetic done on it
|
||||
int output = stillTainted + 100;
|
||||
int output = stillTainted + 100; // $ MISSING: Alert[java/tainted-arithmetic]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -107,7 +107,7 @@ public class ArithmeticTainted {
|
||||
}
|
||||
int output = data + 1;
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
double x= Double.MAX_VALUE;
|
||||
// OK: CWE-190 only pertains to integer arithmetic
|
||||
|
||||
@@ -84,7 +84,7 @@ class Test {
|
||||
// FALSE POSITIVE: the query check purely based on the type, it
|
||||
// can't try to
|
||||
// determine whether the value may in fact always be in bounds
|
||||
i += j; // $ Alert[java/implicit-cast-in-compound-assignment]
|
||||
i += j; // $ SPURIOUS: Alert[java/implicit-cast-in-compound-assignment]
|
||||
}
|
||||
|
||||
// ArithmeticWithExtremeValues
|
||||
@@ -224,7 +224,7 @@ class Test {
|
||||
// FALSE NEGATIVE: stillLarge could still be very large, even
|
||||
// after
|
||||
// it has had arithmetic done on it
|
||||
int output = stillLarge + 100;
|
||||
int output = stillLarge + 100; // $ MISSING: Alert[java/uncontrolled-arithmetic]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ class Test {
|
||||
// FALSE NEGATIVE: stillLarge could still be very large, even
|
||||
// after
|
||||
// it has had arithmetic done on it
|
||||
int output = stillLarge + 100;
|
||||
int output = stillLarge + 100; // $ MISSING: Alert[java/uncontrolled-arithmetic]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ interface Hello extends java.rmi.Remote {
|
||||
|
||||
class HelloImpl implements Hello {
|
||||
public static void main(String[] args) {
|
||||
try {
|
||||
try {
|
||||
// HttpsUrls
|
||||
{
|
||||
String protocol = "http://"; // $ Source[java/non-https-url]
|
||||
@@ -31,7 +31,7 @@ class HelloImpl implements Hello {
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String protocol = "http"; // $ Source[java/non-https-url]
|
||||
URL u = new URL(protocol, "www.secret.example.org", "foo");
|
||||
@@ -44,7 +44,7 @@ class HelloImpl implements Hello {
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String protocol = "http://"; // $ Source[java/non-https-url]
|
||||
// the second URL overwrites the first, as it has a protocol
|
||||
@@ -58,7 +58,7 @@ class HelloImpl implements Hello {
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String protocol = "https://";
|
||||
URL u = new URL(protocol + "www.secret.example.org/");
|
||||
@@ -70,7 +70,7 @@ class HelloImpl implements Hello {
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String protocol = "https";
|
||||
URL u = new URL(protocol, "www.secret.example.org", "foo");
|
||||
@@ -82,27 +82,27 @@ class HelloImpl implements Hello {
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String protocol = "http"; // $ Source[java/non-https-url]
|
||||
String protocol = "http"; // $ SPURIOUS: Source[java/non-https-url]
|
||||
URL u = new URL(protocol, "internal-url", "foo");
|
||||
// FALSE POSITIVE: the query has no way of knowing whether the url will
|
||||
// resolve to somewhere outside the internal network, where there
|
||||
// are unlikely to be interception attempts
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection(); // $ Alert[java/non-https-url]
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection(); // $ SPURIOUS: Alert[java/non-https-url]
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
hu.disconnect();
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
String input = "URL is: http://www.secret-example.org";
|
||||
String url = input.substring(8);
|
||||
URL u = new URL(url);
|
||||
// FALSE NEGATIVE: we cannot tell that the substring results in a url
|
||||
// string
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection();
|
||||
HttpsURLConnection hu = (HttpsURLConnection) u.openConnection(); // $ MISSING: Alert[java/non-https-url]
|
||||
hu.setRequestMethod("PUT");
|
||||
hu.connect();
|
||||
OutputStream os = hu.getOutputStream();
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes.
|
||||
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and fewer false positive results after these changes.
|
||||
|
||||
## 7.1.1
|
||||
|
||||
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and less fewer positive results after these changes.
|
||||
* The sensitive data heuristics used to identify code that handles passwords and private data have been improved. Most of the changes permit more variations of established patterns, thereby finding more sensitive data. Queries that use the sensitive data library (for example `py/clear-text-logging-sensitive-data`) may find more correct results and fewer false positive results after these changes.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
string foo() {
|
||||
result = concat(string x | x = [0 .. 10].toString() | x order by x desc, ", ") // BAD
|
||||
result = concat(string x | x = [0 .. 10].toString() | x order by x desc, ", ") // $ Alert // BAD
|
||||
or
|
||||
result = concat(string x | x = [0 .. 10].toString() | x, ", " order by x desc) // GOOD
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/bugs/OrderByConst.ql
|
||||
query: queries/bugs/OrderByConst.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/bugs/SumWithoutDomain.ql
|
||||
query: queries/bugs/SumWithoutDomain.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// Result is 3 and not 4
|
||||
int foo() {
|
||||
result = sum([1, 1, 2]) // <- Alert here
|
||||
result = sum([1, 1, 2]) // $ Alert // <- Alert here
|
||||
}
|
||||
|
||||
// Ok - false negative
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/overlay/InlineOverlayCaller.ql
|
||||
query: queries/overlay/InlineOverlayCaller.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -4,7 +4,7 @@ module;
|
||||
import ql
|
||||
|
||||
pragma[inline]
|
||||
predicate foo(int x) { x = 42 }
|
||||
predicate foo(int x) { x = 42 } // $ Alert
|
||||
|
||||
overlay[caller]
|
||||
pragma[inline]
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/performance/AbstractClassImport.ql
|
||||
query: queries/performance/AbstractClassImport.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import ql
|
||||
import AbstractClassImportTest2
|
||||
|
||||
abstract class Base extends AstNode { }
|
||||
abstract class Base extends AstNode { } // $ Alert
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/performance/MissingNoinline.ql
|
||||
query: queries/performance/MissingNoinline.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -5,7 +5,7 @@ import ql
|
||||
*
|
||||
* This predicate exists to fix a join order.
|
||||
*/
|
||||
predicate missingNoInline(AddExpr add, Expr e1, Expr e2) {
|
||||
predicate missingNoInline(AddExpr add, Expr e1, Expr e2) { // $ Alert
|
||||
// BAD
|
||||
add.getLeftOperand() = e1 and
|
||||
add.getRightOperand() = e2
|
||||
|
||||
@@ -13,21 +13,21 @@ class MyStr extends string {
|
||||
predicate bad1(Big b) {
|
||||
b.toString().matches("%foo")
|
||||
or
|
||||
any()
|
||||
any() // $ Alert
|
||||
}
|
||||
|
||||
int bad2() {
|
||||
exists(Big big, Small small |
|
||||
result = big.toString().toInt()
|
||||
or
|
||||
result = small.toString().toInt()
|
||||
result = small.toString().toInt() // $ Alert
|
||||
)
|
||||
}
|
||||
|
||||
float bad3(Big t) {
|
||||
result = [1 .. 10].toString().toFloat() or
|
||||
result = [11 .. 20].toString().toFloat() or
|
||||
result = t.toString().toFloat() or
|
||||
result = t.toString().toFloat() or // $ Alert
|
||||
result = [21 .. 30].toString().toFloat()
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ predicate bad4(Big fromType, Big toType) {
|
||||
or
|
||||
fromType.toString().matches("%foo")
|
||||
or
|
||||
helper(toType, fromType)
|
||||
helper(toType, fromType) // $ Alert
|
||||
}
|
||||
|
||||
predicate good2(Big t) {
|
||||
@@ -71,7 +71,7 @@ predicate mixed1(Big good, Small small) {
|
||||
small.toString().matches("%foo") and
|
||||
// the use of good is fine, the comparison further up binds it.
|
||||
// the same is not true for bad.
|
||||
(bad.toString().matches("%foo") or good.toString().regexpMatch("foo.*")) and
|
||||
(bad.toString().matches("%foo") or good.toString().regexpMatch("foo.*")) and // $ Alert
|
||||
small.toString().regexpMatch(".*foo")
|
||||
)
|
||||
}
|
||||
@@ -112,7 +112,7 @@ predicate good5(Big bb, Big v, boolean certain) {
|
||||
)
|
||||
}
|
||||
|
||||
predicate bad5(Big bb) { if none() then bb.toString().matches("%foo") else any() }
|
||||
predicate bad5(Big bb) { if none() then bb.toString().matches("%foo") else any() } // $ Alert
|
||||
|
||||
pragma[inline]
|
||||
predicate good5(Big a, Big b) {
|
||||
@@ -126,12 +126,12 @@ predicate bad6(Big a) {
|
||||
(
|
||||
a.toString().matches("%foo") // bad
|
||||
or
|
||||
any()
|
||||
any() // $ Alert
|
||||
) and
|
||||
(
|
||||
a.toString().matches("%foo") // also bad
|
||||
or
|
||||
any()
|
||||
any() // $ Alert
|
||||
)
|
||||
}
|
||||
|
||||
@@ -163,7 +163,7 @@ class HasField extends Big {
|
||||
HasField() {
|
||||
field = this
|
||||
or
|
||||
this.toString().matches("%foo") // <- field only defined here.
|
||||
this.toString().matches("%foo") // $ Alert // <- field only defined here.
|
||||
}
|
||||
|
||||
Big getField() { result = field }
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/performance/VarUnusedInDisjunct.ql
|
||||
query: queries/performance/VarUnusedInDisjunct.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/style/AcronymsShouldBeCamelCase.ql
|
||||
query: queries/style/AcronymsShouldBeCamelCase.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// BAD
|
||||
predicate isXML() { any() }
|
||||
predicate isXML() { any() } // $ Alert
|
||||
|
||||
// GOOD [ AES is exceptional ]
|
||||
predicate isAES() { any() }
|
||||
|
||||
// BAD
|
||||
newtype TXMLElements =
|
||||
newtype TXMLElements = // $ Alert
|
||||
TXmlElement() or // GOOD
|
||||
TXMLElement() // BAD
|
||||
TXMLElement() // $ Alert // BAD
|
||||
|
||||
// GOOD
|
||||
newtype TIRFunction = MkIRFunction()
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/style/CouldBeCast.ql
|
||||
query: queries/style/CouldBeCast.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
bindingset[i]
|
||||
predicate foo(int i) {
|
||||
exists(Even j | j = i) // NOT OK
|
||||
exists(Even j | j = i) // $ Alert // NOT OK
|
||||
or
|
||||
exists(Even j | j = i | j % 4 = 0) // OK
|
||||
or
|
||||
any(Even j | j = i) = 2 // NOT OK
|
||||
any(Even j | j = i) = 2 // $ Alert // NOT OK
|
||||
or
|
||||
any(Even j | j = i | j) = 2 // NOT OK
|
||||
any(Even j | j = i | j) = 2 // $ Alert // NOT OK
|
||||
or
|
||||
any(Even j | j = i | j * 2) = 4 // OK
|
||||
or
|
||||
any(Even j | j = i and j % 4 = 0 | j) = 4 // OK
|
||||
or
|
||||
any(int j | j = i) = 2 // NOT OK
|
||||
any(int j | j = i) = 2 // $ Alert // NOT OK
|
||||
or
|
||||
exists(int j | j = i) // NOT OK
|
||||
exists(int j | j = i) // $ Alert // NOT OK
|
||||
}
|
||||
|
||||
class Even extends int {
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/style/DataFlowConfigModuleNaming.ql
|
||||
query: queries/style/DataFlowConfigModuleNaming.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -8,14 +8,14 @@ module EmptyConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
|
||||
// BAD - does not end with "Config"
|
||||
module EmptyConfiguration implements DataFlow::ConfigSig {
|
||||
module EmptyConfiguration implements DataFlow::ConfigSig { // $ Alert
|
||||
predicate isSource(DataFlow::Node src) { none() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
// BAD - does not end with "Config"
|
||||
module EmptyFlow implements DataFlow::ConfigSig {
|
||||
module EmptyFlow implements DataFlow::ConfigSig { // $ Alert
|
||||
predicate isSource(DataFlow::Node src) { none() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { none() }
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/style/DeadCode.ql
|
||||
query: queries/style/DeadCode.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import ql
|
||||
|
||||
private module Mixed {
|
||||
private predicate dead1() { none() }
|
||||
private predicate dead1() { none() } // $ Alert
|
||||
|
||||
predicate alive1() { none() }
|
||||
|
||||
predicate dead2() { none() }
|
||||
predicate dead2() { none() } // $ Alert
|
||||
}
|
||||
|
||||
predicate usesAlive() { Mixed::alive1() }
|
||||
@@ -43,7 +43,7 @@ private module Input1 implements InputSig {
|
||||
predicate foo() { any() }
|
||||
}
|
||||
|
||||
private module Input2 implements InputSig {
|
||||
private module Input2 implements InputSig { // $ Alert
|
||||
predicate foo() { any() }
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ private module Input3 implements InputSig {
|
||||
|
||||
module M1 = ParameterizedModule<Input1>;
|
||||
|
||||
private module M2 = ParameterizedModule<Input2>;
|
||||
private module M2 = ParameterizedModule<Input2>; // $ Alert
|
||||
|
||||
import ParameterizedModule<Input3>
|
||||
|
||||
@@ -65,7 +65,7 @@ private class CImpl1 extends AstNode { }
|
||||
|
||||
final class CPublic1 = CImpl1;
|
||||
|
||||
private class CImpl2 extends AstNode { }
|
||||
private class CImpl2 extends AstNode { } // $ Alert
|
||||
|
||||
overlay[discard_entity]
|
||||
private predicate discard(@foo x) { any() }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class C1 extends int {
|
||||
int field; // BAD
|
||||
int field; // $ Alert // BAD
|
||||
|
||||
C1() {
|
||||
this = field and
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/style/FieldOnlyUsedInCharPred.ql
|
||||
query: queries/style/FieldOnlyUsedInCharPred.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -7,5 +7,5 @@ class Foo extends string {
|
||||
|
||||
string getBarWithThis() { result = this.getBar() }
|
||||
|
||||
string getBarWithoutThis() { result = getBar() }
|
||||
string getBarWithoutThis() { result = getBar() } // $ Alert
|
||||
}
|
||||
|
||||
@@ -5,5 +5,5 @@ class Foo extends string {
|
||||
|
||||
string getBar() { result = "bar" }
|
||||
|
||||
string getBarWithoutThis() { result = getBar() }
|
||||
string getBarWithoutThis() { result = getBar() } // $ Alert
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
queries/style/ImplicitThis.ql
|
||||
query: queries/style/ImplicitThis.ql
|
||||
postprocess: utils/test/InlineExpectationsTestQuery.ql
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
predicate test1(int param1, int param2, int param3) { none() } // OK
|
||||
|
||||
/** `param1`, `par2` */
|
||||
predicate test2(int param1, int param2) { none() } // NOT OK - `par2` is not a parameter, and `param2` has no documentation
|
||||
predicate test2(int param1, int param2) { none() } // $ Alert // NOT OK - `par2` is not a parameter, and `param2` has no documentation
|
||||
|
||||
/** `param1`, `par2 + par3` */
|
||||
predicate test3(int param1, int par2, int par3) { none() } // OK
|
||||
@@ -11,4 +11,4 @@ predicate test3(int param1, int par2, int par3) { none() } // OK
|
||||
predicate test4(int param1, int param2) { none() } // OK - the QLDoc mentions none of the parameters, that's OK
|
||||
|
||||
/** the param1 parameter is mentioned in a non-code block, but the `par2` parameter is misspelled */
|
||||
predicate test5(int param1, int param2) { none() } // NOT OK - the `param1` parameter is "documented" in clear text, but `par2` is misspelled
|
||||
predicate test5(int param1, int param2) { none() } // $ Alert // NOT OK - the `param1` parameter is "documented" in clear text, but `par2` is misspelled
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user