diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Assignment.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Assignment.cs index f3e2e510cd64..6f6b4609f050 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Assignment.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Assignment.cs @@ -23,15 +23,12 @@ public static Assignment Create(ExpressionNodeInfo info) protected override void PopulateExpression(TextWriter trapFile) { var operatorKind = OperatorKind; + // TODO: THIS CHECK CAN BE SIMPLIFIED - As we now always consider this to be an operator invocation. if (operatorKind.HasValue) { - // Convert assignment such as `a += b` into `a = a + b`. - var simpleAssignExpr = new Expression(new ExpressionInfo(Context, Type, Location, ExprKind.SIMPLE_ASSIGN, this, 2, isCompilerGenerated: true, null)); - Create(Context, Syntax.Left, simpleAssignExpr, 1); - var opexpr = new Expression(new ExpressionInfo(Context, Type, Location, operatorKind.Value, simpleAssignExpr, 0, isCompilerGenerated: true, null)); - Create(Context, Syntax.Left, opexpr, 0, isCompilerGenerated: true); - Create(Context, Syntax.Right, opexpr, 1); - opexpr.OperatorCall(trapFile, Syntax); + Create(Context, Syntax.Left, this, 0); + Create(Context, Syntax.Right, this, 1); + OperatorCall(trapFile, Syntax); } else { diff --git a/csharp/ql/lib/semmle/code/csharp/Assignable.qll b/csharp/ql/lib/semmle/code/csharp/Assignable.qll index 3c7170a6f846..e4cf08282f3c 100644 --- a/csharp/ql/lib/semmle/code/csharp/Assignable.qll +++ b/csharp/ql/lib/semmle/code/csharp/Assignable.qll @@ -78,6 +78,8 @@ class AssignableRead extends AssignableAccess { this.isRefArgument() or this = any(AssignableDefinitions::AddressOfDefinition def).getTargetAccess() + or + this = any(AssignableDefinitions::AssignOperationDefinition def).getTargetAccess() ) and not nameOfChild(_, this) } @@ -271,6 +273,8 @@ module AssignableInternal { def = TAddressOfDefinition(result) or def = TPatternDefinition(result) + or + def = TAssignOperationDefinition(result) } /** A local variable declaration at the top-level of a pattern. */ @@ -286,7 +290,10 @@ module AssignableInternal { private module Cached { cached newtype TAssignableDefinition = - TAssignmentDefinition(Assignment a) { not a.getLValue() instanceof TupleExpr } or + TAssignmentDefinition(Assignment a) { + not a.getLValue() instanceof TupleExpr and + not a instanceof AssignOperation + } or TTupleAssignmentDefinition(AssignExpr ae, Expr leaf) { tupleAssignmentDefinition(ae, leaf) } or TOutRefDefinition(AssignableAccess aa) { aa.isOutArgument() @@ -309,7 +316,8 @@ module AssignableInternal { ) } or TAddressOfDefinition(AddressOfExpr aoe) or - TPatternDefinition(TopLevelPatternDecl tlpd) + TPatternDefinition(TopLevelPatternDecl tlpd) or + TAssignOperationDefinition(AssignOperation ao) /** * Gets the source expression assigned in tuple definition `def`, if any. @@ -355,6 +363,8 @@ module AssignableInternal { def = TMutationDefinition(any(MutatorOperation mo | mo.getOperand() = result)) or def = TAddressOfDefinition(any(AddressOfExpr aoe | aoe.getOperand() = result)) + or + def = TAssignOperationDefinition(any(AssignOperation ao | ao.getLeftOperand() = result)) } /** @@ -369,7 +379,7 @@ module AssignableInternal { or exists(Assignment ass | ac = ass.getLValue() | result = ass.getRValue() and - not ass.(AssignOperation).hasExpandedAssignment() + not ass instanceof AssignOperation ) } } @@ -388,8 +398,9 @@ private import AssignableInternal * a mutation update (`AssignableDefinitions::MutationDefinition`), a local variable * declaration without an initializer (`AssignableDefinitions::LocalVariableDefinition`), * an implicit parameter definition (`AssignableDefinitions::ImplicitParameterDefinition`), - * an address-of definition (`AssignableDefinitions::AddressOfDefinition`), or a pattern - * definition (`AssignableDefinitions::PatternDefinition`). + * an address-of definition (`AssignableDefinitions::AddressOfDefinition`), a pattern + * definition (`AssignableDefinitions::PatternDefinition`), or a compound assignment + * operation definition (`AssignableDefinitions::AssignOperationDefinition`) */ class AssignableDefinition extends TAssignableDefinition { /** @@ -511,7 +522,7 @@ module AssignableDefinitions { override Expr getSource() { result = a.getRValue() and - not a instanceof AssignOperation + not a instanceof AddOrRemoveEventExpr } override string toString() { result = a.toString() } @@ -735,4 +746,17 @@ module AssignableDefinitions { /** Gets the assignable (field or property) being initialized. */ Assignable getAssignable() { result = fieldOrProp } } + + /** + * A definition by a compound assignment operation, for example `x += y`. + */ + class AssignOperationDefinition extends AssignableDefinition, TAssignOperationDefinition { + AssignOperation ao; + + AssignOperationDefinition() { this = TAssignOperationDefinition(ao) } + + override Expr getSource() { result = ao } + + override string toString() { result = ao.toString() } + } } diff --git a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll index aa834ef91038..3ce937316a84 100644 --- a/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll +++ b/csharp/ql/lib/semmle/code/csharp/ExprOrStmtParent.qll @@ -20,7 +20,7 @@ class ExprOrStmtParent extends Element, @exprorstmt_parent { /** Gets the `i`th child expression of this element (zero-based). */ final Expr getChildExpr(int i) { - expr_parent_adjusted(result, i, this) or + expr_parent(result, i, this) or expr_parent_top_level_adjusted(result, i, this) } @@ -119,66 +119,14 @@ private module Cached { } /** - * The `expr_parent()` relation adjusted for expandable assignments. For example, - * the assignment `x += y` is extracted as - * - * ``` - * += - * | - * 2 - * | - * = - * / \ - * 1 0 - * / \ - * x + - * / \ - * 1 0 - * / \ - * x y - * ``` - * - * in order to be able to retrieve the expanded assignment `x = x + y` as the 2nd - * child. This predicate changes the diagram above into - * - * ``` - * += - * / \ - * 1 0 - * / \ - * x y - * ``` + * Use `expr_parent` instead. */ cached - predicate expr_parent_adjusted(Expr child, int i, ControlFlowElement parent) { - if parent instanceof AssignOperation - then - parent = - any(AssignOperation ao | - exists(AssignExpr ae | ae = ao.getExpandedAssignment() | - i = 0 and - exists(Expr right | - // right = `x + y` - expr_parent(right, 0, ae) - | - expr_parent(child, 1, right) - ) - or - i = 1 and - expr_parent(child, 1, ae) - ) - or - not ao.hasExpandedAssignment() and - expr_parent(child, i, parent) - ) - else expr_parent(child, i, parent) - } + deprecated predicate expr_parent_adjusted(Expr child, int i, ControlFlowElement parent) { none() } private Expr getAChildExpr(ExprOrStmtParent parent) { result = parent.getAChildExpr() and not result = parent.(DeclarationWithGetSetAccessors).getExpressionBody() - or - result = parent.(AssignOperation).getExpandedAssignment() } private ControlFlowElement getAChild(ExprOrStmtParent parent) { diff --git a/csharp/ql/lib/semmle/code/csharp/commons/Strings.qll b/csharp/ql/lib/semmle/code/csharp/commons/Strings.qll index bdf9e5585394..f2d39f9dcc7c 100644 --- a/csharp/ql/lib/semmle/code/csharp/commons/Strings.qll +++ b/csharp/ql/lib/semmle/code/csharp/commons/Strings.qll @@ -49,6 +49,16 @@ class ImplicitToStringExpr extends Expr { this = add.getOtherOperand(o).stripImplicit() ) or + // s1 += s2 for where the left hand side is a string, call an operator +(string, object) + exists(AssignAddExpr add, Operator o, Parameter p0, Parameter p1 | + o = add.getTarget() and + o.getName() = "+" and + p0 = o.getParameter(0) and + p1 = o.getParameter(1) and + p0.getType() instanceof StringType and + this = getAnAssignedArgumentOrParam(p1).stripImplicit() + ) + or this = any(InterpolatedStringExpr ise).getAnInsert().stripImplicit() } } diff --git a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll index 1696869e5911..ea3007e3a839 100644 --- a/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll +++ b/csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImpl.qll @@ -89,18 +89,13 @@ class CfgScope extends Element, @top_level_exprorstmt_parent { private class TAstNode = @callable or @control_flow_element; -private Element getAChild(Element p) { - result = p.getAChild() or - result = p.(AssignOperation).getExpandedAssignment() -} - pragma[nomagic] private predicate astNode(Element e) { e = any(@top_level_exprorstmt_parent p | not p instanceof Attribute) or exists(Element parent | astNode(parent) and - e = getAChild(parent) + e = parent.getAChild() ) } @@ -486,6 +481,7 @@ module Expressions { result = qe.getChild(i) ) or + // TODO: This can be fixed if the extracted indexes are fixed. e = any(Assignment a | // The left-hand side of an assignment is evaluated before the right-hand side @@ -520,7 +516,6 @@ module Expressions { not this instanceof LogicalOrExpr and not this instanceof NullCoalescingExpr and not this instanceof ConditionalExpr and - not this instanceof AssignOperationWithExpandedAssignment and not this instanceof ConditionallyQualifiedExpr and not this instanceof ThrowExpr and not this instanceof ObjectCreation and @@ -618,7 +613,7 @@ module Expressions { def.getExpr() = this and def.getTargetAccess().(WriteAccess) instanceof QualifiableExpr and not def instanceof AssignableDefinitions::OutRefDefinition and - not this instanceof AssignOperationWithExpandedAssignment + not def instanceof AssignableDefinitions::AssignOperationDefinition } /** @@ -801,26 +796,6 @@ module Expressions { } } - /** - * An assignment operation that has an expanded version. We use the expanded - * version in the control flow graph in order to get better data flow / taint - * tracking. - */ - private class AssignOperationWithExpandedAssignment extends ControlFlowTree instanceof AssignOperation - { - private Expr expanded; - - AssignOperationWithExpandedAssignment() { expanded = this.getExpandedAssignment() } - - final override predicate first(AstNode first) { first(expanded, first) } - - final override predicate last(AstNode last, Completion c) { last(expanded, last, c) } - - final override predicate propagatesAbnormal(AstNode child) { none() } - - final override predicate succ(AstNode pred, AstNode succ, Completion c) { none() } - } - /** A conditionally qualified expression. */ private class ConditionallyQualifiedExpr extends PostOrderTree instanceof QualifiableExpr { private Expr qualifier; @@ -1578,7 +1553,7 @@ module Statements { /** Gets a child of `cfe` that is in CFG scope `scope`. */ pragma[noinline] private ControlFlowElement getAChildInScope(AstNode cfe, Callable scope) { - result = getAChild(cfe) and + result = cfe.getAChild() and scope = result.getEnclosingCallable() } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll index 70161a6fc477..b5be9582c6b6 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowPrivate.qll @@ -1579,6 +1579,19 @@ private module ArgumentNodes { scope = def.getExpr() ) else scope = e2 + or + e1.(Argument).isArgumentOf(e2, _) and + ( + e2 instanceof DynamicMemberAccess or + e2 instanceof DynamicElementAccess + ) and + exists(AssignableDefinitions::AssignOperationDefinition def | + def.getTargetAccess() = e2 and + def.getExpr() = e1 + ) and + exactScope = false and + isSuccessor = false and + scope = e1 } } diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll index bb08c8f7e2ca..3f0090d4791c 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/TaintTrackingPrivate.qll @@ -60,6 +60,9 @@ private class LocalTaintExprStepConfiguration extends ControlFlowReachabilityCon e1 = e2.(AddExpr).getAnOperand() and scope = e2 or + e1 = e2.(AssignAddExpr).getAnOperand() and + scope = e2 + or // A comparison expression where taint can flow from one of the // operands if the other operand is a constant value. exists(ComparisonTest ct, Expr other | diff --git a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll index 71d177a48bb1..edfd7914088b 100644 --- a/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll +++ b/csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/RangeUtils.qll @@ -33,7 +33,9 @@ private module Impl { /** Holds if SSA definition `def` equals `e + delta`. */ predicate ssaUpdateStep(ExplicitDefinition def, ExprNode e, int delta) { exists(ControlFlow::Node cfn | cfn = def.getControlFlowNode() | - e = cfn.(ExprNode::Assignment).getRValue() and delta = 0 + e = cfn.(ExprNode::Assignment).getRValue() and + delta = 0 and + not cfn instanceof ExprNode::AssignOperation or e = cfn.(ExprNode::PostIncrExpr).getOperand() and delta = 1 or @@ -66,6 +68,12 @@ private module Impl { x.getIntValue() = delta ) or + exists(ConstantIntegerExpr x | + e2.(ExprNode::AssignAddExpr).getLeftOperand() = e1 and + e2.(ExprNode::AssignAddExpr).getRightOperand() = x and + x.getIntValue() = delta + ) + or exists(ConstantIntegerExpr x | e2.(ExprNode::SubExpr).getLeftOperand() = e1 and e2.(ExprNode::SubExpr).getRightOperand() = x and @@ -230,6 +238,11 @@ module ExprNode { override CS::AssignExpr e; } + /** A compound assignment operation. */ + class AssignOperation extends Assignment, BinaryOperation { + override CS::AssignOperation e; + } + /** A unary operation. */ class UnaryOperation extends ExprNode { override CS::UnaryOperation e; @@ -327,6 +340,12 @@ module ExprNode { override TAddOp getOp() { any() } } + class AssignAddExpr extends AssignOperation { + override CS::AssignAddExpr e; + + override TAddOp getOp() { any() } + } + /** A subtraction operation. */ class SubExpr extends BinaryOperation { override CS::SubExpr e; diff --git a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll index a83967441d74..f7f6c7a50be4 100644 --- a/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/lib/semmle/code/csharp/dispatch/Dispatch.qll @@ -202,11 +202,9 @@ private module Internal { private predicate isPotentialEventCall( AssignArithmeticOperation aao, DynamicMemberAccess dma, string name ) { - exists(DynamicOperatorCall doc, AssignExpr ae | - ae = aao.getExpandedAssignment() and - dma = ae.getLValue() and - doc = ae.getRValue() - | + aao instanceof DynamicOperatorCall and + dma = aao.getLeftOperand() and + ( aao instanceof AssignAddExpr and name = "add_" + dma.getLateBoundTargetName() or diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll index 9fa2a93724d4..3cce72515d45 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Assignment.qll @@ -64,33 +64,31 @@ class AssignExpr extends Assignment, @simple_assign_expr { /** * An assignment operation. Either an arithmetic assignment operation - * (`AssignArithmeticOperation`), a bitwise assignment operation - * (`AssignBitwiseOperation`), or an event assignment (`AddOrRemoveEventExpr`). + * (`AssignArithmeticOperation`), a bitwise assignment operation or + * (`AssignBitwiseOperation`). */ -class AssignOperation extends Assignment, @assign_op_expr { +class AssignOperation extends Assignment, OperatorCall, @assign_op_expr { override string getOperator() { none() } /** - * Gets the expanded version of this assignment operation, if any. - * - * For example, if this assignment operation is `x += y` then - * the expanded assignment is `x = x + y`. - * - * If an expanded version exists, then it is used in the control - * flow graph. + * Expanded versions of compound assignments are no longer extracted. */ - AssignExpr getExpandedAssignment() { expr_parent(result, 2, this) } + deprecated AssignExpr getExpandedAssignment() { none() } /** - * Holds if this assignment operation has an expanded version. - * - * For example, if this assignment operation is `x += y` then - * it has the expanded version `x = x + y`. - * - * If an expanded version exists, then it is used in the control - * flow graph. + * Expanded versions of compound assignments are no longer extracted. */ - predicate hasExpandedAssignment() { exists(this.getExpandedAssignment()) } + deprecated predicate hasExpandedAssignment() { none() } + + override Expr getLeftOperand() { result = this.getChild(0) } + + override Expr getRightOperand() { result = this.getChild(1) } + + /** Gets the left operand of this assignment. */ + override Expr getLValue() { result = this.getChild(0) } + + /** Gets the right operand of this assignment. */ + override Expr getRValue() { result = this.getChild(1) } override string toString() { result = "... " + this.getOperator() + " ..." } } @@ -218,13 +216,21 @@ class AssignUnsighedRightShiftExpr extends AssignBitwiseOperation, @assign_urshi * An event assignment. Either an event addition (`AddEventExpr`) or an event * removal (`RemoveEventExpr`). */ -class AddOrRemoveEventExpr extends AssignOperation, @assign_event_expr { +class AddOrRemoveEventExpr extends Assignment, @assign_event_expr { + override string getOperator() { none() } + /** Gets the event targeted by this event assignment. */ Event getTarget() { result = this.getLValue().getTarget() } override EventAccess getLValue() { result = this.getChild(1) } override Expr getRValue() { result = this.getChild(0) } + + override EventAccess getLeftOperand() { result = this.getChild(1) } + + override Expr getRightOperand() { result = this.getChild(0) } + + override string toString() { result = "... " + this.getOperator() + " ..." } } /** diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll index f8b51a990ed1..912cb23e06b7 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Call.qll @@ -493,12 +493,16 @@ class ConstructorInitializer extends Call, @constructor_init_expr { * } * ``` */ -class OperatorCall extends Call, LateBindableExpr, @operator_invocation_expr { +class OperatorCall extends Call, LateBindableExpr, @op_invoke_expr { override Operator getTarget() { expr_call(this, result) } override Operator getARuntimeTarget() { result = Call.super.getARuntimeTarget() } - override string toString() { result = "call to operator " + this.getTarget().getName() } + override string toString() { + if this instanceof DynamicOperatorCall + then result = "dynamic call to operator " + this.getLateBoundTargetName() + else result = "call to operator " + this.getTarget().getName() + } override string getAPrimaryQlClass() { result = "OperatorCall" } } diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll index 04ea9f062a50..bfc5c36ff37c 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Dynamic.qll @@ -96,13 +96,7 @@ class DynamicMethodCall extends DynamicExpr, MethodCall { * Unlike an ordinary call to a user-defined operator (`OperatorCall`), the * target operator may not be known at compile-time (as in the example above). */ -class DynamicOperatorCall extends DynamicExpr, OperatorCall { - override string toString() { - result = "dynamic call to operator " + this.getLateBoundTargetName() - } - - override string getAPrimaryQlClass() { result = "DynamicOperatorCall" } -} +class DynamicOperatorCall extends DynamicExpr, OperatorCall { } /** * A call to a user-defined mutator operator where the operand is a `dynamic` diff --git a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll index c3b9bcc363b3..7b5176278ce4 100644 --- a/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/lib/semmle/code/csharp/exprs/Expr.qll @@ -65,25 +65,11 @@ class Expr extends ControlFlowElement, @expr { /** Gets the enclosing callable of this expression, if any. */ override Callable getEnclosingCallable() { enclosingCallable(this, result) } - pragma[nomagic] - private predicate isExpandedAssignmentRValueDescendant() { - this = - any(AssignOperation op).getExpandedAssignment().getRValue().getChildExpr(0).getAChildExpr() - or - exists(Expr parent | - parent.isExpandedAssignmentRValueDescendant() and - this = parent.getAChildExpr() - ) - } - /** * Holds if this expression is generated by the compiler and does not appear * explicitly in the source code. */ - final predicate isImplicit() { - compiler_generated(this) or - this.isExpandedAssignmentRValueDescendant() - } + final predicate isImplicit() { compiler_generated(this) } /** * Gets an expression that is the result of stripping (recursively) all diff --git a/csharp/ql/lib/semmlecode.csharp.dbscheme b/csharp/ql/lib/semmlecode.csharp.dbscheme index e73ca2c93df8..eadfb04c00fc 100644 --- a/csharp/ql/lib/semmlecode.csharp.dbscheme +++ b/csharp/ql/lib/semmlecode.csharp.dbscheme @@ -1215,8 +1215,8 @@ case @expr.kind of @literal_expr = @bool_literal_expr | @char_literal_expr | @integer_literal_expr | @real_literal_expr | @string_literal_expr | @null_literal_expr; -@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr; -@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_event_expr | @assign_coalesce_expr; +@assign_expr = @simple_assign_expr | @assign_op_expr | @local_var_decl_expr | @assign_event_expr; +@assign_op_expr = @assign_arith_expr | @assign_bitwise_expr | @assign_coalesce_expr; @assign_event_expr = @add_event_expr | @remove_event_expr; @assign_arith_expr = @assign_add_expr | @assign_sub_expr | @assign_mul_expr | @assign_div_expr @@ -1270,14 +1270,15 @@ case @expr.kind of @anonymous_function_expr = @lambda_expr | @anonymous_method_expr; -@call = @method_invocation_expr | @constructor_init_expr | @operator_invocation_expr +@op_invoke_expr = @operator_invocation_expr | @assign_op_expr +@call = @method_invocation_expr | @constructor_init_expr | @op_invoke_expr | @delegate_invocation_expr | @object_creation_expr | @call_access_expr | @local_function_invocation_expr | @function_pointer_invocation_expr; @call_access_expr = @property_access_expr | @event_access_expr | @indexer_access_expr; @late_bindable_expr = @dynamic_element_access_expr | @dynamic_member_access_expr - | @object_creation_expr | @method_invocation_expr | @operator_invocation_expr; + | @object_creation_expr | @method_invocation_expr | @op_invoke_expr; @throw_element = @throw_expr | @throw_stmt; diff --git a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql index 0f6e6d11fb2c..59816a18b3fb 100644 --- a/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql +++ b/csharp/ql/src/Dead Code/DeadStoreOfLocal.ql @@ -84,6 +84,8 @@ class RelevantDefinition extends AssignableDefinition { ) or this instanceof AssignableDefinitions::PatternDefinition + or + this instanceof AssignableDefinitions::AssignOperationDefinition } /** Holds if this assignment may be live. */ diff --git a/csharp/ql/src/Likely Bugs/DangerousNonShortCircuitLogic.ql b/csharp/ql/src/Likely Bugs/DangerousNonShortCircuitLogic.ql index b980bfba1aea..53bf2599a551 100644 --- a/csharp/ql/src/Likely Bugs/DangerousNonShortCircuitLogic.ql +++ b/csharp/ql/src/Likely Bugs/DangerousNonShortCircuitLogic.ql @@ -18,14 +18,9 @@ import csharp /** A use of `&` or `|` on operands of type boolean. */ class NonShortCircuit extends BinaryBitwiseOperation { NonShortCircuit() { - ( - this instanceof BitwiseAndExpr - or - this instanceof BitwiseOrExpr - ) and - not exists(AssignBitwiseOperation abo | abo.getExpandedAssignment().getRValue() = this) and - this.getLeftOperand().getType() instanceof BoolType and - this.getRightOperand().getType() instanceof BoolType + this instanceof BitwiseAndExpr + or + this instanceof BitwiseOrExpr } pragma[nomagic] diff --git a/csharp/ql/src/Performance/StringConcatenationInLoop.ql b/csharp/ql/src/Performance/StringConcatenationInLoop.ql index a015771610d5..3b3228588a4b 100644 --- a/csharp/ql/src/Performance/StringConcatenationInLoop.ql +++ b/csharp/ql/src/Performance/StringConcatenationInLoop.ql @@ -23,7 +23,6 @@ class StringCat extends AddExpr { * where `v` is a simple variable (and not, for example, a property). */ predicate isSelfConcatAssignExpr(AssignExpr e, Variable v) { - not e = any(AssignAddExpr a).getExpandedAssignment() and exists(VariableAccess use | stringCatContains(e.getRValue(), use) and use.getTarget() = e.getTargetVariable() and diff --git a/csharp/ql/src/Security Features/InsecureRandomness.ql b/csharp/ql/src/Security Features/InsecureRandomness.ql index 2c2df7010c67..8237afdff130 100644 --- a/csharp/ql/src/Security Features/InsecureRandomness.ql +++ b/csharp/ql/src/Security Features/InsecureRandomness.ql @@ -89,11 +89,7 @@ module Random { e = any(SensitiveLibraryParameter v).getAnAssignedArgument() or // Assignment operation, e.g. += or similar - exists(AssignOperation ao | - ao.getRValue() = e and - // "expanded" assignments will be covered by simple assignment - not ao.hasExpandedAssignment() - | + exists(AssignOperation ao | ao.getRValue() = e | ao.getLValue() = any(SensitiveVariable v).getAnAccess() or ao.getLValue() = any(SensitiveProperty v).getAnAccess() or ao.getLValue() = any(SensitiveLibraryParameter v).getAnAccess() diff --git a/csharp/ql/test/library-tests/assignments/AssignOperation.expected b/csharp/ql/test/library-tests/assignments/AssignOperation.expected index f6f03fd050c6..0315bbe1c906 100644 --- a/csharp/ql/test/library-tests/assignments/AssignOperation.expected +++ b/csharp/ql/test/library-tests/assignments/AssignOperation.expected @@ -1,4 +1,3 @@ | Assignments.cs:6:9:6:14 | ... += ... | Assignments.cs:6:9:6:9 | access to local variable x | Assignments.cs:6:14:6:14 | 1 | | Assignments.cs:9:9:9:14 | ... -= ... | Assignments.cs:9:9:9:9 | access to local variable d | Assignments.cs:9:14:9:14 | 2 | | Assignments.cs:12:9:12:17 | ... += ... | Assignments.cs:12:9:12:9 | access to local variable a | Assignments.cs:12:14:12:17 | this access | -| Assignments.cs:14:9:14:35 | ... += ... | Assignments.cs:14:9:14:13 | access to event Event | Assignments.cs:14:18:14:35 | (...) => ... | diff --git a/csharp/ql/test/library-tests/assignments/AssignOperationExpanded.expected b/csharp/ql/test/library-tests/assignments/AssignOperationExpanded.expected deleted file mode 100644 index bcc9d11c42f5..000000000000 --- a/csharp/ql/test/library-tests/assignments/AssignOperationExpanded.expected +++ /dev/null @@ -1,3 +0,0 @@ -| Assignments.cs:6:9:6:14 | ... += ... | Assignments.cs:6:9:6:14 | ... = ... | Assignments.cs:6:9:6:9 | access to local variable x | Assignments.cs:6:9:6:14 | ... + ... | Assignments.cs:6:9:6:9 | access to local variable x | Assignments.cs:6:14:6:14 | 1 | -| Assignments.cs:9:9:9:14 | ... -= ... | Assignments.cs:9:9:9:14 | ... = ... | Assignments.cs:9:9:9:9 | access to local variable d | Assignments.cs:9:9:9:14 | dynamic call to operator - | Assignments.cs:9:9:9:9 | access to local variable d | Assignments.cs:9:14:9:14 | 2 | -| Assignments.cs:12:9:12:17 | ... += ... | Assignments.cs:12:9:12:17 | ... = ... | Assignments.cs:12:9:12:9 | access to local variable a | Assignments.cs:12:9:12:17 | call to operator + | Assignments.cs:12:9:12:9 | access to local variable a | Assignments.cs:12:14:12:17 | this access | diff --git a/csharp/ql/test/library-tests/assignments/AssignOperationExpanded.ql b/csharp/ql/test/library-tests/assignments/AssignOperationExpanded.ql deleted file mode 100644 index bd67776520fb..000000000000 --- a/csharp/ql/test/library-tests/assignments/AssignOperationExpanded.ql +++ /dev/null @@ -1,22 +0,0 @@ -import csharp - -predicate getExpandedOperatorArgs(Expr e, Expr left, Expr right) { - e = - any(BinaryArithmeticOperation bo | - bo.getLeftOperand() = left and - bo.getRightOperand() = right - ) - or - e = - any(OperatorCall oc | - oc.getArgument(0) = left and - oc.getArgument(1) = right - ) -} - -from AssignOperation ao, AssignExpr ae, Expr op, Expr left, Expr right -where - ae = ao.getExpandedAssignment() and - op = ae.getRValue() and - getExpandedOperatorArgs(op, left, right) -select ao, ae, ae.getLValue(), op, left, right diff --git a/csharp/ql/test/library-tests/csharp11/operators.expected b/csharp/ql/test/library-tests/csharp11/operators.expected index 2c7bda6800d2..6bce5dfa6f5e 100644 --- a/csharp/ql/test/library-tests/csharp11/operators.expected +++ b/csharp/ql/test/library-tests/csharp11/operators.expected @@ -1,7 +1,6 @@ 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 | >>> | UnsignedRightShiftExpr | 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 | >>>= | AssignUnsighedRightShiftExpr | userdefined diff --git a/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.expected b/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.expected index d388d2fdb7c2..1b4f30ad6e75 100644 --- a/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.expected +++ b/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.expected @@ -1,5 +1,4 @@ nullcoalescing -| NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... | | NullableRefTypes.cs:94:17:94:25 | ... ?? ... | assignments -| NullCoalescingAssignment.cs:8:9:8:18 | ... ??= ... | NullCoalescingAssignment.cs:8:9:8:18 | ... = ... | +| NullCoalescingAssignment.cs:8:9:8:18 | ... ??= ... | diff --git a/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.ql b/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.ql index a3a8ca20e927..1a452274677c 100644 --- a/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.ql +++ b/csharp/ql/test/library-tests/csharp8/NullCoalescingAssignment.ql @@ -2,6 +2,4 @@ import csharp query predicate nullcoalescing(NullCoalescingExpr expr) { any() } -query predicate assignments(AssignCoalesceExpr expr, Expr expanded) { - expanded = expr.getExpandedAssignment() -} +query predicate assignments(AssignCoalesceExpr expr) { any() } diff --git a/csharp/ql/test/library-tests/csharp8/NullCoalescingControlFlow.expected b/csharp/ql/test/library-tests/csharp8/NullCoalescingControlFlow.expected index 2657c450d681..463002be5414 100644 --- a/csharp/ql/test/library-tests/csharp8/NullCoalescingControlFlow.expected +++ b/csharp/ql/test/library-tests/csharp8/NullCoalescingControlFlow.expected @@ -4,9 +4,7 @@ | NullCoalescingAssignment.cs:7:9:7:24 | ... ...; | NullCoalescingAssignment.cs:7:20:7:23 | null | semmle.label | successor | | NullCoalescingAssignment.cs:7:16:7:23 | Object o = ... | NullCoalescingAssignment.cs:8:9:8:19 | ...; | semmle.label | successor | | NullCoalescingAssignment.cs:7:20:7:23 | null | NullCoalescingAssignment.cs:7:16:7:23 | Object o = ... | semmle.label | successor | -| NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... | semmle.label | non-null | -| NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | NullCoalescingAssignment.cs:8:15:8:18 | this access | semmle.label | null | -| NullCoalescingAssignment.cs:8:9:8:18 | ... = ... | NullCoalescingAssignment.cs:5:10:5:23 | exit NullCoalescing (normal) | semmle.label | successor | -| NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... | NullCoalescingAssignment.cs:8:9:8:18 | ... = ... | semmle.label | successor | +| NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | NullCoalescingAssignment.cs:8:15:8:18 | this access | semmle.label | successor | +| NullCoalescingAssignment.cs:8:9:8:18 | ... ??= ... | NullCoalescingAssignment.cs:5:10:5:23 | exit NullCoalescing (normal) | semmle.label | successor | | NullCoalescingAssignment.cs:8:9:8:19 | ...; | NullCoalescingAssignment.cs:8:9:8:9 | access to local variable o | semmle.label | successor | -| NullCoalescingAssignment.cs:8:15:8:18 | this access | NullCoalescingAssignment.cs:8:9:8:18 | ... ?? ... | semmle.label | successor | +| NullCoalescingAssignment.cs:8:15:8:18 | this access | NullCoalescingAssignment.cs:8:9:8:18 | ... ??= ... | semmle.label | successor | diff --git a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected index 861e4c519a82..29533a67083f 100644 --- a/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/DataFlowStep.expected @@ -32,13 +32,14 @@ | LocalDataFlow.cs:59:13:59:25 | SSA def(sink1) | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | | LocalDataFlow.cs:59:21:59:25 | "abc" | LocalDataFlow.cs:59:13:59:17 | access to local variable sink1 | | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | LocalDataFlow.cs:60:9:60:22 | SSA def(sink1) | -| LocalDataFlow.cs:60:9:60:22 | ... + ... | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | +| LocalDataFlow.cs:60:9:60:22 | ... += ... | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | | LocalDataFlow.cs:60:9:60:22 | SSA def(sink1) | LocalDataFlow.cs:61:15:61:19 | access to local variable sink1 | +| LocalDataFlow.cs:60:18:60:22 | [post] access to local variable sink0 | LocalDataFlow.cs:168:20:168:24 | access to local variable sink0 | | LocalDataFlow.cs:60:18:60:22 | access to local variable sink0 | LocalDataFlow.cs:168:20:168:24 | access to local variable sink0 | | LocalDataFlow.cs:61:15:61:19 | [post] access to local variable sink1 | LocalDataFlow.cs:68:21:68:25 | access to local variable sink1 | | LocalDataFlow.cs:61:15:61:19 | access to local variable sink1 | LocalDataFlow.cs:68:21:68:25 | access to local variable sink1 | | LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | LocalDataFlow.cs:64:9:64:25 | SSA def(nonSink0) | -| LocalDataFlow.cs:64:9:64:25 | ... + ... | LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | +| LocalDataFlow.cs:64:9:64:25 | ... += ... | LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | | LocalDataFlow.cs:64:9:64:25 | SSA def(nonSink0) | LocalDataFlow.cs:65:15:65:22 | access to local variable nonSink0 | | LocalDataFlow.cs:65:15:65:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:72:20:72:27 | access to local variable nonSink0 | | LocalDataFlow.cs:65:15:65:22 | access to local variable nonSink0 | LocalDataFlow.cs:72:20:72:27 | access to local variable nonSink0 | diff --git a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected index 0950638d8306..4be5dcf12952 100644 --- a/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected +++ b/csharp/ql/test/library-tests/dataflow/local/TaintTrackingStep.expected @@ -31,19 +31,20 @@ | LocalDataFlow.cs:59:13:59:17 | access to local variable sink1 | LocalDataFlow.cs:59:13:59:25 | SSA def(sink1) | | LocalDataFlow.cs:59:13:59:25 | SSA def(sink1) | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | | LocalDataFlow.cs:59:21:59:25 | "abc" | LocalDataFlow.cs:59:13:59:17 | access to local variable sink1 | -| LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | LocalDataFlow.cs:60:9:60:22 | ... + ... | +| LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | LocalDataFlow.cs:60:9:60:22 | ... += ... | | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | LocalDataFlow.cs:60:9:60:22 | SSA def(sink1) | -| LocalDataFlow.cs:60:9:60:22 | ... + ... | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | +| LocalDataFlow.cs:60:9:60:22 | ... += ... | LocalDataFlow.cs:60:9:60:13 | access to local variable sink1 | | LocalDataFlow.cs:60:9:60:22 | SSA def(sink1) | LocalDataFlow.cs:61:15:61:19 | access to local variable sink1 | -| LocalDataFlow.cs:60:18:60:22 | access to local variable sink0 | LocalDataFlow.cs:60:9:60:22 | ... + ... | +| LocalDataFlow.cs:60:18:60:22 | [post] access to local variable sink0 | LocalDataFlow.cs:168:20:168:24 | access to local variable sink0 | +| LocalDataFlow.cs:60:18:60:22 | access to local variable sink0 | LocalDataFlow.cs:60:9:60:22 | ... += ... | | LocalDataFlow.cs:60:18:60:22 | access to local variable sink0 | LocalDataFlow.cs:168:20:168:24 | access to local variable sink0 | | LocalDataFlow.cs:61:15:61:19 | [post] access to local variable sink1 | LocalDataFlow.cs:68:21:68:25 | access to local variable sink1 | | LocalDataFlow.cs:61:15:61:19 | access to local variable sink1 | LocalDataFlow.cs:68:21:68:25 | access to local variable sink1 | -| LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | LocalDataFlow.cs:64:9:64:25 | ... + ... | +| LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | LocalDataFlow.cs:64:9:64:25 | ... += ... | | LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | LocalDataFlow.cs:64:9:64:25 | SSA def(nonSink0) | -| LocalDataFlow.cs:64:9:64:25 | ... + ... | LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | +| LocalDataFlow.cs:64:9:64:25 | ... += ... | LocalDataFlow.cs:64:9:64:16 | access to local variable nonSink0 | | LocalDataFlow.cs:64:9:64:25 | SSA def(nonSink0) | LocalDataFlow.cs:65:15:65:22 | access to local variable nonSink0 | -| LocalDataFlow.cs:64:21:64:25 | "abc" | LocalDataFlow.cs:64:9:64:25 | ... + ... | +| LocalDataFlow.cs:64:21:64:25 | "abc" | LocalDataFlow.cs:64:9:64:25 | ... += ... | | LocalDataFlow.cs:65:15:65:22 | [post] access to local variable nonSink0 | LocalDataFlow.cs:72:20:72:27 | access to local variable nonSink0 | | LocalDataFlow.cs:65:15:65:22 | access to local variable nonSink0 | LocalDataFlow.cs:72:20:72:27 | access to local variable nonSink0 | | LocalDataFlow.cs:68:13:68:17 | access to local variable sink5 | LocalDataFlow.cs:68:13:68:32 | SSA def(sink5) | diff --git a/csharp/ql/test/library-tests/dynamic/DynamicOperatorCall.expected b/csharp/ql/test/library-tests/dynamic/DynamicOperatorCall.expected index 6c0a054c84ab..6e98bffaf6f8 100644 --- a/csharp/ql/test/library-tests/dynamic/DynamicOperatorCall.expected +++ b/csharp/ql/test/library-tests/dynamic/DynamicOperatorCall.expected @@ -1,6 +1,6 @@ | dynamic.cs:35:13:35:14 | dynamic call to operator - | - | 0 | dynamic.cs:35:14:35:14 | access to local variable d | | dynamic.cs:36:13:36:17 | dynamic call to operator + | + | 0 | dynamic.cs:36:13:36:13 | access to local variable d | | dynamic.cs:36:13:36:17 | dynamic call to operator + | + | 1 | dynamic.cs:36:17:36:17 | access to local variable d | -| dynamic.cs:37:9:37:14 | dynamic call to operator + | + | 0 | dynamic.cs:37:9:37:9 | access to local variable d | -| dynamic.cs:37:9:37:14 | dynamic call to operator + | + | 1 | dynamic.cs:37:14:37:14 | access to local variable d | +| dynamic.cs:37:9:37:14 | ... += ... | + | 0 | dynamic.cs:37:9:37:9 | access to local variable d | +| dynamic.cs:37:9:37:14 | ... += ... | + | 1 | dynamic.cs:37:14:37:14 | access to local variable d | | dynamic.cs:47:9:47:11 | dynamic call to operator ++ | ++ | 0 | dynamic.cs:47:9:47:9 | access to local variable d | diff --git a/csharp/ql/test/library-tests/dynamic/PrintAst.expected b/csharp/ql/test/library-tests/dynamic/PrintAst.expected index 3bde4d42d862..3526e0b6bf54 100644 --- a/csharp/ql/test/library-tests/dynamic/PrintAst.expected +++ b/csharp/ql/test/library-tests/dynamic/PrintAst.expected @@ -105,12 +105,12 @@ dynamic.cs: # 35| 15: [ExprStmt] ...; # 35| 0: [AssignExpr] ... = ... # 35| 0: [LocalVariableAccess] access to local variable d -# 35| 1: [DynamicOperatorCall] dynamic call to operator - +# 35| 1: [OperatorCall] dynamic call to operator - # 35| 0: [LocalVariableAccess] access to local variable d # 36| 16: [ExprStmt] ...; # 36| 0: [AssignExpr] ... = ... # 36| 0: [LocalVariableAccess] access to local variable d -# 36| 1: [DynamicOperatorCall] dynamic call to operator + +# 36| 1: [OperatorCall] dynamic call to operator + # 36| 0: [LocalVariableAccess] access to local variable d # 36| 1: [LocalVariableAccess] access to local variable d # 37| 17: [ExprStmt] ...; @@ -141,7 +141,7 @@ dynamic.cs: # 44| 0: [PostIncrExpr] ...++ # 44| 0: [LocalVariableAccess] access to local variable i # 47| 23: [ExprStmt] ...; -# 47| 0: [DynamicOperatorCall] dynamic call to operator ++ +# 47| 0: [OperatorCall] dynamic call to operator ++ # 47| 0: [LocalVariableAccess] access to local variable d # 50| 24: [ExprStmt] ...; # 50| 0: [PostIncrExpr] ...++ diff --git a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected index 6271d6276c72..2073fce06a77 100644 --- a/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected +++ b/csharp/ql/test/query-tests/Dead Code/DeadStoreOfLocal/DeadStoreOfLocal.expected @@ -1,7 +1,7 @@ | DeadStoreOfLocal.cs:12:13:12:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:12:13:12:13 | x | x | | DeadStoreOfLocal.cs:19:21:19:25 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:18:13:18:13 | x | x | | DeadStoreOfLocal.cs:44:13:44:20 | Int32 x = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:44:13:44:13 | x | x | -| DeadStoreOfLocal.cs:50:9:50:14 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:49:13:49:13 | x | x | +| DeadStoreOfLocal.cs:50:9:50:14 | ... += ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:49:13:49:13 | x | x | | DeadStoreOfLocal.cs:56:9:56:11 | ...++ | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:55:13:55:13 | x | x | | DeadStoreOfLocal.cs:82:22:82:24 | String val | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:82:22:82:24 | val | val | | DeadStoreOfLocal.cs:101:13:101:37 | ... = ... | This assignment to $@ is useless, since its value is never read. | DeadStoreOfLocal.cs:94:40:94:44 | extra | extra | diff --git a/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected b/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected index 2477cd600e0f..fc8933cac930 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected +++ b/csharp/ql/test/query-tests/Security Features/CWE-112/MissingXMLValidation.expected @@ -3,7 +3,6 @@ | MissingXMLValidation.cs:21:26:21:58 | object creation of type StringReader | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:21:26:21:58 | object creation of type StringReader | This XML processing depends on a $@ without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString | user-provided value | | MissingXMLValidation.cs:27:26:27:58 | object creation of type StringReader | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:27:26:27:58 | object creation of type StringReader | This XML processing depends on a $@ without validation because the 'XmlReaderSettings' instance does not specify the 'ValidationType' as 'Schema'. | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString | user-provided value | | MissingXMLValidation.cs:45:26:45:58 | object creation of type StringReader | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:45:26:45:58 | object creation of type StringReader | This XML processing depends on a $@ without validation because the 'XmlReaderSettings' instance specifies 'ProcessInlineSchema'. | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString | user-provided value | -| MissingXMLValidation.cs:45:26:45:58 | object creation of type StringReader | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString : NameValueCollection | MissingXMLValidation.cs:45:26:45:58 | object creation of type StringReader | This XML processing depends on a $@ without validation because the 'XmlReaderSettings' instance specifies 'ProcessSchemaLocation'. | MissingXMLValidation.cs:12:34:12:56 | access to property QueryString | user-provided value | edges | MissingXMLValidation.cs:12:16:12:30 | access to local variable userProvidedXml : String | MissingXMLValidation.cs:16:43:16:57 | access to local variable userProvidedXml : String | provenance | | | MissingXMLValidation.cs:12:16:12:30 | access to local variable userProvidedXml : String | MissingXMLValidation.cs:21:43:21:57 | access to local variable userProvidedXml : String | provenance | |