From 664453707a36b386a15f6e53f861bfc2786bdbf6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 5 Dec 2018 11:00:15 +0100 Subject: [PATCH 01/69] C#: Speedup `Assertions::strictlyDominates()` and `ControlFlowElement::controlsBlock()` Only calculate dominance by explicit recursion for split nodes; all other nodes can use regular CFG dominance. --- .../semmle/code/csharp/commons/Assertions.qll | 32 ++++++--- .../code/csharp/controlflow/BasicBlocks.qll | 1 + .../csharp/controlflow/ControlFlowElement.qll | 72 ++++++++++++++----- .../csharp/controlflow/ControlFlowGraph.qll | 7 ++ 4 files changed, 82 insertions(+), 30 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/commons/Assertions.qll b/csharp/ql/src/semmle/code/csharp/commons/Assertions.qll index 5fa5bb92ad73..f7f0183b1da6 100644 --- a/csharp/ql/src/semmle/code/csharp/commons/Assertions.qll +++ b/csharp/ql/src/semmle/code/csharp/commons/Assertions.qll @@ -51,6 +51,9 @@ class Assertion extends MethodCall { pragma[nomagic] private JoinBlockPredecessor getAPossiblyDominatedPredecessor(JoinBlock jb) { + // Only calculate dominance by explicit recursion for split nodes; + // all other nodes can use regular CFG dominance + this instanceof ControlFlow::Internal::SplitControlFlowElement and exists(BasicBlock bb | bb = this.getAControlFlowNode().getBasicBlock() | result = bb.getASuccessor*() @@ -70,6 +73,22 @@ class Assertion extends MethodCall { ) } + pragma[nomagic] + private predicate strictlyDominatesSplit(BasicBlock bb) { + this.getAControlFlowNode().getBasicBlock().immediatelyDominates(bb) + or + if bb instanceof JoinBlock then + this.isPossiblyDominatedJoinBlock(bb) and + forall(BasicBlock pred | + pred = this.getAPossiblyDominatedPredecessor(bb) | + this.strictlyDominatesSplit(pred) + or + this.getAControlFlowNode().getBasicBlock() = pred + ) + else + this.strictlyDominatesSplit(bb.getAPredecessor()) + } + /** * Holds if this assertion strictly dominates basic block `bb`. That is, `bb` * can only be reached from the callable entry point by going via *some* basic @@ -81,18 +100,9 @@ class Assertion extends MethodCall { */ pragma[nomagic] predicate strictlyDominates(BasicBlock bb) { - this.getAControlFlowNode().getBasicBlock().immediatelyDominates(bb) + this.strictlyDominatesSplit(bb) or - if bb instanceof JoinBlock then - this.isPossiblyDominatedJoinBlock(bb) and - forall(BasicBlock pred | - pred = this.getAPossiblyDominatedPredecessor(bb) | - this.strictlyDominates(pred) - or - this.getAControlFlowNode().getBasicBlock() = pred - ) - else - this.strictlyDominates(bb.getAPredecessor()) + this.getAControlFlowNode().getBasicBlock().strictlyDominates(bb) } } diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll b/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll index 2edf13d12765..7ab1a0ba3b39 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/BasicBlocks.qll @@ -473,6 +473,7 @@ class ConditionBlock extends BasicBlock { * successor of this block, and `succ` can only be reached from * the callable entry point by going via the `s` edge out of this basic block. */ + pragma[nomagic] predicate immediatelyControls(BasicBlock succ, ConditionalSuccessor s) { succ = this.getASuccessorByType(s) and forall(BasicBlock pred | diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll index fcd0f61aa059..15481f02956c 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll @@ -79,12 +79,23 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { * `pred` ending with this element, and `pred` is an immediate predecessor * of `succ`. * - * This predicate is different from - * `this.getAControlFlowNode().getBasicBlock().(ConditionBlock).immediatelyControls(succ, s)` - * in that it takes control flow splitting into account. + * Moroever, this control flow element corresponds to multiple control flow nodes, + * which is why + * + * ``` + * exists(ConditionBlock cb | + * cb.getLastNode() = this.getAControlFlowNode() | + * cb.immediatelyControls(succ, s) + * ) + * ``` + * + * does not work. */ pragma[nomagic] - private predicate immediatelyControls(BasicBlock succ, ConditionalSuccessor s) { + private predicate immediatelyControlsBlockSplit(BasicBlock succ, ConditionalSuccessor s) { + // Only calculate dominance by explicit recursion for split nodes; + // all other nodes can use regular CFG dominance + this instanceof ControlFlow::Internal::SplitControlFlowElement and exists(ConditionBlock cb | cb.getLastNode() = this.getAControlFlowNode() | succ = cb.getASuccessorByType(s) and @@ -103,7 +114,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { pragma[nomagic] private JoinBlockPredecessor getAPossiblyControlledPredecessor(JoinBlock controlled, ConditionalSuccessor s) { exists(BasicBlock mid | - this.immediatelyControls(mid, s) | + this.immediatelyControlsBlockSplit(mid, s) | result = mid.getASuccessor*() ) and result.getASuccessor() = controlled and @@ -121,6 +132,20 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { ) } + cached + private predicate controlsBlockSplit(BasicBlock controlled, ConditionalSuccessor s) { + this.immediatelyControlsBlockSplit(controlled, s) + or + if controlled instanceof JoinBlock then + this.isPossiblyControlledJoinBlock(controlled, s) and + forall(BasicBlock pred | + pred = this.getAPossiblyControlledPredecessor(controlled, s) | + this.controlsBlock(pred, s) + ) + else + this.controlsBlockSplit(controlled.getAPredecessor(), s) + } + /** * Holds if basic block `controlled` is controlled by this control flow element * with conditional value `s`. That is, `controlled` can only be reached from @@ -128,21 +153,23 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { * ending with this element. * * This predicate is different from - * `this.getAControlFlowNode().getBasicBlock().(ConditionBlock).controls(controlled, s)` - * in that it takes control flow splitting into account. + * + * ``` + * exists(ConditionBlock cb | + * cb.getLastNode() = this.getAControlFlowNode() | + * cb.controls(controlled, s) + * ) + * ``` + * + * as control flow splitting is taken into account. */ - cached predicate controlsBlock(BasicBlock controlled, ConditionalSuccessor s) { - this.immediatelyControls(controlled, s) + this.controlsBlockSplit(controlled, s) or - if controlled instanceof JoinBlock then - this.isPossiblyControlledJoinBlock(controlled, s) and - forall(BasicBlock pred | - pred = this.getAPossiblyControlledPredecessor(controlled, s) | - this.controlsBlock(pred, s) - ) - else - this.controlsBlock(controlled.getAPredecessor(), s) + exists(ConditionBlock cb | + cb.getLastNode() = this.getAControlFlowNode() | + cb.controls(controlled, s) + ) } /** @@ -151,8 +178,15 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { * from the callable entry point by going via the `s` edge out of this element. * * This predicate is different from - * `this.getAControlFlowNode().getBasicBlock().(ConditionBlock).controls(controlled.getAControlFlowNode().getBasicBlock(), s)` - * in that it takes control flow splitting into account. + * + * ``` + * exists(ConditionBlock cb | + * cb.getLastNode() = this.getAControlFlowNode() | + * cb.controls(controlled.getAControlFlowNode().getBasicBlock(), s) + * ) + * ``` + * + * as control flow splitting is taken into account. */ pragma[inline] // potentially very large predicate, so must be inlined predicate controlsElement(ControlFlowElement controlled, ConditionalSuccessor s) { diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll index 8a594bbeb69d..8d2600469438 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowGraph.qll @@ -4185,6 +4185,13 @@ module ControlFlow { } } import Cached + + /** A control flow element that is split into multiple control flow nodes. */ + class SplitControlFlowElement extends ControlFlowElement { + SplitControlFlowElement() { + strictcount(this.getAControlFlowNode()) > 1 + } + } } private import Internal } From e05bbb0f106f0b6793c5d7c392562648c88dab7d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 7 Dec 2018 15:46:27 +0100 Subject: [PATCH 02/69] C#: Fix always-`null` bug in TRAP writer --- csharp/extractor/Semmle.Extraction/TrapWriter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/extractor/Semmle.Extraction/TrapWriter.cs b/csharp/extractor/Semmle.Extraction/TrapWriter.cs index cdc31019d1f1..25003e4e53d6 100644 --- a/csharp/extractor/Semmle.Extraction/TrapWriter.cs +++ b/csharp/extractor/Semmle.Extraction/TrapWriter.cs @@ -285,7 +285,7 @@ private void ArchiveContents(string fullInputPath, string contents) public static string NestPaths(ILogger logger, string outerpath, string innerpath, InnerPathComputation innerPathComputation) { string nested = innerpath; - if (outerpath != null || outerpath.Length != 0) + if (!string.IsNullOrEmpty(outerpath)) { if (!Path.IsPathRooted(innerpath) && innerPathComputation == InnerPathComputation.ABSOLUTE) innerpath = Path.GetFullPath(innerpath); From 6411d1c7dd69c4f4671f32e770543ce2e7728465 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 7 Dec 2018 15:47:20 +0100 Subject: [PATCH 03/69] C#: Refactor operator call logic Refactored to make it clear when `@operator.Symbol as IMethodSymbol` can be `null`. --- .../Semmle.Extraction.CSharp/Entities/Expression.cs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index c050d4d83e95..d88050b545bf 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -119,14 +119,15 @@ public void OperatorCall(ExpressionSyntax node) var @operator = cx.GetSymbolInfo(node); var method = @operator.Symbol as IMethodSymbol; - if (GetCallType(cx, node) == CallType.Dynamic) + var callType = GetCallType(cx, node); + if (callType == CallType.Dynamic) { UserOperator.OperatorSymbol(method.Name, out string operatorName); cx.Emit(Tuples.dynamic_member_name(this, operatorName)); return; } - if (method != null) + if (callType != CallType.None) cx.Emit(Tuples.expr_call(this, Method.Create(cx, method))); } @@ -148,12 +149,9 @@ public static CallType GetCallType(Context cx, ExpressionSyntax node) { var @operator = cx.GetSymbolInfo(node); - if (@operator.Symbol != null) + if (@operator.Symbol is IMethodSymbol method) { - var method = @operator.Symbol as IMethodSymbol; - - var containingSymbol = method.ContainingSymbol as ITypeSymbol; - if (containingSymbol != null && containingSymbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Dynamic) + if (method.ContainingSymbol is ITypeSymbol containingSymbol && containingSymbol.TypeKind == Microsoft.CodeAnalysis.TypeKind.Dynamic) { return CallType.Dynamic; } From 8d072863dfa8194481309a813ddc100780480ca2 Mon Sep 17 00:00:00 2001 From: calum Date: Mon, 10 Dec 2018 18:51:22 +0000 Subject: [PATCH 04/69] C#: Reorder for statements to ensure variables declared in the condition are declared before they are used. --- .../Entities/Statements/For.cs | 10 +++++----- csharp/ql/test/library-tests/csharp7/CSharp7.cs | 11 +++++++++++ csharp/ql/test/library-tests/csharp7/DefUse.expected | 7 +++++++ .../ql/test/library-tests/csharp7/IsPatterns.expected | 1 + .../library-tests/csharp7/LocalTaintFlow.expected | 11 +++++++++++ .../library-tests/csharp7/LocalVariables.expected | 2 ++ 6 files changed, 37 insertions(+), 5 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/For.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/For.cs index 2c918af83ef6..c0860d21d127 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/For.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Statements/For.cs @@ -28,7 +28,10 @@ protected override void Populate() Expression.Create(cx, init, this, child--); } - Statement.Create(cx, Stmt.Statement, this, 1 + Stmt.Incrementors.Count); + if (Stmt.Condition != null) + { + Expression.Create(cx, Stmt.Condition, this, 0); + } child = 1; foreach (var inc in Stmt.Incrementors) @@ -36,10 +39,7 @@ protected override void Populate() Expression.Create(cx, inc, this, child++); } - if (Stmt.Condition != null) - { - Expression.Create(cx, Stmt.Condition, this, 0); - } + Statement.Create(cx, Stmt.Statement, this, 1 + Stmt.Incrementors.Count); } } } diff --git a/csharp/ql/test/library-tests/csharp7/CSharp7.cs b/csharp/ql/test/library-tests/csharp7/CSharp7.cs index 7a2898a97e46..0b0c543216f1 100644 --- a/csharp/ql/test/library-tests/csharp7/CSharp7.cs +++ b/csharp/ql/test/library-tests/csharp7/CSharp7.cs @@ -290,3 +290,14 @@ void Test() foreach (var (a, b) in list) { } } } + +class ForLoops +{ + void Test() + { + for(int x=0; x<10 && x is int y; ++x) + { + Console.WriteLine(y); + } + } +} diff --git a/csharp/ql/test/library-tests/csharp7/DefUse.expected b/csharp/ql/test/library-tests/csharp7/DefUse.expected index e6f5a6c407b9..93bdff568c26 100644 --- a/csharp/ql/test/library-tests/csharp7/DefUse.expected +++ b/csharp/ql/test/library-tests/csharp7/DefUse.expected @@ -66,3 +66,10 @@ | CSharp7.cs:284:13:284:62 | IEnumerable<(Int32,String)> list = ... | CSharp7.cs:290:32:290:35 | access to local variable list | | CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:41:284:44 | access to parameter item | | CSharp7.cs:284:32:284:35 | item | CSharp7.cs:284:51:284:54 | access to parameter item | +| CSharp7.cs:298:17:298:19 | Int32 x = ... | CSharp7.cs:298:22:298:22 | access to local variable x | +| CSharp7.cs:298:17:298:19 | Int32 x = ... | CSharp7.cs:298:30:298:30 | access to local variable x | +| CSharp7.cs:298:17:298:19 | Int32 x = ... | CSharp7.cs:298:44:298:44 | access to local variable x | +| CSharp7.cs:298:35:298:39 | Int32 y | CSharp7.cs:300:31:300:31 | access to local variable y | +| CSharp7.cs:298:42:298:44 | ++... | CSharp7.cs:298:22:298:22 | access to local variable x | +| CSharp7.cs:298:42:298:44 | ++... | CSharp7.cs:298:30:298:30 | access to local variable x | +| CSharp7.cs:298:42:298:44 | ++... | CSharp7.cs:298:44:298:44 | access to local variable x | diff --git a/csharp/ql/test/library-tests/csharp7/IsPatterns.expected b/csharp/ql/test/library-tests/csharp7/IsPatterns.expected index 054a9accab33..6259acf8790f 100644 --- a/csharp/ql/test/library-tests/csharp7/IsPatterns.expected +++ b/csharp/ql/test/library-tests/csharp7/IsPatterns.expected @@ -2,3 +2,4 @@ | CSharp7.cs:238:18:238:31 | ... is ... | CSharp7.cs:238:23:238:28 | access to type String | String | CSharp7.cs:238:23:238:31 | String s1 | false | | CSharp7.cs:245:18:245:28 | ... is ... | CSharp7.cs:245:23:245:25 | access to type Object | Object | CSharp7.cs:245:23:245:28 | Object v1 | true | | CSharp7.cs:255:27:255:40 | ... is ... | CSharp7.cs:255:32:255:37 | access to type String | String | CSharp7.cs:255:32:255:40 | String s4 | false | +| CSharp7.cs:298:30:298:39 | ... is ... | CSharp7.cs:298:35:298:37 | access to type Int32 | Int32 | CSharp7.cs:298:35:298:39 | Int32 y | false | diff --git a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected index f07a6f7efc86..32766ee67a39 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalTaintFlow.expected @@ -193,3 +193,14 @@ | CSharp7.cs:288:36:288:39 | access to local variable list | CSharp7.cs:290:32:290:35 | access to local variable list | | CSharp7.cs:290:23:290:23 | Int32 a | CSharp7.cs:290:18:290:27 | (..., ...) | | CSharp7.cs:290:26:290:26 | String b | CSharp7.cs:290:18:290:27 | (..., ...) | +| CSharp7.cs:298:17:298:19 | SSA def(x) | CSharp7.cs:298:22:298:39 | SSA phi(x) | +| CSharp7.cs:298:19:298:19 | 0 | CSharp7.cs:298:17:298:19 | SSA def(x) | +| CSharp7.cs:298:22:298:22 | access to local variable x | CSharp7.cs:298:22:298:25 | ... < ... | +| CSharp7.cs:298:22:298:22 | access to local variable x | CSharp7.cs:298:30:298:30 | access to local variable x | +| CSharp7.cs:298:22:298:25 | ... < ... | CSharp7.cs:298:22:298:39 | ... && ... | +| CSharp7.cs:298:22:298:39 | SSA phi(x) | CSharp7.cs:298:22:298:22 | access to local variable x | +| CSharp7.cs:298:30:298:30 | access to local variable x | CSharp7.cs:298:35:298:39 | SSA def(y) | +| CSharp7.cs:298:30:298:30 | access to local variable x | CSharp7.cs:298:44:298:44 | access to local variable x | +| CSharp7.cs:298:30:298:39 | ... is ... | CSharp7.cs:298:22:298:39 | ... && ... | +| CSharp7.cs:298:35:298:39 | SSA def(y) | CSharp7.cs:300:31:300:31 | access to local variable y | +| CSharp7.cs:298:42:298:44 | SSA def(x) | CSharp7.cs:298:22:298:39 | SSA phi(x) | diff --git a/csharp/ql/test/library-tests/csharp7/LocalVariables.expected b/csharp/ql/test/library-tests/csharp7/LocalVariables.expected index 95cfa37a6267..1e04aeafd004 100644 --- a/csharp/ql/test/library-tests/csharp7/LocalVariables.expected +++ b/csharp/ql/test/library-tests/csharp7/LocalVariables.expected @@ -65,3 +65,5 @@ | CSharp7.cs:288:30:288:30 | b | string | | CSharp7.cs:290:23:290:23 | a | int | | CSharp7.cs:290:26:290:26 | b | string | +| CSharp7.cs:298:17:298:17 | x | int | +| CSharp7.cs:298:39:298:39 | y | int | From f0fb47cde0b099b29230c65ab3f7343cc6182296 Mon Sep 17 00:00:00 2001 From: calum Date: Tue, 11 Dec 2018 10:31:39 +0000 Subject: [PATCH 05/69] C#: Update change notes. --- change-notes/1.20/analysis-csharp.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/change-notes/1.20/analysis-csharp.md b/change-notes/1.20/analysis-csharp.md index 13ec3648eb2e..6c80a8be29a3 100644 --- a/change-notes/1.20/analysis-csharp.md +++ b/change-notes/1.20/analysis-csharp.md @@ -17,6 +17,8 @@ ## Changes to code extraction +* Fix extraction of `for` statements where the condition declares new variables using `is`. + ## Changes to QL libraries ## Changes to the autobuilder From e80837681fce130fe64f61091fc4ad22496ec90f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 7 Dec 2018 15:48:38 +0100 Subject: [PATCH 06/69] C#: Refactor LINQ logic Factor `ClauseCall` out into three classes to make it clear when the fields `operand` and `declaration` can be `null`. --- .../Entities/Expressions/Query.cs | 189 ++++++++++-------- 1 file changed, 102 insertions(+), 87 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs index d5c8ead52fd1..18a016d07096 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expressions/Query.cs @@ -33,58 +33,37 @@ public QueryCall(Context cx, IMethodSymbol method, SyntaxNode clause, IExpressio /// /// Represents a chain of method calls (the operand being recursive). /// - class ClauseCall + abstract class Clause { - public ClauseCall operand; - public IMethodSymbol method; - public readonly List arguments = new List(); - public SyntaxNode node; - public ISymbol declaration; - public SyntaxToken name; - public ISymbol intoDeclaration; + protected readonly IMethodSymbol method; + protected readonly List arguments = new List(); + protected readonly SyntaxNode node; - public ExpressionSyntax Expr => arguments.First(); - - public ClauseCall WithClause(IMethodSymbol newMethod, SyntaxNode newNode, SyntaxToken newName = default(SyntaxToken), ISymbol newDeclaration = null) + protected Clause(IMethodSymbol method, SyntaxNode node) { - return new ClauseCall - { - operand = this, - method = newMethod, - node = newNode, - name = newName, - declaration = newDeclaration - }; + this.method = method; + this.node = node; } - public ClauseCall AddArgument(ExpressionSyntax arg) - { - if (arg != null) - arguments.Add(arg); - return this; - } + public ExpressionSyntax Expr => arguments.First(); - public ClauseCall WithInto(ISymbol into) - { - intoDeclaration = into; - return this; - } + public CallClause WithCallClause(IMethodSymbol newMethod, SyntaxNode newNode) => + new CallClause(this, newMethod, newNode); - Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement) - { - return DeclareRangeVariable(cx, parent, child, getElement, declaration); - } + public LetClause WithLetClause(IMethodSymbol newMethod, SyntaxNode newNode, ISymbol newDeclaration, SyntaxToken newName) => + new LetClause(this, newMethod, newNode, newDeclaration, newName); - void DeclareIntoVariable(Context cx, IExpressionParentEntity parent, int intoChild, bool getElement) + public Clause AddArgument(ExpressionSyntax arg) { - if (intoDeclaration != null) - DeclareRangeVariable(cx, parent, intoChild, getElement, intoDeclaration); + if (arg != null) + arguments.Add(arg); + return this; } - Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol) + protected Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int child, bool getElement, ISymbol variableSymbol, SyntaxToken name) { var type = Type.Create(cx, cx.GetType(Expr)); - Semmle.Extraction.Entities.Location nameLoc; + Extraction.Entities.Location nameLoc; Type declType; if (getElement) @@ -115,7 +94,7 @@ Expression DeclareRangeVariable(Context cx, IExpressionParentEntity parent, int return decl; } - void PopulateArguments(Context cx, QueryCall callExpr, int child) + protected void PopulateArguments(Context cx, QueryCall callExpr, int child) { foreach (var e in arguments) { @@ -123,34 +102,79 @@ void PopulateArguments(Context cx, QueryCall callExpr, int child) } } - public Expression Populate(Context cx, IExpressionParentEntity parent, int child) + public abstract Expression Populate(Context cx, IExpressionParentEntity parent, int child); + } + + class RangeClause : Clause + { + readonly ISymbol declaration; + readonly SyntaxToken name; + + public RangeClause(IMethodSymbol method, SyntaxNode node, ISymbol declaration, SyntaxToken name) : base(method, node) { - if (declaration != null) // The first "from" clause, or a "let" clause - { - if (operand == null) - { - return DeclareRangeVariable(cx, parent, child, true); - } - else - { - if (method == null) - cx.ModelError(node, "Unable to determine target of query expression"); - - var callExpr = new QueryCall(cx, method, node, parent, child); - operand.Populate(cx, callExpr, 0); - DeclareRangeVariable(cx, callExpr, 1, false); - PopulateArguments(cx, callExpr, 2); - DeclareIntoVariable(cx, callExpr, 2 + arguments.Count, false); - return callExpr; - } - } - else - { - var callExpr = new QueryCall(cx, method, node, parent, child); - operand.Populate(cx, callExpr, 0); - PopulateArguments(cx, callExpr, 1); - return callExpr; - } + this.declaration = declaration; + this.name = name; + } + + public override Expression Populate(Context cx, IExpressionParentEntity parent, int child) => + DeclareRangeVariable(cx, parent, child, true, declaration, name); + } + + class LetClause : Clause + { + readonly Clause operand; + readonly ISymbol declaration; + readonly SyntaxToken name; + ISymbol intoDeclaration; + + public LetClause(Clause operand, IMethodSymbol method, SyntaxNode node, ISymbol declaration, SyntaxToken name) : base(method, node) + { + this.operand = operand; + this.declaration = declaration; + this.name = name; + } + + public Clause WithInto(ISymbol into) + { + intoDeclaration = into; + return this; + } + + void DeclareIntoVariable(Context cx, IExpressionParentEntity parent, int intoChild, bool getElement) + { + if (intoDeclaration != null) + DeclareRangeVariable(cx, parent, intoChild, getElement, intoDeclaration, name); + } + + public override Expression Populate(Context cx, IExpressionParentEntity parent, int child) + { + if (method == null) + cx.ModelError(node, "Unable to determine target of query expression"); + + var callExpr = new QueryCall(cx, method, node, parent, child); + operand.Populate(cx, callExpr, 0); + DeclareRangeVariable(cx, callExpr, 1, false, declaration, name); + PopulateArguments(cx, callExpr, 2); + DeclareIntoVariable(cx, callExpr, 2 + arguments.Count, false); + return callExpr; + } + } + + class CallClause : Clause + { + readonly Clause operand; + + public CallClause(Clause operand, IMethodSymbol method, SyntaxNode node) : base(method, node) + { + this.operand = operand; + } + + public override Expression Populate(Context cx, IExpressionParentEntity parent, int child) + { + var callExpr = new QueryCall(cx, method, node, parent, child); + operand.Populate(cx, callExpr, 0); + PopulateArguments(cx, callExpr, 1); + return callExpr; } } @@ -161,18 +185,12 @@ public Expression Populate(Context cx, IExpressionParentEntity parent, int child /// The extraction context. /// The query expression. /// A "syntax tree" of the query. - static ClauseCall ConstructQueryExpression(Context cx, QueryExpressionSyntax node) + static Clause ConstructQueryExpression(Context cx, QueryExpressionSyntax node) { var info = cx.Model(node).GetQueryClauseInfo(node.FromClause); var method = info.OperationInfo.Symbol as IMethodSymbol; - ClauseCall clauseExpr = new ClauseCall - { - declaration = cx.Model(node).GetDeclaredSymbol(node.FromClause), - name = node.FromClause.Identifier, - method = method, - node = node.FromClause - }.AddArgument(node.FromClause.Expression); + Clause clauseExpr = new RangeClause(method, node.FromClause, cx.Model(node).GetDeclaredSymbol(node.FromClause), node.FromClause.Identifier).AddArgument(node.FromClause.Expression); foreach (var qc in node.Body.Clauses) { @@ -188,7 +206,7 @@ static ClauseCall ConstructQueryExpression(Context cx, QueryExpressionSyntax nod { method = cx.Model(node).GetSymbolInfo(ordering).Symbol as IMethodSymbol; - clauseExpr = clauseExpr.WithClause(method, orderByClause).AddArgument(ordering.Expression); + clauseExpr = clauseExpr.WithCallClause(method, orderByClause).AddArgument(ordering.Expression); if (method == null) cx.ModelError(ordering, "Could not determine method call for orderby clause"); @@ -196,23 +214,23 @@ static ClauseCall ConstructQueryExpression(Context cx, QueryExpressionSyntax nod break; case SyntaxKind.WhereClause: var whereClause = (WhereClauseSyntax)qc; - clauseExpr = clauseExpr.WithClause(method, whereClause).AddArgument(whereClause.Condition); + clauseExpr = clauseExpr.WithCallClause(method, whereClause).AddArgument(whereClause.Condition); break; case SyntaxKind.FromClause: var fromClause = (FromClauseSyntax)qc; clauseExpr = clauseExpr. - WithClause(method, fromClause, fromClause.Identifier, cx.Model(node).GetDeclaredSymbol(fromClause)). + WithLetClause(method, fromClause, cx.Model(node).GetDeclaredSymbol(fromClause), fromClause.Identifier). AddArgument(fromClause.Expression); break; case SyntaxKind.LetClause: var letClause = (LetClauseSyntax)qc; - clauseExpr = clauseExpr.WithClause(method, letClause, letClause.Identifier, cx.Model(node).GetDeclaredSymbol(letClause)). + clauseExpr = clauseExpr.WithLetClause(method, letClause, cx.Model(node).GetDeclaredSymbol(letClause), letClause.Identifier). AddArgument(letClause.Expression); break; case SyntaxKind.JoinClause: var joinClause = (JoinClauseSyntax)qc; - clauseExpr = clauseExpr.WithClause(method, joinClause, joinClause.Identifier, cx.Model(node).GetDeclaredSymbol(joinClause)). + clauseExpr = clauseExpr.WithLetClause(method, joinClause, cx.Model(node).GetDeclaredSymbol(joinClause), joinClause.Identifier). AddArgument(joinClause.InExpression). AddArgument(joinClause.LeftExpression). AddArgument(joinClause.RightExpression); @@ -220,7 +238,7 @@ static ClauseCall ConstructQueryExpression(Context cx, QueryExpressionSyntax nod if (joinClause.Into != null) { var into = cx.Model(node).GetDeclaredSymbol(joinClause.Into); - clauseExpr.WithInto(into); + ((LetClause)clauseExpr).WithInto(into); } break; @@ -231,16 +249,13 @@ static ClauseCall ConstructQueryExpression(Context cx, QueryExpressionSyntax nod method = cx.Model(node).GetSymbolInfo(node.Body.SelectOrGroup).Symbol as IMethodSymbol; - var selectClause = node.Body.SelectOrGroup as SelectClauseSyntax; - var groupClause = node.Body.SelectOrGroup as GroupClauseSyntax; - - clauseExpr = new ClauseCall { operand = clauseExpr, method = method, node = node.Body.SelectOrGroup }; + clauseExpr = new CallClause(clauseExpr, method, node.Body.SelectOrGroup); - if (selectClause != null) + if (node.Body.SelectOrGroup is SelectClauseSyntax selectClause) { clauseExpr.AddArgument(selectClause.Expression); } - else if (groupClause != null) + else if (node.Body.SelectOrGroup is GroupClauseSyntax groupClause) { clauseExpr. AddArgument(groupClause.GroupExpression). From 1366638f061bbfe9a28a531a0b5d9c1f383a4dcc Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 12 Dec 2018 13:13:13 +0100 Subject: [PATCH 07/69] C#: Fix whitespaces --- .../Collections/ContainerLengthCmpOffByOne.ql | 6 ++--- .../ql/src/Security Features/CWE-730/ReDoS.ql | 2 +- .../CWE-937/Vulnerabilities.qll | 22 +++++++++---------- .../semmle/code/csharp/controlflow/Guards.qll | 4 ++-- .../library-tests/cil/regressions/Methods.cs | 2 +- .../ContainerLengthCmpOffByOne.cs | 6 ++--- .../Security Features/CWE-937/csproj.config | 4 ++-- .../Security Features/CWE-937/packages.config | 2 +- 8 files changed, 24 insertions(+), 24 deletions(-) diff --git a/csharp/ql/src/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql b/csharp/ql/src/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql index 2cb7103ee0c5..e337aef3b1f7 100644 --- a/csharp/ql/src/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql +++ b/csharp/ql/src/Likely Bugs/Collections/ContainerLengthCmpOffByOne.ql @@ -20,10 +20,10 @@ import semmle.code.csharp.commons.ComparisonTest class IndexGuard extends ComparisonTest { VariableAccess indexAccess; Variable array; - + IndexGuard() { this.getFirstArgument() = indexAccess and - this.getSecondArgument() = any(PropertyAccess lengthAccess | + this.getSecondArgument() = any(PropertyAccess lengthAccess | lengthAccess.getQualifier() = array.getAnAccess() and lengthAccess.getTarget().hasName("Length") ) @@ -50,7 +50,7 @@ from IndexGuard incorrectGuard, Variable array, Variable index, ElementAccess ea where // Look for `index <= array.Length` or `array.Length >= index` incorrectGuard.controls(array, index) and - incorrectGuard.isIncorrect() and + incorrectGuard.isIncorrect() and // Look for `array[index]` ea.getQualifier() = array.getAnAccess() and ea.getIndex(0) = indexAccess and diff --git a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql index f1dbe5a068ec..83aab48820ef 100644 --- a/csharp/ql/src/Security Features/CWE-730/ReDoS.ql +++ b/csharp/ql/src/Security Features/CWE-730/ReDoS.ql @@ -19,7 +19,7 @@ from TaintTrackingConfiguration c, DataFlow::PathNode source, DataFlow::PathNode where c.hasFlowPath(source, sink) and // No global timeout set - not exists(RegexGlobalTimeout r) and + not exists(RegexGlobalTimeout r) and ( sink.getNode() instanceof Sink or diff --git a/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll b/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll index 13e2ea301bbc..b7277850fdf4 100644 --- a/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll +++ b/csharp/ql/src/Security Features/CWE-937/Vulnerabilities.qll @@ -1,6 +1,6 @@ /** * Provides a list of NuGet packages with known vulnerabilities. - * + * * To add a new vulnerability follow the existing pattern. * Create a new class that extends the abstract class `Vulnerability`, * supplying the name and the URL, and override one (or both) of @@ -73,9 +73,9 @@ class MicrosoftAdvisory4021279 extends Vulnerability { class CVE_2017_8700 extends Vulnerability { CVE_2017_8700() { this = "CVE-2017-8700" } - + override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/279" } - + override predicate matchesRange(string name, Version affected, Version fixed) { ( name = "Microsoft.AspNetCore.Mvc.Core" @@ -91,9 +91,9 @@ class CVE_2017_8700 extends Vulnerability { class CVE_2018_0765 extends Vulnerability { CVE_2018_0765() { this = "CVE-2018-0765" } - + override string getUrl() { result = "https://github.com/dotnet/announcements/issues/67" } - + override predicate matchesRange(string name, Version affected, Version fixed) { name = "System.Security.Cryptography.Xml" and affected = "0.0.0" and @@ -103,7 +103,7 @@ class CVE_2018_0765 extends Vulnerability { class AspNetCore_Mar18 extends Vulnerability { AspNetCore_Mar18() { this = "ASPNETCore-Mar18" } - + override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/300" } override predicate matchesRange(string name, Version affected, Version fixed) { @@ -125,9 +125,9 @@ class AspNetCore_Mar18 extends Vulnerability { class CVE_2018_8409 extends Vulnerability { CVE_2018_8409() { this = "CVE-2018-8409" } - + override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/316" } - + override predicate matchesRange(string name, Version affected, Version fixed) { name = "System.IO.Pipelines" and affected = "4.5.0" and fixed = "4.5.1" or @@ -138,9 +138,9 @@ class CVE_2018_8409 extends Vulnerability { class CVE_2018_8171 extends Vulnerability { CVE_2018_8171() { this = "CVE-2018-8171" } - + override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/310" } - + override predicate matchesRange(string name, Version affected, Version fixed) { name = "Microsoft.AspNetCore.Identity" and ( affected = "1.0.0" and fixed = "1.0.6" @@ -204,7 +204,7 @@ class CVE_2018_8356 extends Vulnerability { class ASPNETCore_Jul18 extends Vulnerability { ASPNETCore_Jul18() { this = "ASPNETCore-July18" } - + override string getUrl() { result = "https://github.com/aspnet/Announcements/issues/311" } override predicate matchesRange(string name, Version affected, Version fixed) { diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll index 1a8a097f6cb3..5cf2582f0952 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll @@ -286,7 +286,7 @@ class DereferenceableExpr extends Expr { ie = any(IsTypeExpr ite | ite.getCheckedType() = ite.getExpr().getType()) and branch = false and isNull = true - ) + ) ) or this.hasNullableType() and @@ -1189,7 +1189,7 @@ module Internal { g1 = cond and v1 = v.getDualValue() and ( - // g1 === g2 ? e : ...; + // g1 === g2 ? e : ...; g2 = cond.getCondition() and v2 = TBooleanValue(branch.booleanNot()) or diff --git a/csharp/ql/test/library-tests/cil/regressions/Methods.cs b/csharp/ql/test/library-tests/cil/regressions/Methods.cs index 2d4f07b9855e..b81a5c9a44fa 100644 --- a/csharp/ql/test/library-tests/cil/regressions/Methods.cs +++ b/csharp/ql/test/library-tests/cil/regressions/Methods.cs @@ -3,7 +3,7 @@ * This tests the correct extraction of F, and we should end up with * 2 constructed methods of F. */ - + // semmle-extractor-options: --cil namespace Methods diff --git a/csharp/ql/test/query-tests/Likely Bugs/Collections/ContainerLengthCmpOffByOne/ContainerLengthCmpOffByOne.cs b/csharp/ql/test/query-tests/Likely Bugs/Collections/ContainerLengthCmpOffByOne/ContainerLengthCmpOffByOne.cs index b25145a8cbd8..d68bbfc274ec 100644 --- a/csharp/ql/test/query-tests/Likely Bugs/Collections/ContainerLengthCmpOffByOne/ContainerLengthCmpOffByOne.cs +++ b/csharp/ql/test/query-tests/Likely Bugs/Collections/ContainerLengthCmpOffByOne/ContainerLengthCmpOffByOne.cs @@ -48,7 +48,7 @@ void Test2(string[] args) } void Test3(string[] args) - { + { // GOOD: Guarded by ternary operator. for (int i = 0; i <= args.Length; i++) { @@ -68,7 +68,7 @@ void Test4(string[] args) } void Test5(string[] args) - { + { // GOOD: A valid test of Length. for (int i = 0; i != args.Length; i++) { @@ -94,6 +94,6 @@ void Test7(string[] args) for (int i = 0; i <= args.Length; i++) { bool b = i == args.Length || args[i] == "x"; - } + } } } diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config b/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config index 721d21559407..690612892147 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config +++ b/csharp/ql/test/query-tests/Security Features/CWE-937/csproj.config @@ -5,12 +5,12 @@ - + - + diff --git a/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config b/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config index 40e82a77df33..12f63f710432 100644 --- a/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config +++ b/csharp/ql/test/query-tests/Security Features/CWE-937/packages.config @@ -4,7 +4,7 @@ - + From 6918dad1dbd53aeb958a227f09160d4e0e430e6f Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 12 Dec 2018 13:14:22 +0100 Subject: [PATCH 08/69] C#: Refactor `localFlowStep()` Using the `forceCachingInSameStage()` trick, we can get rid of the non-cached version of local flow, while still computing it in the same stage. --- .../semmle/code/csharp/dataflow/DataFlow.qll | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index dfd7885899c5..1e5e6b0353ed 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -90,7 +90,7 @@ module DataFlow { localFlowStep*(source, sink) } - predicate localFlowStep = localFlowStepCached/2; + predicate localFlowStep = Internal::LocalFlow::step/2; /** * A data flow node augmented with a call context and a configuration. Only @@ -690,12 +690,14 @@ module DataFlow { /** * Provides predicates related to local data flow. */ - private module LocalFlow { + module LocalFlow { /** * Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local * (intra-procedural) step. */ - predicate localFlowStepNonCached(Node nodeFrom, Node nodeTo) { + cached + predicate step(Node nodeFrom, Node nodeTo) { + forceCachingInSameStage() and localFlowStepExpr(nodeFrom.asExpr(), nodeTo.asExpr()) or // Flow from source to SSA definition @@ -1119,6 +1121,8 @@ module DataFlow { * same stage. */ cached module Cached { + cached predicate forceCachingInSameStage() { any() } + cached newtype TNode = TExprNode(DotNet::Expr e) or @@ -1137,14 +1141,6 @@ module DataFlow { ) } - /** - * Holds if data flows from `nodeFrom` to `nodeTo` in exactly one local - * (intra-procedural) step. - */ - cached predicate localFlowStepCached(Node nodeFrom, Node nodeTo) { - LocalFlow::localFlowStepNonCached(nodeFrom, nodeTo) - } - /** * Holds if `pred` can flow to `succ`, by jumping from one callable to * another. From 74167e478a639d209deab026422d791d4b44799c Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 12 Dec 2018 13:16:28 +0100 Subject: [PATCH 09/69] C#: Cache `NamedElement::getLabel()` --- csharp/ql/src/semmle/code/dotnet/Element.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/src/semmle/code/dotnet/Element.qll b/csharp/ql/src/semmle/code/dotnet/Element.qll index c6d6e7e410c1..739a31ec16bf 100644 --- a/csharp/ql/src/semmle/code/dotnet/Element.qll +++ b/csharp/ql/src/semmle/code/dotnet/Element.qll @@ -80,6 +80,7 @@ class NamedElement extends Element, @dotnet_named_element { } /** Gets a unique string label for this element. */ + cached string getLabel() { none() } /** From 344466a8c16a215a9463823ee3e1827d4a422ae9 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 12 Dec 2018 21:49:21 +0100 Subject: [PATCH 10/69] C#: Cache `DataFlow::Node::getEnclosingCallable()` --- csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll | 1 + 1 file changed, 1 insertion(+) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index dfd7885899c5..6f8acfba723d 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -28,6 +28,7 @@ module DataFlow { DotNet::Type getType() { none() } /** Gets the enclosing callable of this node. */ + cached DotNet::Callable getEnclosingCallable() { none() } /** Gets a textual representation of this node. */ From b155a0f5fb7a50b21c3397d5809f5fb116946ade Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 12 Dec 2018 21:50:34 +0100 Subject: [PATCH 11/69] C#: Avoid computing CIL strings and non-PDB locations in data flow library Computing strings and locations for CIL instructions can be quite time consuming. The CIL `toString()`s are not very helpful in path explanations, and their locations are only useful when a PDB source file exists. Therefore, produce a simple constant `toString()`, and restrict locations to those in PDB files. --- .../src/semmle/code/csharp/dataflow/DataFlow.qll | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll index 6f8acfba723d..96c3ec664ef2 100755 --- a/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/DataFlow.qll @@ -53,9 +53,19 @@ module DataFlow { override DotNet::Callable getEnclosingCallable() { result = expr.getEnclosingCallable() } - override string toString() { result = expr.toString() } + override string toString() { + result = expr.(Expr).toString() + or + expr instanceof CIL::Expr and + result = "CIL expression" + } - override Location getLocation() { result = expr.getLocation() } + override Location getLocation() { + result = expr.(Expr).getLocation() + or + result.getFile().isPdbSourceFile() and + result = expr.(CIL::Expr).getALocation() + } } /** From 7656936cadd1169f33636827d2df9ac6abd2e04d Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Thu, 13 Dec 2018 17:43:26 +0000 Subject: [PATCH 12/69] Java: Remove Metrics/queries.xml --- java/ql/src/Metrics/queries.xml | 1 - 1 file changed, 1 deletion(-) delete mode 100644 java/ql/src/Metrics/queries.xml diff --git a/java/ql/src/Metrics/queries.xml b/java/ql/src/Metrics/queries.xml deleted file mode 100644 index 0d33187fe86a..000000000000 --- a/java/ql/src/Metrics/queries.xml +++ /dev/null @@ -1 +0,0 @@ - From 56b80ae13ae53d7bd29bb6bdf819f37bfe7e5e0e Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 14 Dec 2018 10:13:39 +0000 Subject: [PATCH 13/69] C#: Add `getALocation()` for namespaces and namespace declarations --- csharp/ql/src/semmle/code/csharp/Namespace.qll | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/Namespace.qll b/csharp/ql/src/semmle/code/csharp/Namespace.qll index 94723bf65d07..e8d7a96e6b96 100644 --- a/csharp/ql/src/semmle/code/csharp/Namespace.qll +++ b/csharp/ql/src/semmle/code/csharp/Namespace.qll @@ -112,8 +112,12 @@ class Namespace extends DotNet::Namespace, TypeContainer, @namespace { override predicate fromLibrary() { not this.fromSource() } - /** Gets the URL of this namespace (which is empty in this case). */ - string getURL() { result = "" } + /** Gets a declaration of this namespace, if any. */ + NamespaceDeclaration getADeclaration() { result.getNamespace() = this } + + override Location getALocation() { + result = this.getADeclaration().getALocation() + } } /** @@ -193,7 +197,7 @@ class NamespaceDeclaration extends Element, @namespace_declaration { */ ValueOrRefType getATypeDeclaration() { parent_namespace_declaration(result, this) } - override Location getALocation() { none() } + override Location getALocation() { namespace_declaration_location(this, result) } override string toString() { result = "namespace ... { ... }" } } From 654f2ae290634f859af214a68e8646a5f3f1dbee Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 14 Dec 2018 10:38:34 +0000 Subject: [PATCH 14/69] C#: Address review comment --- .../Entities/Expression.cs | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs index d88050b545bf..d51f438fbcdb 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp/Entities/Expression.cs @@ -117,18 +117,19 @@ public static ExprKind UnaryOperatorKind(Context cx, ExprKind originalKind, Expr public void OperatorCall(ExpressionSyntax node) { var @operator = cx.GetSymbolInfo(node); - var method = @operator.Symbol as IMethodSymbol; - - var callType = GetCallType(cx, node); - if (callType == CallType.Dynamic) + if (@operator.Symbol is IMethodSymbol method) { - UserOperator.OperatorSymbol(method.Name, out string operatorName); - cx.Emit(Tuples.dynamic_member_name(this, operatorName)); - return; - } - if (callType != CallType.None) + var callType = GetCallType(cx, node); + if (callType == CallType.Dynamic) + { + UserOperator.OperatorSymbol(method.Name, out string operatorName); + cx.Emit(Tuples.dynamic_member_name(this, operatorName)); + return; + } + cx.Emit(Tuples.expr_call(this, Method.Create(cx, method))); + } } public enum CallType From 5ccad6ffc206985626cd94669c2804634c805ab1 Mon Sep 17 00:00:00 2001 From: Max Schaefer Date: Fri, 14 Dec 2018 11:56:59 +0000 Subject: [PATCH 15/69] JavaScript: Minor improvements. --- .../ql/src/semmle/javascript/frameworks/Express.qll | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/Express.qll b/javascript/ql/src/semmle/javascript/frameworks/Express.qll index 09ac3cdce2ef..4940dddd2ab9 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Express.qll @@ -851,12 +851,11 @@ module Express { } /** A call to `response.sendFile`, considered as a file system access. */ - private class ResponseSendFileAsFileSystemAccess extends FileSystemReadAccess, DataFlow::ValueNode { - override MethodCallExpr astNode; - + private class ResponseSendFileAsFileSystemAccess extends FileSystemReadAccess, DataFlow::MethodCallNode { ResponseSendFileAsFileSystemAccess() { exists (string name | name = "sendFile" or name = "sendfile" | - asExpr().(MethodCallExpr).calls(any(ResponseExpr res), name)) + calls(any(ResponseExpr res).flow(), name) + ) } override DataFlow::Node getADataNode() { @@ -864,7 +863,7 @@ module Express { } override DataFlow::Node getAPathArgument() { - result = DataFlow::valueNode(astNode.getArgument(0)) + result = getArgument(0) } } From 287ce4e683e6b9615ccc93a05fd3d75c9c9b4c62 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 11 Dec 2018 10:00:12 +0100 Subject: [PATCH 16/69] C#: Add more nullness tests --- csharp/ql/test/query-tests/Nullness/E.cs | 38 +++++++++++++++++++ .../Nullness/EqualityCheck.expected | 4 ++ .../Nullness/Implications.expected | 33 ++++++++++++++++ .../query-tests/Nullness/NullCheck.expected | 6 +++ .../query-tests/Nullness/NullMaybe.expected | 3 ++ 5 files changed, 84 insertions(+) diff --git a/csharp/ql/test/query-tests/Nullness/E.cs b/csharp/ql/test/query-tests/Nullness/E.cs index aebc5138f404..a96029622dad 100644 --- a/csharp/ql/test/query-tests/Nullness/E.cs +++ b/csharp/ql/test/query-tests/Nullness/E.cs @@ -260,6 +260,44 @@ public int Ex21(int? i) i = 0; return i.Value; // GOOD } + + public void Ex22() + { + object o = null; + try + { + o = Make(); + o.ToString(); // GOOD (false positive) + } + finally + { + if (o != null) + o.ToString(); // GOOD + } + } + + public void Ex23(bool b) + { + if (b) + b.ToString(); + var o = Make(); + o?.ToString(); + o.ToString(); // BAD (maybe) + if (b) + b.ToString(); + } + + public void Ex24(bool b) + { + string s = b ? null : ""; + if (s?.M2() == 0) + { + s.ToString(); // GOOD (false positive) + } + } + + public bool Field; + string Make() => Field ? null : ""; } public static class Extensions diff --git a/csharp/ql/test/query-tests/Nullness/EqualityCheck.expected b/csharp/ql/test/query-tests/Nullness/EqualityCheck.expected index d14a8ce95542..61b5f7a61bf5 100644 --- a/csharp/ql/test/query-tests/Nullness/EqualityCheck.expected +++ b/csharp/ql/test/query-tests/Nullness/EqualityCheck.expected @@ -211,6 +211,10 @@ | E.cs:252:13:252:21 | ... != ... | false | E.cs:252:18:252:21 | null | E.cs:252:13:252:13 | access to parameter i | | E.cs:259:13:259:21 | ... == ... | true | E.cs:259:13:259:13 | access to parameter i | E.cs:259:18:259:21 | null | | E.cs:259:13:259:21 | ... == ... | true | E.cs:259:18:259:21 | null | E.cs:259:13:259:13 | access to parameter i | +| E.cs:274:17:274:25 | ... != ... | false | E.cs:274:17:274:17 | access to local variable o | E.cs:274:22:274:25 | null | +| E.cs:274:17:274:25 | ... != ... | false | E.cs:274:22:274:25 | null | E.cs:274:17:274:17 | access to local variable o | +| E.cs:293:13:293:24 | ... == ... | true | E.cs:293:15:293:19 | call to method M2 | E.cs:293:24:293:24 | (...) ... | +| E.cs:293:13:293:24 | ... == ... | true | E.cs:293:24:293:24 | (...) ... | E.cs:293:15:293:19 | call to method M2 | | Forwarding.cs:59:13:59:21 | ... == ... | true | Forwarding.cs:59:13:59:13 | access to parameter o | Forwarding.cs:59:18:59:21 | null | | Forwarding.cs:59:13:59:21 | ... == ... | true | Forwarding.cs:59:18:59:21 | null | Forwarding.cs:59:13:59:13 | access to parameter o | | Forwarding.cs:78:16:78:39 | call to method ReferenceEquals | true | Forwarding.cs:78:32:78:32 | access to parameter o | Forwarding.cs:78:35:78:38 | null | diff --git a/csharp/ql/test/query-tests/Nullness/Implications.expected b/csharp/ql/test/query-tests/Nullness/Implications.expected index 0ceb07b87bf4..6767c7453fcc 100644 --- a/csharp/ql/test/query-tests/Nullness/Implications.expected +++ b/csharp/ql/test/query-tests/Nullness/Implications.expected @@ -1426,6 +1426,39 @@ | E.cs:260:13:260:17 | ... = ... | non-null | E.cs:260:17:260:17 | (...) ... | non-null | | E.cs:260:13:260:17 | ... = ... | null | E.cs:260:13:260:13 | access to parameter i | null | | E.cs:260:13:260:17 | ... = ... | null | E.cs:260:17:260:17 | (...) ... | null | +| E.cs:266:16:266:23 | Object o = ... | non-null | E.cs:266:16:266:16 | access to local variable o | non-null | +| E.cs:266:16:266:23 | Object o = ... | null | E.cs:266:16:266:16 | access to local variable o | null | +| E.cs:269:13:269:22 | ... = ... | non-null | E.cs:269:13:269:13 | access to local variable o | non-null | +| E.cs:269:13:269:22 | ... = ... | non-null | E.cs:269:17:269:22 | call to method Make | non-null | +| E.cs:269:13:269:22 | ... = ... | null | E.cs:269:13:269:13 | access to local variable o | null | +| E.cs:269:13:269:22 | ... = ... | null | E.cs:269:17:269:22 | call to method Make | null | +| E.cs:270:13:270:13 | access to local variable o | non-null | E.cs:269:17:269:22 | call to method Make | non-null | +| E.cs:270:13:270:13 | access to local variable o | null | E.cs:269:17:269:22 | call to method Make | null | +| E.cs:274:17:274:25 | ... != ... | false | E.cs:274:17:274:17 | access to local variable o | null | +| E.cs:274:17:274:25 | ... != ... | true | E.cs:274:17:274:17 | access to local variable o | non-null | +| E.cs:283:13:283:22 | String o = ... | non-null | E.cs:283:13:283:13 | access to local variable o | non-null | +| E.cs:283:13:283:22 | String o = ... | null | E.cs:283:13:283:13 | access to local variable o | null | +| E.cs:284:9:284:9 | access to local variable o | non-null | E.cs:283:17:283:22 | call to method Make | non-null | +| E.cs:284:9:284:9 | access to local variable o | null | E.cs:283:17:283:22 | call to method Make | null | +| E.cs:284:11:284:21 | call to method ToString | non-null | E.cs:284:9:284:9 | access to local variable o | non-null | +| E.cs:285:9:285:9 | access to local variable o | non-null | E.cs:283:17:283:22 | call to method Make | non-null | +| E.cs:285:9:285:9 | access to local variable o | null | E.cs:283:17:283:22 | call to method Make | null | +| E.cs:292:16:292:32 | String s = ... | non-null | E.cs:292:16:292:16 | access to local variable s | non-null | +| E.cs:292:16:292:32 | String s = ... | null | E.cs:292:16:292:16 | access to local variable s | null | +| E.cs:292:20:292:32 | ... ? ... : ... | non-null | E.cs:292:20:292:20 | access to parameter b | false | +| E.cs:292:20:292:32 | ... ? ... : ... | non-null | E.cs:292:31:292:32 | "" | non-null | +| E.cs:292:20:292:32 | ... ? ... : ... | null | E.cs:292:20:292:20 | access to parameter b | true | +| E.cs:292:20:292:32 | ... ? ... : ... | null | E.cs:292:24:292:27 | null | null | +| E.cs:293:13:293:13 | access to local variable s | non-null | E.cs:292:20:292:20 | access to parameter b | false | +| E.cs:293:13:293:13 | access to local variable s | non-null | E.cs:292:20:292:32 | ... ? ... : ... | non-null | +| E.cs:293:13:293:13 | access to local variable s | null | E.cs:292:20:292:20 | access to parameter b | true | +| E.cs:293:13:293:13 | access to local variable s | null | E.cs:292:20:292:32 | ... ? ... : ... | null | +| E.cs:295:13:295:13 | access to local variable s | non-null | E.cs:292:20:292:32 | ... ? ... : ... | non-null | +| E.cs:295:13:295:13 | access to local variable s | null | E.cs:292:20:292:32 | ... ? ... : ... | null | +| E.cs:300:22:300:38 | ... ? ... : ... | non-null | E.cs:300:22:300:26 | access to field Field | false | +| E.cs:300:22:300:38 | ... ? ... : ... | non-null | E.cs:300:37:300:38 | "" | non-null | +| E.cs:300:22:300:38 | ... ? ... : ... | null | E.cs:300:22:300:26 | access to field Field | true | +| E.cs:300:22:300:38 | ... ? ... : ... | null | E.cs:300:30:300:33 | null | null | | Forwarding.cs:7:16:7:23 | String s = ... | non-null | Forwarding.cs:7:16:7:16 | access to local variable s | non-null | | Forwarding.cs:7:16:7:23 | String s = ... | null | Forwarding.cs:7:16:7:16 | access to local variable s | null | | Forwarding.cs:9:13:9:30 | !... | false | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | true | diff --git a/csharp/ql/test/query-tests/Nullness/NullCheck.expected b/csharp/ql/test/query-tests/Nullness/NullCheck.expected index 9b93a84e2282..6047334692a7 100644 --- a/csharp/ql/test/query-tests/Nullness/NullCheck.expected +++ b/csharp/ql/test/query-tests/Nullness/NullCheck.expected @@ -193,6 +193,12 @@ | E.cs:252:13:252:21 | ... != ... | E.cs:252:13:252:13 | access to parameter i | true | false | | E.cs:259:13:259:21 | ... == ... | E.cs:259:13:259:13 | access to parameter i | false | false | | E.cs:259:13:259:21 | ... == ... | E.cs:259:13:259:13 | access to parameter i | true | true | +| E.cs:274:17:274:25 | ... != ... | E.cs:274:17:274:17 | access to local variable o | false | true | +| E.cs:274:17:274:25 | ... != ... | E.cs:274:17:274:17 | access to local variable o | true | false | +| E.cs:284:9:284:9 | access to local variable o | E.cs:284:9:284:9 | access to local variable o | non-null | false | +| E.cs:284:9:284:9 | access to local variable o | E.cs:284:9:284:9 | access to local variable o | null | true | +| E.cs:293:13:293:13 | access to local variable s | E.cs:293:13:293:13 | access to local variable s | non-null | false | +| E.cs:293:13:293:13 | access to local variable s | E.cs:293:13:293:13 | access to local variable s | null | true | | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | Forwarding.cs:9:14:9:14 | access to local variable s | false | false | | Forwarding.cs:14:13:14:32 | call to method IsNotNullOrEmpty | Forwarding.cs:14:13:14:13 | access to local variable s | true | false | | Forwarding.cs:19:14:19:23 | call to method IsNull | Forwarding.cs:19:14:19:14 | access to local variable s | false | false | diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected index b0b000287cb4..4edb9f3ded5c 100644 --- a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected +++ b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected @@ -68,6 +68,9 @@ | E.cs:230:9:230:9 | access to local variable x | Variable $@ may be null here because of $@ assignment. | E.cs:225:13:225:13 | x | x | E.cs:227:13:227:20 | ... = ... | this | | E.cs:235:16:235:16 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:233:26:233:26 | i | i | E.cs:233:26:233:26 | i | this | | E.cs:240:21:240:21 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:238:26:238:26 | i | i | E.cs:238:26:238:26 | i | this | +| E.cs:270:13:270:13 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:266:16:266:16 | o | o | E.cs:274:17:274:25 | ... != ... | this | +| E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this | +| E.cs:295:13:295:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | E.cs:292:16:292:16 | s | s | E.cs:292:16:292:32 | String s = ... | this | | GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null here because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this | | NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null here because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this | | StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this | From 078dc7b6c06c27fc63ead0965b91b317c0bba2ff Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 11 Dec 2018 10:00:42 +0100 Subject: [PATCH 17/69] C#: Fix false positives in `cs/dereferenced-value-may-be-null` --- csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll | 6 +++++- csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll | 3 +++ csharp/ql/test/query-tests/Nullness/E.cs | 4 ++-- csharp/ql/test/query-tests/Nullness/Implications.expected | 3 +++ csharp/ql/test/query-tests/Nullness/NullCheck.expected | 1 + csharp/ql/test/query-tests/Nullness/NullMaybe.expected | 2 -- 6 files changed, 14 insertions(+), 5 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll index 1a8a097f6cb3..7e8e83c1be9c 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll @@ -578,8 +578,12 @@ module Internal { */ Expr getNullEquivParent(Expr e) { result = any(QualifiableExpr qe | - qe.getQualifier() = e and qe.isConditional() and + ( + e = qe.getQualifier() + or + e = qe.(ExtensionMethodCall).getArgument(0) + ) and ( // The accessed declaration must have a value type in order // for `only if` to hold diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll b/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll index 5f0f7932b90a..b1cdeae03bec 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll @@ -155,6 +155,9 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) reason = de.getANullCheck(_, true) and msg = "as suggested by $@ null check" and not def instanceof Ssa::PseudoDefinition and + strictcount(Location l | + l = any(Ssa::Definition def0 | de = def0.getARead()).getLocation() + ) = 1 and not nonNullDef(def) and // Don't use a check as reason if there is a `null` assignment not def.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof MaybeNullExpr diff --git a/csharp/ql/test/query-tests/Nullness/E.cs b/csharp/ql/test/query-tests/Nullness/E.cs index a96029622dad..6be4074be02f 100644 --- a/csharp/ql/test/query-tests/Nullness/E.cs +++ b/csharp/ql/test/query-tests/Nullness/E.cs @@ -267,7 +267,7 @@ public void Ex22() try { o = Make(); - o.ToString(); // GOOD (false positive) + o.ToString(); // GOOD } finally { @@ -292,7 +292,7 @@ public void Ex24(bool b) string s = b ? null : ""; if (s?.M2() == 0) { - s.ToString(); // GOOD (false positive) + s.ToString(); // GOOD } } diff --git a/csharp/ql/test/query-tests/Nullness/Implications.expected b/csharp/ql/test/query-tests/Nullness/Implications.expected index 6767c7453fcc..49c854bc4216 100644 --- a/csharp/ql/test/query-tests/Nullness/Implications.expected +++ b/csharp/ql/test/query-tests/Nullness/Implications.expected @@ -1453,6 +1453,9 @@ | E.cs:293:13:293:13 | access to local variable s | non-null | E.cs:292:20:292:32 | ... ? ... : ... | non-null | | E.cs:293:13:293:13 | access to local variable s | null | E.cs:292:20:292:20 | access to parameter b | true | | E.cs:293:13:293:13 | access to local variable s | null | E.cs:292:20:292:32 | ... ? ... : ... | null | +| E.cs:293:13:293:24 | ... == ... | true | E.cs:293:15:293:19 | call to method M2 | non-null | +| E.cs:293:15:293:19 | call to method M2 | non-null | E.cs:293:13:293:13 | access to local variable s | non-null | +| E.cs:293:15:293:19 | call to method M2 | null | E.cs:293:13:293:13 | access to local variable s | null | | E.cs:295:13:295:13 | access to local variable s | non-null | E.cs:292:20:292:32 | ... ? ... : ... | non-null | | E.cs:295:13:295:13 | access to local variable s | null | E.cs:292:20:292:32 | ... ? ... : ... | null | | E.cs:300:22:300:38 | ... ? ... : ... | non-null | E.cs:300:22:300:26 | access to field Field | false | diff --git a/csharp/ql/test/query-tests/Nullness/NullCheck.expected b/csharp/ql/test/query-tests/Nullness/NullCheck.expected index 6047334692a7..966c9fa5464e 100644 --- a/csharp/ql/test/query-tests/Nullness/NullCheck.expected +++ b/csharp/ql/test/query-tests/Nullness/NullCheck.expected @@ -199,6 +199,7 @@ | E.cs:284:9:284:9 | access to local variable o | E.cs:284:9:284:9 | access to local variable o | null | true | | E.cs:293:13:293:13 | access to local variable s | E.cs:293:13:293:13 | access to local variable s | non-null | false | | E.cs:293:13:293:13 | access to local variable s | E.cs:293:13:293:13 | access to local variable s | null | true | +| E.cs:293:13:293:24 | ... == ... | E.cs:293:15:293:19 | call to method M2 | true | false | | Forwarding.cs:9:14:9:30 | call to method IsNullOrEmpty | Forwarding.cs:9:14:9:14 | access to local variable s | false | false | | Forwarding.cs:14:13:14:32 | call to method IsNotNullOrEmpty | Forwarding.cs:14:13:14:13 | access to local variable s | true | false | | Forwarding.cs:19:14:19:23 | call to method IsNull | Forwarding.cs:19:14:19:14 | access to local variable s | false | false | diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected index 4edb9f3ded5c..3c28cc8a951b 100644 --- a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected +++ b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected @@ -68,9 +68,7 @@ | E.cs:230:9:230:9 | access to local variable x | Variable $@ may be null here because of $@ assignment. | E.cs:225:13:225:13 | x | x | E.cs:227:13:227:20 | ... = ... | this | | E.cs:235:16:235:16 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:233:26:233:26 | i | i | E.cs:233:26:233:26 | i | this | | E.cs:240:21:240:21 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:238:26:238:26 | i | i | E.cs:238:26:238:26 | i | this | -| E.cs:270:13:270:13 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:266:16:266:16 | o | o | E.cs:274:17:274:25 | ... != ... | this | | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this | -| E.cs:295:13:295:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | E.cs:292:16:292:16 | s | s | E.cs:292:16:292:32 | String s = ... | this | | GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null here because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this | | NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null here because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this | | StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this | From e2f271bddbb2df22d0480550b827219f85d9e713 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 5 Dec 2018 15:14:36 +0100 Subject: [PATCH 18/69] C#: Add more guard implication steps --- .../semmle/code/csharp/controlflow/Guards.qll | 50 +++++++++++++++++-- .../controlflow/guards/Implications.expected | 8 +++ .../Nullness/Implications.expected | 10 ++++ 3 files changed, 65 insertions(+), 3 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll index 7e8e83c1be9c..e1d8e8e02a5f 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/Guards.qll @@ -694,7 +694,7 @@ module Internal { predicate preControls(PreBasicBlocks::PreBasicBlock bb, AbstractValue v) { exists(AbstractValue v0, Guard g | g.preControlsDirect(bb, v0) | - impliesSteps(g, v0, this, v) + preImpliesSteps(g, v0, this, v) ) } @@ -781,7 +781,7 @@ module Internal { def.nullGuardedReturn(ret, isNull) or exists(NullValue nv | - impliesSteps(ret, retVal, def.getARead(), nv) | + preImpliesSteps(ret, retVal, def.getARead(), nv) | if nv.isNull() then isNull = true else isNull = false ) ) @@ -1123,6 +1123,28 @@ module Internal { def = guarded.getAnSsaQualifier() ) } + + /** + * Holds if the assumption that `g1` has abstract value `v1` implies that + * `g2` has abstract value `v2`, using one step of reasoning. That is, the + * evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`. + * + * This predicate relies on the control flow graph. + */ + cached + predicate impliesStep(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) { + preImpliesStep(g1, v1, g2, v2) + or + forex(ControlFlow::Node cfn | + cfn = g1.getAControlFlowNode() | + exists(Ssa::ExplicitDefinition def | + def.getADefinition().getSource() = g2 | + g1 = def.getAReadAtNode(cfn) and + v1 = g1.getAValue() and + v2 = v1 + ) + ) + } } import Cached @@ -1143,9 +1165,11 @@ module Internal { * Holds if the assumption that `g1` has abstract value `v1` implies that * `g2` has abstract value `v2`, using one step of reasoning. That is, the * evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`. + * + * This predicate does not rely on the control flow graph. */ cached - predicate impliesStep(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) { + predicate preImpliesStep(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) { g1 = any(BinaryOperation bo | ( bo instanceof BitwiseAndExpr or @@ -1279,6 +1303,26 @@ module Internal { * Holds if the assumption that `g1` has abstract value `v1` implies that * `g2` has abstract value `v2`, using zero or more steps of reasoning. That is, * the evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`. + * + * This predicate does not rely on the control flow graph. + */ + predicate preImpliesSteps(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) { + g1 = g2 and + v1 = v2 and + v1 = g1.getAValue() + or + exists(Expr mid, AbstractValue vMid | + preImpliesSteps(g1, v1, mid, vMid) | + preImpliesStep(mid, vMid, g2, v2) + ) + } + + /** + * Holds if the assumption that `g1` has abstract value `v1` implies that + * `g2` has abstract value `v2`, using zero or more steps of reasoning. That is, + * the evaluation of `g2` to `v2` dominates the evaluation of `g1` to `v1`. + * + * This predicate relies on the control flow graph. */ predicate impliesSteps(Guard g1, AbstractValue v1, Guard g2, AbstractValue v2) { g1 = g2 and diff --git a/csharp/ql/test/library-tests/controlflow/guards/Implications.expected b/csharp/ql/test/library-tests/controlflow/guards/Implications.expected index 7e78c7d7198c..67de6b196c59 100644 --- a/csharp/ql/test/library-tests/controlflow/guards/Implications.expected +++ b/csharp/ql/test/library-tests/controlflow/guards/Implications.expected @@ -251,6 +251,10 @@ | Guards.cs:106:9:106:25 | ... = ... | non-null | Guards.cs:106:22:106:25 | null | non-null | | Guards.cs:106:9:106:25 | ... = ... | null | Guards.cs:106:9:106:18 | access to property Property | null | | Guards.cs:106:9:106:25 | ... = ... | null | Guards.cs:106:22:106:25 | null | null | +| Guards.cs:107:27:107:36 | access to property Property | non-null | Guards.cs:106:22:106:25 | null | non-null | +| Guards.cs:107:27:107:36 | access to property Property | null | Guards.cs:106:22:106:25 | null | null | +| Guards.cs:108:27:108:36 | access to property Property | non-null | Guards.cs:106:22:106:25 | null | non-null | +| Guards.cs:108:27:108:36 | access to property Property | null | Guards.cs:106:22:106:25 | null | null | | Guards.cs:113:13:114:38 | String dummy = ... | non-null | Guards.cs:113:13:113:17 | access to local variable dummy | non-null | | Guards.cs:113:13:114:38 | String dummy = ... | null | Guards.cs:113:13:113:17 | access to local variable dummy | null | | Guards.cs:115:9:115:55 | ... = ... | non-null | Guards.cs:115:9:115:13 | access to local variable dummy | non-null | @@ -261,6 +265,10 @@ | Guards.cs:117:9:117:25 | ... = ... | non-null | Guards.cs:117:22:117:25 | null | non-null | | Guards.cs:117:9:117:25 | ... = ... | null | Guards.cs:117:9:117:18 | access to property Property | null | | Guards.cs:117:9:117:25 | ... = ... | null | Guards.cs:117:22:117:25 | null | null | +| Guards.cs:118:27:118:36 | access to property Property | non-null | Guards.cs:117:22:117:25 | null | non-null | +| Guards.cs:118:27:118:36 | access to property Property | null | Guards.cs:117:22:117:25 | null | null | +| Guards.cs:119:27:119:36 | access to property Property | non-null | Guards.cs:117:22:117:25 | null | non-null | +| Guards.cs:119:27:119:36 | access to property Property | null | Guards.cs:117:22:117:25 | null | null | | Guards.cs:124:13:124:30 | Boolean b1 = ... | false | Guards.cs:124:13:124:14 | access to local variable b1 | false | | Guards.cs:124:13:124:30 | Boolean b1 = ... | true | Guards.cs:124:13:124:14 | access to local variable b1 | true | | Guards.cs:125:13:125:31 | Nullable b2 = ... | non-null | Guards.cs:125:13:125:14 | access to local variable b2 | non-null | diff --git a/csharp/ql/test/query-tests/Nullness/Implications.expected b/csharp/ql/test/query-tests/Nullness/Implications.expected index 49c854bc4216..aef55ff476c6 100644 --- a/csharp/ql/test/query-tests/Nullness/Implications.expected +++ b/csharp/ql/test/query-tests/Nullness/Implications.expected @@ -930,6 +930,8 @@ | D.cs:187:13:187:28 | ... = ... | non-null | D.cs:187:20:187:28 | call to method MkMaybe | non-null | | D.cs:187:13:187:28 | ... = ... | null | D.cs:187:13:187:16 | access to local variable obj3 | null | | D.cs:187:13:187:28 | ... = ... | null | D.cs:187:20:187:28 | call to method MkMaybe | null | +| D.cs:190:9:190:12 | access to local variable obj3 | non-null | D.cs:187:20:187:28 | call to method MkMaybe | non-null | +| D.cs:190:9:190:12 | access to local variable obj3 | null | D.cs:187:20:187:28 | call to method MkMaybe | null | | D.cs:195:13:195:28 | Object o = ... | non-null | D.cs:195:13:195:13 | access to local variable o | non-null | | D.cs:195:13:195:28 | Object o = ... | null | D.cs:195:13:195:13 | access to local variable o | null | | D.cs:196:13:196:13 | access to local variable o | non-null | D.cs:195:17:195:28 | object creation of type Object | non-null | @@ -985,6 +987,8 @@ | D.cs:230:13:230:28 | ... = ... | non-null | D.cs:230:17:230:28 | object creation of type Object | non-null | | D.cs:230:13:230:28 | ... = ... | null | D.cs:230:13:230:13 | access to local variable o | null | | D.cs:230:13:230:28 | ... = ... | null | D.cs:230:17:230:28 | object creation of type Object | null | +| D.cs:232:13:232:13 | access to local variable o | non-null | D.cs:230:17:230:28 | object creation of type Object | non-null | +| D.cs:232:13:232:13 | access to local variable o | null | D.cs:230:17:230:28 | object creation of type Object | null | | D.cs:234:9:234:16 | ... = ... | non-null | D.cs:234:9:234:9 | access to local variable o | non-null | | D.cs:234:9:234:16 | ... = ... | non-null | D.cs:234:13:234:16 | null | non-null | | D.cs:234:9:234:16 | ... = ... | null | D.cs:234:9:234:9 | access to local variable o | null | @@ -993,6 +997,8 @@ | D.cs:236:13:236:18 | ... = ... | non-null | D.cs:236:17:236:18 | "" | non-null | | D.cs:236:13:236:18 | ... = ... | null | D.cs:236:13:236:13 | access to local variable o | null | | D.cs:236:13:236:18 | ... = ... | null | D.cs:236:17:236:18 | "" | null | +| D.cs:238:13:238:13 | access to local variable o | non-null | D.cs:236:17:236:18 | "" | non-null | +| D.cs:238:13:238:13 | access to local variable o | null | D.cs:236:17:236:18 | "" | null | | D.cs:240:9:240:16 | ... = ... | non-null | D.cs:240:9:240:9 | access to local variable o | non-null | | D.cs:240:9:240:16 | ... = ... | non-null | D.cs:240:13:240:16 | null | non-null | | D.cs:240:9:240:16 | ... = ... | null | D.cs:240:9:240:9 | access to local variable o | null | @@ -1410,12 +1416,16 @@ | E.cs:217:13:217:20 | ... = ... | non-null | E.cs:217:17:217:20 | null | non-null | | E.cs:217:13:217:20 | ... = ... | null | E.cs:217:13:217:13 | access to local variable x | null | | E.cs:217:13:217:20 | ... = ... | null | E.cs:217:17:217:20 | null | null | +| E.cs:220:13:220:13 | access to local variable x | non-null | E.cs:217:17:217:20 | null | non-null | +| E.cs:220:13:220:13 | access to local variable x | null | E.cs:217:17:217:20 | null | null | | E.cs:225:13:225:18 | String x = ... | non-null | E.cs:225:13:225:13 | access to local variable x | non-null | | E.cs:225:13:225:18 | String x = ... | null | E.cs:225:13:225:13 | access to local variable x | null | | E.cs:227:13:227:20 | ... = ... | non-null | E.cs:227:13:227:13 | access to local variable x | non-null | | E.cs:227:13:227:20 | ... = ... | non-null | E.cs:227:17:227:20 | null | non-null | | E.cs:227:13:227:20 | ... = ... | null | E.cs:227:13:227:13 | access to local variable x | null | | E.cs:227:13:227:20 | ... = ... | null | E.cs:227:17:227:20 | null | null | +| E.cs:229:13:229:13 | access to local variable x | non-null | E.cs:227:17:227:20 | null | non-null | +| E.cs:229:13:229:13 | access to local variable x | null | E.cs:227:17:227:20 | null | null | | E.cs:245:13:245:22 | access to property HasValue | false | E.cs:245:13:245:13 | access to parameter i | null | | E.cs:245:13:245:22 | access to property HasValue | true | E.cs:245:13:245:13 | access to parameter i | non-null | | E.cs:252:13:252:21 | ... != ... | false | E.cs:252:13:252:13 | access to parameter i | null | From 91e4f7ad83b3d7d8a7bb225a1b316829cfe19731 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 5 Dec 2018 16:26:24 +0100 Subject: [PATCH 19/69] C#: Make `cs/dereferenced-value-may-be-null` a path query --- csharp/ql/src/CSI/NullMaybe.ql | 9 +- .../semmle/code/csharp/dataflow/Nullness.qll | 227 ++++- .../src/semmle/code/csharp/dataflow/SSA.qll | 3 + .../query-tests/Nullness/NullMaybe.expected | 853 ++++++++++++++++-- 4 files changed, 972 insertions(+), 120 deletions(-) diff --git a/csharp/ql/src/CSI/NullMaybe.ql b/csharp/ql/src/CSI/NullMaybe.ql index eaacd7fa3dab..7bd099e78e92 100644 --- a/csharp/ql/src/CSI/NullMaybe.ql +++ b/csharp/ql/src/CSI/NullMaybe.ql @@ -2,7 +2,7 @@ * @name Dereferenced variable may be null * @description Dereferencing a variable whose value may be 'null' may cause a * 'NullReferenceException'. - * @kind problem + * @kind path-problem * @problem.severity warning * @precision high * @id cs/dereferenced-value-may-be-null @@ -14,7 +14,8 @@ import csharp import semmle.code.csharp.dataflow.Nullness +import PathGraph -from Dereference d, Ssa::SourceVariable v, string msg, Element reason -where d.isFirstMaybeNull(v.getAnSsaDefinition(), msg, reason) -select d, "Variable $@ may be null here " + msg + ".", v, v.toString(), reason, "this" +from Dereference d, PathNode source, PathNode sink, Ssa::SourceVariable v, string msg, Element reason +where d.isFirstMaybeNull(v.getAnSsaDefinition(), source, sink, msg, reason) +select d, source, sink, "Variable $@ may be null here " + msg + ".", v, v.toString(), reason, "this" diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll b/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll index b1cdeae03bec..c5a662ccb56f 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/Nullness.qll @@ -147,6 +147,15 @@ private ControlFlowElement getANullCheck(Ssa::Definition def, SuccessorTypes::Co ) } +private predicate isMaybeNullArgument(Ssa::ExplicitDefinition def, MaybeNullExpr arg) { + exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p | + pdef = def.getADefinition() | + p = pdef.getParameter().getSourceDeclaration() and + p.getAnAssignedArgument() = arg and + not arg.getEnclosingCallable().getEnclosingCallable*() instanceof TestMethod + ) +} + /** Holds if `def` is an SSA definition that may be `null`. */ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) { // A variable compared to `null` might be `null` @@ -160,18 +169,14 @@ private predicate defMaybeNull(Ssa::Definition def, string msg, Element reason) ) = 1 and not nonNullDef(def) and // Don't use a check as reason if there is a `null` assignment - not def.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof MaybeNullExpr + // or argument + not def.(Ssa::ExplicitDefinition).getADefinition().getSource() instanceof MaybeNullExpr and + not isMaybeNullArgument(def, _) ) or // A parameter might be `null` if there is a `null` argument somewhere - exists(AssignableDefinitions::ImplicitParameterDefinition pdef, Parameter p, MaybeNullExpr arg | - pdef = def.(Ssa::ExplicitDefinition).getADefinition() | - p = pdef.getParameter().getSourceDeclaration() and - p.getAnAssignedArgument() = arg and - reason = arg and - msg = "because of $@ null argument" and - not arg.getEnclosingCallable().getEnclosingCallable*() instanceof TestMethod - ) + isMaybeNullArgument(def, reason) and + msg = "because of $@ null argument" or // If the source of a variable is `null` then the variable may be `null` exists(AssignableDefinition adef | @@ -202,12 +207,12 @@ private predicate defNullImpliesStep(Ssa::Definition def1, BasicBlock bb1, Ssa:: def1.getSourceVariable() = v | def2.(Ssa::PseudoDefinition).getAnInput() = def1 and - def2.definesAt(bb2, _) + bb2 = def2.getBasicBlock() or def2 = def1 and not exists(Ssa::PseudoDefinition def | def.getSourceVariable() = v and - def.definesAt(bb2, _) + bb2 = def.getBasicBlock() ) ) and def1.isLiveAtEndOfBlock(bb1) and @@ -224,13 +229,12 @@ private predicate defNullImpliesStep(Ssa::Definition def1, BasicBlock bb1, Ssa:: * The transitive closure of `defNullImpliesStep()` originating from `defMaybeNull()`. * That is, those basic blocks for which the SSA definition is suspected of being `null`. */ -private predicate defMaybeNullInBlock(Ssa::Definition def, Ssa::SourceVariable v, BasicBlock bb) { +private predicate defMaybeNullInBlock(Ssa::Definition def, BasicBlock bb) { defMaybeNull(def, _, _) and - def.definesAt(bb, _) and - v = def.getSourceVariable() + bb = def.getBasicBlock() or exists(BasicBlock mid, Ssa::Definition midDef | - defMaybeNullInBlock(midDef, v, mid) | + defMaybeNullInBlock(midDef, mid) | defNullImpliesStep(midDef, mid, def, bb) ) } @@ -242,20 +246,167 @@ private predicate defMaybeNullInBlock(Ssa::Definition def, Ssa::SourceVariable v private predicate nullDerefCandidateVariable(Ssa::SourceVariable v) { exists(Ssa::Definition def, BasicBlock bb | potentialNullDereferenceAt(bb, _, def, _) | - defMaybeNullInBlock(def, v, bb) + defMaybeNullInBlock(def, bb) and + v = def.getSourceVariable() ) } -private predicate defMaybeNullInBlockOrigin(Ssa::Definition origin, Ssa::Definition def, BasicBlock bb) { - nullDerefCandidateVariable(def.getSourceVariable()) and - defMaybeNull(def, _, _) and - def.definesAt(bb, _) and - origin = def +private predicate succStep(PathNode pred, Ssa::Definition def, BasicBlock bb) { + defNullImpliesStep(pred.getSsaDefinition(), pred.getBasicBlock(), def, bb) +} + +private predicate succNullArgument(SourcePathNode pred, Ssa::Definition def, BasicBlock bb) { + pred = TSourcePathNode(def, _, _, true) and + bb = def.getBasicBlock() +} + +private predicate succSourceSink(SourcePathNode source, Ssa::Definition def, BasicBlock bb) { + source = TSourcePathNode(def, _, _, false) and + bb = def.getBasicBlock() +} + +private newtype TPathNode = + TSourcePathNode(Ssa::Definition def, string msg, Element reason, boolean isNullArgument) { + nullDerefCandidateVariable(def.getSourceVariable()) and + defMaybeNull(def, msg, reason) and + if isMaybeNullArgument(def, reason) then isNullArgument = true else isNullArgument = false + } or - exists(BasicBlock mid, Ssa::Definition midDef | - defMaybeNullInBlockOrigin(origin, midDef, mid) and - defNullImpliesStep(midDef, mid, def, bb) - ) + TInternalPathNode(Ssa::Definition def, BasicBlock bb) { + succStep(_, def, bb) + or + succNullArgument(_, def, bb) + } + or + TSinkPathNode(Ssa::Definition def, BasicBlock bb, int i, Dereference d) { + potentialNullDereferenceAt(bb, i, def, d) and + ( + succStep(_, def, bb) + or + succNullArgument(_, def, bb) + or + succSourceSink(_, def, bb) + ) + } + +/** + * An SSA definition, which may be `null`, augmented with at basic block which can + * be reached without passing through a `null` check. + */ +abstract class PathNode extends TPathNode { + /** Gets the SSA definition. */ + abstract Ssa::Definition getSsaDefinition(); + + /** Gets the basic block that can be reached without passing through a `null` check. */ + abstract BasicBlock getBasicBlock(); + + /** Gets another node that can be reached from this node. */ + abstract PathNode getASuccessor(); + + /** Gets a textual representation of this node. */ + abstract string toString(); + + /** Gets the location of this node. */ + abstract Location getLocation(); +} + +private class SourcePathNode extends PathNode, TSourcePathNode { + private Ssa::Definition def; + private string msg; + private Element reason; + private boolean isNullArgument; + + SourcePathNode() { this = TSourcePathNode(def, msg, reason, isNullArgument) } + + override Ssa::Definition getSsaDefinition() { result = def } + + override BasicBlock getBasicBlock() { + isNullArgument = false and + result = def.getBasicBlock() + } + + string getMessage() { result = msg } + + Element getReason() { result = reason } + + override PathNode getASuccessor() { + succStep(this, result.getSsaDefinition(), result.getBasicBlock()) + or + succNullArgument(this, result.getSsaDefinition(), result.getBasicBlock()) + or + result instanceof SinkPathNode and + succSourceSink(this, result.getSsaDefinition(), result.getBasicBlock()) + } + + override string toString() { + if isNullArgument = true then + result = reason.toString() + else + result = def.toString() + } + + override Location getLocation() { + if isNullArgument = true then + result = reason.getLocation() + else + result = def.getLocation() + } +} + +private class InternalPathNode extends PathNode, TInternalPathNode { + private Ssa::Definition def; + private BasicBlock bb; + + InternalPathNode() { this = TInternalPathNode(def, bb) } + + override Ssa::Definition getSsaDefinition() { result = def } + + override BasicBlock getBasicBlock() { result = bb } + + override PathNode getASuccessor() { + succStep(this, result.getSsaDefinition(), result.getBasicBlock()) + } + + override string toString() { result = bb.getFirstNode().toString() } + + override Location getLocation() { result = bb.getFirstNode().getLocation() } +} + +private class SinkPathNode extends PathNode, TSinkPathNode { + private Ssa::Definition def; + private BasicBlock bb; + private int i; + private Dereference d; + + SinkPathNode() { this = TSinkPathNode(def, bb, i, d) } + + override Ssa::Definition getSsaDefinition() { result = def } + + override BasicBlock getBasicBlock() { result = bb } + + override PathNode getASuccessor() { none() } + + Dereference getDereference() { result = d } + + override string toString() { result = d.toString() } + + override Location getLocation() { result = d.getLocation() } +} + +/** + * Provides the query predicates needed to include a graph in a path-problem query + * for `Dereference::is[First]MaybeNull()`. + */ +module PathGraph { + query predicate nodes(PathNode n) { + n.getASuccessor*() instanceof SinkPathNode + } + + query predicate edges(PathNode pred, PathNode succ) { + nodes(pred) and + nodes(succ) and + succ = pred.getASuccessor() + } } private Ssa::Definition getAPseudoInput(Ssa::Definition def) { @@ -282,7 +433,7 @@ private predicate defReaches(Ssa::Definition def, AssignableRead ar, boolean alw defReaches(def, mid, always) | ar = mid.getANextRead() and not mid = any(Dereference d | - if always = true then d.isAlwaysNull(def.getSourceVariable()) else d.isMaybeNull(def, _, _) + if always = true then d.isAlwaysNull(def.getSourceVariable()) else d.isMaybeNull(def, _, _, _, _) ) ) } @@ -378,24 +529,16 @@ class Dereference extends G::DereferenceableExpr { defReaches(v.getAnSsaDefinition(), this, true) } - pragma[noinline] - private predicate nullDerefCandidate(Ssa::Definition origin) { - exists(Ssa::Definition ssa, BasicBlock bb | - potentialNullDereferenceAt(bb, _, ssa, this) | - defMaybeNullInBlockOrigin(origin, ssa, bb) - ) - } - /** * Holds if this expression dereferences SSA definition `def`, which may * be `null`. */ - predicate isMaybeNull(Ssa::Definition def, string msg, Element reason) { - exists(Ssa::Definition origin, BasicBlock bb | - this.nullDerefCandidate(origin) and - defMaybeNull(origin, msg, reason) and - potentialNullDereferenceAt(bb, _, def, this) - ) and + predicate isMaybeNull(Ssa::Definition def, SourcePathNode source, SinkPathNode sink, string msg, Element reason) { + source.getASuccessor*() = sink and + msg = source.getMessage() and + reason = source.getReason() and + def = sink.getSsaDefinition() and + this = sink.getDereference() and not this.isAlwaysNull(def.getSourceVariable()) } @@ -404,8 +547,8 @@ class Dereference extends G::DereferenceableExpr { * be `null`, and this expression can be reached from `def` without passing * through another such dereference. */ - predicate isFirstMaybeNull(Ssa::Definition def, string msg, Element reason) { - this.isMaybeNull(def, msg, reason) and + predicate isFirstMaybeNull(Ssa::Definition def, SourcePathNode source, SinkPathNode sink, string msg, Element reason) { + this.isMaybeNull(def, source, sink, msg, reason) and defReaches(def, this, false) } } diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index e8fa362ebf89..7cb75b63dcb9 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -2249,6 +2249,9 @@ module Ssa { definesAt(this, bb, i, _) } + /** Gets the basic block to which this SSA definition belongs. */ + BasicBlock getBasicBlock() { this.definesAt(result, _) } + /** * Holds if this SSA definition assigns to `out`/`ref` parameter `p`, and the * parameter may remain unchanged throughout the rest of the enclosing callable. diff --git a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected index 3c28cc8a951b..b6b6f22c2c37 100644 --- a/csharp/ql/test/query-tests/Nullness/NullMaybe.expected +++ b/csharp/ql/test/query-tests/Nullness/NullMaybe.expected @@ -1,74 +1,779 @@ -| C.cs:64:9:64:10 | access to local variable o1 | Variable $@ may be null here because of $@ assignment. | C.cs:62:13:62:14 | o1 | o1 | C.cs:62:13:62:46 | Object o1 = ... | this | -| C.cs:68:9:68:10 | access to local variable o2 | Variable $@ may be null here because of $@ assignment. | C.cs:66:13:66:14 | o2 | o2 | C.cs:66:13:66:46 | Object o2 = ... | this | -| C.cs:96:15:96:15 | access to local variable o | Variable $@ may be null here because of $@ assignment. | C.cs:95:13:95:13 | o | o | C.cs:95:13:95:45 | Object o = ... | this | -| C.cs:104:27:104:30 | access to parameter list | Variable $@ may be null here because of $@ assignment. | C.cs:100:42:100:45 | list | list | C.cs:103:13:103:23 | ... = ... | this | -| C.cs:178:13:178:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:152:13:152:13 | s | s | C.cs:179:13:179:20 | ... = ... | this | -| C.cs:204:13:204:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:186:13:186:13 | s | s | C.cs:205:13:205:20 | ... = ... | this | -| C.cs:224:9:224:9 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:211:13:211:13 | s | s | C.cs:223:13:223:20 | ... = ... | this | -| C.cs:243:13:243:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:229:16:229:16 | s | s | C.cs:241:24:241:31 | ... = ... | this | -| D.cs:23:9:23:13 | access to parameter param | Variable $@ may be null here because of $@ null argument. | D.cs:21:32:21:36 | param | param | D.cs:17:17:17:20 | null | this | -| D.cs:32:9:32:13 | access to parameter param | Variable $@ may be null here as suggested by $@ null check. | D.cs:26:32:26:36 | param | param | D.cs:28:13:28:25 | ... != ... | this | -| D.cs:62:13:62:14 | access to local variable o5 | Variable $@ may be null here because of $@ assignment. | D.cs:58:13:58:14 | o5 | o5 | D.cs:58:13:58:41 | String o5 = ... | this | -| D.cs:73:13:73:14 | access to local variable o7 | Variable $@ may be null here because of $@ assignment. | D.cs:68:13:68:14 | o7 | o7 | D.cs:68:13:68:34 | String o7 = ... | this | -| D.cs:82:13:82:14 | access to local variable o8 | Variable $@ may be null here because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this | -| D.cs:84:13:84:14 | access to local variable o8 | Variable $@ may be null here because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this | -| D.cs:91:13:91:14 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | -| D.cs:94:21:94:22 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | -| D.cs:98:21:98:22 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | -| D.cs:102:31:102:32 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | -| D.cs:105:19:105:20 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | -| D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this | -| D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this | -| D.cs:135:24:135:24 | access to parameter b | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:44:125:44 | b | b | D.cs:128:20:128:28 | ... == ... | this | -| D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this | -| D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this | -| D.cs:151:9:151:11 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | D.cs:149:36:149:38 | obj | obj | D.cs:152:17:152:27 | ... != ... | this | -| D.cs:171:9:171:11 | access to local variable obj | Variable $@ may be null here because of $@ assignment. | D.cs:163:16:163:18 | obj | obj | D.cs:163:16:163:25 | Object obj = ... | this | -| D.cs:245:13:245:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this | -| D.cs:247:13:247:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this | -| D.cs:253:13:253:14 | access to local variable o2 | Variable $@ may be null here because of $@ assignment. | D.cs:249:13:249:14 | o2 | o2 | D.cs:249:13:249:38 | String o2 = ... | this | -| D.cs:267:13:267:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:258:16:258:23 | Object o = ... | this | -| D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this | -| D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this | -| D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this | -| D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this | -| D.cs:300:17:300:20 | access to local variable prev | Variable $@ may be null here because of $@ assignment. | D.cs:296:16:296:19 | prev | prev | D.cs:296:16:296:26 | Object prev = ... | this | -| D.cs:313:17:313:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | D.cs:304:16:304:16 | s | s | D.cs:304:16:304:23 | String s = ... | this | -| D.cs:324:9:324:9 | access to local variable r | Variable $@ may be null here because of $@ assignment. | D.cs:316:16:316:16 | r | r | D.cs:316:16:316:23 | Object r = ... | this | -| D.cs:356:13:356:13 | access to local variable a | Variable $@ may be null here because of $@ assignment. | D.cs:351:15:351:15 | a | a | D.cs:351:15:351:22 | Int32[] a = ... | this | -| D.cs:363:13:363:16 | access to local variable last | Variable $@ may be null here because of $@ assignment. | D.cs:360:20:360:23 | last | last | D.cs:360:20:360:30 | String last = ... | this | -| D.cs:372:13:372:13 | access to local variable b | Variable $@ may be null here because of $@ assignment. | D.cs:366:15:366:15 | b | b | D.cs:366:15:366:47 | Int32[] b = ... | this | -| D.cs:395:20:395:20 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:388:36:388:36 | a | a | D.cs:390:20:390:28 | ... == ... | this | -| D.cs:400:20:400:20 | access to parameter b | Variable $@ may be null here as suggested by $@ null check. | D.cs:388:45:388:45 | b | b | D.cs:397:20:397:28 | ... == ... | this | -| D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:27:407:35 | ... == ... | this | -| D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:55:407:63 | ... != ... | this | -| D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:411:13:411:21 | ... != ... | this | -| D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:14:407:22 | ... != ... | this | -| D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:42:407:50 | ... == ... | this | -| D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:409:13:409:21 | ... != ... | this | -| E.cs:12:38:12:39 | access to local variable a2 | Variable $@ may be null here because of $@ assignment. | E.cs:9:18:9:19 | a2 | a2 | E.cs:9:18:9:26 | Int64[][] a2 = ... | this | -| E.cs:14:13:14:14 | access to local variable a3 | Variable $@ may be null here because of $@ assignment. | E.cs:11:16:11:17 | a3 | a3 | E.cs:11:16:11:24 | Int64[] a3 = ... | this | -| E.cs:27:13:27:14 | access to local variable s1 | Variable $@ may be null here because of $@ assignment. | E.cs:19:13:19:14 | s1 | s1 | E.cs:23:13:23:30 | ... = ... | this | -| E.cs:35:9:35:12 | access to local variable last | Variable $@ may be null here because of $@ assignment. | E.cs:32:16:32:19 | last | last | E.cs:32:16:32:26 | String last = ... | this | -| E.cs:43:13:43:16 | access to local variable last | Variable $@ may be null here because of $@ assignment. | E.cs:32:16:32:19 | last | last | E.cs:37:9:37:19 | ... = ... | this | -| E.cs:61:13:61:17 | access to local variable slice | Variable $@ may be null here because of $@ assignment. | E.cs:51:22:51:26 | slice | slice | E.cs:51:22:51:33 | List slice = ... | this | -| E.cs:73:13:73:15 | access to parameter arr | Variable $@ may be null here as suggested by $@ null check. | E.cs:66:40:66:42 | arr | arr | E.cs:70:22:70:32 | ... == ... | this | -| E.cs:112:13:112:16 | access to local variable arr2 | Variable $@ may be null here because of $@ assignment. | E.cs:107:15:107:18 | arr2 | arr2 | E.cs:107:15:107:25 | Int32[] arr2 = ... | this | -| E.cs:125:33:125:35 | access to local variable obj | Variable $@ may be null here because of $@ assignment. | E.cs:119:13:119:15 | obj | obj | E.cs:137:25:137:34 | ... = ... | this | -| E.cs:159:13:159:16 | access to local variable obj2 | Variable $@ may be null here as suggested by $@ null check. | E.cs:152:16:152:19 | obj2 | obj2 | E.cs:153:13:153:24 | ... != ... | this | -| E.cs:167:21:167:21 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | E.cs:162:28:162:28 | a | a | E.cs:164:17:164:25 | ... == ... | this | -| E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this | -| E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this | -| E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this | -| E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this | -| E.cs:192:17:192:17 | access to parameter o | Variable $@ may be null here as suggested by $@ null check. | E.cs:190:29:190:29 | o | o | E.cs:193:17:193:17 | access to parameter o | this | -| E.cs:201:11:201:11 | access to local variable o | Variable $@ may be null here because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this | -| E.cs:203:11:203:11 | access to local variable o | Variable $@ may be null here because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this | -| E.cs:218:9:218:9 | access to local variable x | Variable $@ may be null here because of $@ assignment. | E.cs:215:13:215:13 | x | x | E.cs:217:13:217:20 | ... = ... | this | -| E.cs:230:9:230:9 | access to local variable x | Variable $@ may be null here because of $@ assignment. | E.cs:225:13:225:13 | x | x | E.cs:227:13:227:20 | ... = ... | this | -| E.cs:235:16:235:16 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:233:26:233:26 | i | i | E.cs:233:26:233:26 | i | this | -| E.cs:240:21:240:21 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:238:26:238:26 | i | i | E.cs:238:26:238:26 | i | this | -| E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this | -| GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null here because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this | -| NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null here because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this | -| StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this | +nodes +| A.cs:7:16:7:40 | SSA def(synchronizedAlways) | +| A.cs:8:15:8:32 | access to local variable synchronizedAlways | +| A.cs:10:13:10:30 | access to local variable synchronizedAlways | +| A.cs:16:15:16:30 | SSA def(arrayNull) | +| A.cs:17:9:17:17 | access to local variable arrayNull | +| A.cs:26:15:26:32 | SSA def(arrayAccess) | +| A.cs:27:18:27:35 | SSA def(fieldAccess) | +| A.cs:28:16:28:34 | SSA def(methodAccess) | +| A.cs:29:16:29:32 | SSA def(methodCall) | +| A.cs:31:27:31:37 | access to local variable arrayAccess | +| A.cs:32:27:32:37 | access to local variable fieldAccess | +| A.cs:33:28:33:39 | access to local variable methodAccess | +| A.cs:34:27:34:36 | access to local variable methodCall | +| A.cs:36:27:36:37 | access to local variable arrayAccess | +| A.cs:37:27:37:37 | access to local variable fieldAccess | +| A.cs:38:15:38:26 | access to local variable methodAccess | +| A.cs:39:27:39:36 | access to local variable methodCall | +| A.cs:48:16:48:28 | SSA def(varRef) | +| A.cs:50:9:50:14 | access to local variable varRef | +| Assert.cs:13:9:13:25 | [b (line 7): false] SSA def(s) | +| Assert.cs:13:9:13:25 | [b (line 7): true] SSA def(s) | +| Assert.cs:15:27:15:27 | access to local variable s | +| Assert.cs:15:27:15:27 | access to local variable s | +| Assert.cs:21:9:21:25 | [b (line 7): false] SSA def(s) | +| Assert.cs:21:9:21:25 | [b (line 7): true] SSA def(s) | +| Assert.cs:23:27:23:27 | access to local variable s | +| Assert.cs:23:27:23:27 | access to local variable s | +| Assert.cs:29:9:29:25 | [b (line 7): false] SSA def(s) | +| Assert.cs:29:9:29:25 | [b (line 7): true] SSA def(s) | +| Assert.cs:31:27:31:27 | access to local variable s | +| Assert.cs:31:27:31:27 | access to local variable s | +| Assert.cs:45:9:45:25 | [b (line 7): false] SSA def(s) | +| Assert.cs:45:9:45:25 | [b (line 7): true] SSA def(s) | +| Assert.cs:46:36:46:36 | [b (line 7): false] access to parameter b | +| Assert.cs:46:36:46:36 | [b (line 7): true] access to parameter b | +| Assert.cs:47:27:47:27 | access to local variable s | +| Assert.cs:47:27:47:27 | access to local variable s | +| Assert.cs:49:9:49:25 | SSA def(s) | +| Assert.cs:50:37:50:37 | access to parameter b | +| Assert.cs:51:27:51:27 | access to local variable s | +| B.cs:7:11:7:29 | SSA def(eqCallAlways) | +| B.cs:10:11:10:30 | SSA def(neqCallAlways) | +| B.cs:13:13:13:24 | access to local variable eqCallAlways | +| B.cs:13:13:13:36 | ...; | +| B.cs:15:9:16:26 | if (...) ... | +| B.cs:16:13:16:26 | ...; | +| B.cs:18:9:20:26 | if (...) ... | +| B.cs:18:25:18:27 | {...} | +| B.cs:20:13:20:26 | ...; | +| B.cs:22:9:24:37 | if (...) ... | +| B.cs:24:13:24:25 | access to local variable neqCallAlways | +| C.cs:10:16:10:23 | SSA def(o) | +| C.cs:16:9:19:9 | if (...) ... | +| C.cs:18:13:18:13 | access to local variable o | +| C.cs:40:13:40:35 | SSA def(s) | +| C.cs:42:9:42:9 | access to local variable s | +| C.cs:55:13:55:36 | SSA def(o2) | +| C.cs:57:9:57:10 | access to local variable o2 | +| C.cs:62:13:62:46 | SSA def(o1) | +| C.cs:64:9:64:10 | access to local variable o1 | +| C.cs:66:13:66:46 | SSA def(o2) | +| C.cs:68:9:68:10 | access to local variable o2 | +| C.cs:95:13:95:45 | SSA def(o) | +| C.cs:96:15:96:15 | access to local variable o | +| C.cs:97:13:97:13 | access to local variable o | +| C.cs:103:13:103:23 | SSA def(list) | +| C.cs:104:9:108:9 | foreach (... ... in ...) ... | +| C.cs:104:22:104:22 | Int32 x | +| C.cs:104:27:104:30 | access to parameter list | +| C.cs:104:27:104:30 | access to parameter list | +| C.cs:107:13:107:16 | access to parameter list | +| C.cs:160:9:160:16 | SSA def(s) | +| C.cs:163:13:163:13 | access to local variable s | +| C.cs:168:9:168:16 | SSA def(s) | +| C.cs:171:13:171:13 | access to local variable s | +| C.cs:178:13:178:13 | access to local variable s | +| C.cs:179:13:179:20 | SSA def(s) | +| C.cs:194:9:194:16 | SSA def(s) | +| C.cs:197:13:197:13 | access to local variable s | +| C.cs:198:13:198:20 | [b (line 193): true] SSA def(s) | +| C.cs:204:13:204:13 | access to local variable s | +| C.cs:205:13:205:20 | SSA def(s) | +| C.cs:211:13:211:35 | SSA def(s) | +| C.cs:215:13:215:20 | SSA def(s) | +| C.cs:218:9:219:25 | if (...) ... | +| C.cs:219:13:219:13 | access to local variable s | +| C.cs:223:13:223:20 | SSA def(s) | +| C.cs:224:9:224:9 | access to local variable s | +| C.cs:230:22:230:22 | access to local variable s | +| C.cs:230:33:230:40 | SSA def(s) | +| C.cs:234:9:234:9 | access to local variable s | +| C.cs:236:14:236:21 | SSA def(s) | +| C.cs:236:24:236:24 | access to local variable s | +| C.cs:236:35:236:42 | SSA def(s) | +| C.cs:238:13:238:13 | access to local variable s | +| C.cs:241:24:241:31 | SSA def(s) | +| C.cs:243:13:243:13 | access to local variable s | +| C.cs:249:15:249:22 | SSA def(a) | +| C.cs:250:9:250:9 | access to local variable a | +| C.cs:258:15:258:23 | SSA def(ia) | +| C.cs:259:18:259:26 | SSA def(sa) | +| C.cs:261:9:261:10 | access to local variable ia | +| C.cs:262:20:262:21 | access to local variable sa | +| C.cs:264:9:264:10 | access to local variable ia | +| C.cs:265:16:265:17 | access to local variable sa | +| D.cs:17:17:17:20 | null | +| D.cs:23:9:23:13 | access to parameter param | +| D.cs:26:32:26:36 | SSA param(param) | +| D.cs:32:9:32:13 | access to parameter param | +| D.cs:58:13:58:41 | SSA def(o5) | +| D.cs:61:9:62:26 | if (...) ... | +| D.cs:62:13:62:14 | access to local variable o5 | +| D.cs:68:13:68:34 | SSA def(o7) | +| D.cs:69:13:69:36 | Boolean ok = ... | +| D.cs:73:13:73:14 | access to local variable o7 | +| D.cs:75:13:75:34 | SSA def(o8) | +| D.cs:76:13:76:43 | Int32 track = ... | +| D.cs:76:34:76:35 | 42 | +| D.cs:79:9:80:26 | if (...) ... | +| D.cs:81:9:82:26 | if (...) ... | +| D.cs:82:13:82:14 | access to local variable o8 | +| D.cs:82:13:82:26 | ...; | +| D.cs:83:9:84:26 | if (...) ... | +| D.cs:84:13:84:14 | access to local variable o8 | +| D.cs:89:15:89:44 | SSA def(xs) | +| D.cs:91:13:91:14 | access to local variable xs | +| D.cs:91:13:91:22 | ...; | +| D.cs:93:9:94:30 | if (...) ... | +| D.cs:94:13:94:30 | ...; | +| D.cs:94:21:94:22 | access to local variable xs | +| D.cs:96:9:99:9 | if (...) ... | +| D.cs:97:9:99:9 | {...} | +| D.cs:98:21:98:22 | access to local variable xs | +| D.cs:101:9:102:35 | if (...) ... | +| D.cs:102:13:102:35 | foreach (... ... in ...) ... | +| D.cs:102:31:102:32 | access to local variable xs | +| D.cs:102:31:102:32 | access to local variable xs | +| D.cs:102:35:102:35 | ; | +| D.cs:104:9:106:30 | if (...) ... | +| D.cs:105:19:105:20 | access to local variable xs | +| D.cs:106:17:106:18 | access to local variable xs | +| D.cs:118:9:118:30 | SSA def(x) | +| D.cs:120:13:120:13 | access to local variable x | +| D.cs:125:35:125:35 | SSA param(a) | +| D.cs:125:35:125:35 | SSA param(a) | +| D.cs:125:44:125:44 | SSA param(b) | +| D.cs:127:13:127:43 | Int32 alen = ... | +| D.cs:127:13:127:43 | Int32 alen = ... | +| D.cs:127:32:127:32 | 0 | +| D.cs:127:32:127:32 | 0 | +| D.cs:127:36:127:36 | access to parameter a | +| D.cs:128:13:128:43 | Int32 blen = ... | +| D.cs:128:13:128:43 | Int32 blen = ... | +| D.cs:128:32:128:32 | 0 | +| D.cs:128:32:128:32 | 0 | +| D.cs:128:36:128:36 | access to parameter b | +| D.cs:131:9:137:9 | {...} | +| D.cs:131:9:137:9 | {...} | +| D.cs:132:29:132:29 | access to local variable i | +| D.cs:132:29:132:29 | access to local variable i | +| D.cs:133:13:136:13 | {...} | +| D.cs:133:13:136:13 | {...} | +| D.cs:134:24:134:24 | access to parameter a | +| D.cs:135:24:135:24 | access to parameter b | +| D.cs:138:9:138:18 | ... ...; | +| D.cs:142:13:142:22 | ...; | +| D.cs:143:9:146:9 | for (...;...;...) ... | +| D.cs:143:25:143:25 | access to local variable i | +| D.cs:144:9:146:9 | {...} | +| D.cs:145:20:145:20 | access to parameter a | +| D.cs:149:36:149:38 | SSA param(obj) | +| D.cs:151:9:151:11 | access to parameter obj | +| D.cs:163:16:163:25 | SSA def(obj) | +| D.cs:168:9:170:9 | [exception: Exception] catch (...) {...} | +| D.cs:171:9:171:11 | access to local variable obj | +| D.cs:240:9:240:16 | SSA def(o) | +| D.cs:241:13:241:37 | String other = ... | +| D.cs:241:29:241:32 | null | +| D.cs:241:36:241:37 | "" | +| D.cs:244:9:247:25 | if (...) ... | +| D.cs:245:13:245:13 | access to local variable o | +| D.cs:247:13:247:13 | access to local variable o | +| D.cs:249:13:249:38 | SSA def(o2) | +| D.cs:253:13:253:14 | access to local variable o2 | +| D.cs:258:16:258:23 | SSA def(o) | +| D.cs:266:9:267:25 | if (...) ... | +| D.cs:267:13:267:13 | access to local variable o | +| D.cs:269:9:269:16 | SSA def(o) | +| D.cs:272:25:272:25 | access to local variable i | +| D.cs:272:39:272:39 | access to local variable i | +| D.cs:273:9:288:9 | {...} | +| D.cs:281:13:287:13 | if (...) ... | +| D.cs:283:17:283:24 | SSA def(o) | +| D.cs:285:28:285:30 | {...} | +| D.cs:286:17:286:30 | ...; | +| D.cs:290:9:291:25 | if (...) ... | +| D.cs:291:13:291:13 | access to local variable o | +| D.cs:291:13:291:25 | ...; | +| D.cs:293:9:294:25 | if (...) ... | +| D.cs:294:13:294:13 | access to local variable o | +| D.cs:296:16:296:26 | SSA def(prev) | +| D.cs:297:25:297:25 | access to local variable i | +| D.cs:298:9:302:9 | {...} | +| D.cs:300:17:300:20 | access to local variable prev | +| D.cs:304:16:304:23 | SSA def(s) | +| D.cs:307:13:311:13 | foreach (... ... in ...) ... | +| D.cs:312:13:313:29 | if (...) ... | +| D.cs:313:17:313:17 | access to local variable s | +| D.cs:316:16:316:23 | SSA def(r) | +| D.cs:318:16:318:62 | ... && ... | +| D.cs:318:41:318:44 | access to local variable stat | +| D.cs:324:9:324:9 | access to local variable r | +| D.cs:351:15:351:22 | SSA def(a) | +| D.cs:355:9:356:21 | for (...;...;...) ... | +| D.cs:355:25:355:25 | access to local variable i | +| D.cs:356:13:356:13 | access to local variable a | +| D.cs:356:13:356:21 | ...; | +| D.cs:360:20:360:30 | SSA def(last) | +| D.cs:361:29:361:29 | access to local variable i | +| D.cs:363:13:363:16 | access to local variable last | +| D.cs:366:15:366:47 | SSA def(b) | +| D.cs:370:9:373:9 | for (...;...;...) ... | +| D.cs:370:25:370:25 | access to local variable i | +| D.cs:371:9:373:9 | {...} | +| D.cs:372:13:372:13 | access to local variable b | +| D.cs:378:19:378:28 | SSA def(ioe) | +| D.cs:382:9:385:27 | if (...) ... | +| D.cs:385:13:385:15 | access to local variable ioe | +| D.cs:388:36:388:36 | SSA param(a) | +| D.cs:388:45:388:45 | SSA param(b) | +| D.cs:390:13:390:43 | Int32 alen = ... | +| D.cs:390:13:390:43 | Int32 alen = ... | +| D.cs:390:32:390:32 | 0 | +| D.cs:390:32:390:32 | 0 | +| D.cs:390:36:390:36 | access to parameter a | +| D.cs:393:21:393:21 | access to local variable i | +| D.cs:393:21:393:21 | access to local variable i | +| D.cs:394:9:396:9 | {...} | +| D.cs:394:9:396:9 | {...} | +| D.cs:395:20:395:20 | access to parameter a | +| D.cs:397:9:397:44 | ... ...; | +| D.cs:397:13:397:43 | Int32 blen = ... | +| D.cs:397:32:397:32 | 0 | +| D.cs:398:21:398:21 | access to local variable i | +| D.cs:399:9:401:9 | {...} | +| D.cs:400:20:400:20 | access to parameter b | +| D.cs:405:35:405:35 | SSA param(x) | +| D.cs:405:35:405:35 | SSA param(x) | +| D.cs:405:35:405:35 | SSA param(x) | +| D.cs:405:45:405:45 | SSA param(y) | +| D.cs:405:45:405:45 | SSA param(y) | +| D.cs:405:45:405:45 | SSA param(y) | +| D.cs:407:42:407:63 | ... && ... | +| D.cs:407:42:407:63 | ... && ... | +| D.cs:407:55:407:55 | access to parameter y | +| D.cs:407:55:407:55 | access to parameter y | +| D.cs:409:9:410:25 | if (...) ... | +| D.cs:409:9:410:25 | if (...) ... | +| D.cs:410:13:410:13 | access to parameter y | +| D.cs:411:9:412:25 | if (...) ... | +| D.cs:412:13:412:13 | access to parameter x | +| E.cs:9:18:9:26 | SSA def(a2) | +| E.cs:10:13:10:54 | Boolean haveA2 = ... | +| E.cs:11:16:11:24 | SSA def(a3) | +| E.cs:12:13:12:52 | Boolean haveA3 = ... | +| E.cs:12:38:12:39 | access to local variable a2 | +| E.cs:14:13:14:14 | access to local variable a3 | +| E.cs:23:13:23:30 | SSA def(s1) | +| E.cs:24:13:24:41 | ... = ... | +| E.cs:24:33:24:36 | null | +| E.cs:26:9:27:26 | if (...) ... | +| E.cs:27:13:27:14 | access to local variable s1 | +| E.cs:32:16:32:26 | SSA def(last) | +| E.cs:33:9:34:21 | foreach (... ... in ...) ... | +| E.cs:35:9:35:12 | access to local variable last | +| E.cs:37:9:37:19 | SSA def(last) | +| E.cs:39:9:44:9 | {...} | +| E.cs:40:13:41:25 | foreach (... ... in ...) ... | +| E.cs:43:13:43:16 | access to local variable last | +| E.cs:51:22:51:33 | SSA def(slice) | +| E.cs:53:16:53:19 | access to local variable iter | +| E.cs:54:9:63:9 | {...} | +| E.cs:61:13:61:17 | access to local variable slice | +| E.cs:61:13:61:27 | ...; | +| E.cs:66:40:66:42 | SSA param(arr) | +| E.cs:70:13:70:49 | ... = ... | +| E.cs:70:13:70:50 | ...; | +| E.cs:70:36:70:36 | 0 | +| E.cs:72:9:73:23 | if (...) ... | +| E.cs:73:13:73:15 | access to parameter arr | +| E.cs:107:15:107:25 | SSA def(arr2) | +| E.cs:111:9:112:30 | for (...;...;...) ... | +| E.cs:111:25:111:25 | access to local variable i | +| E.cs:112:13:112:16 | access to local variable arr2 | +| E.cs:112:13:112:30 | ...; | +| E.cs:120:16:120:20 | !... | +| E.cs:121:9:143:9 | {...} | +| E.cs:123:20:123:35 | ... && ... | +| E.cs:123:29:123:29 | access to local variable j | +| E.cs:124:13:142:13 | {...} | +| E.cs:125:33:125:35 | access to local variable obj | +| E.cs:128:21:128:23 | access to local variable obj | +| E.cs:137:25:137:34 | SSA def(obj) | +| E.cs:139:21:139:29 | continue; | +| E.cs:141:17:141:26 | ...; | +| E.cs:152:16:152:26 | SSA def(obj2) | +| E.cs:158:9:159:28 | if (...) ... | +| E.cs:159:13:159:16 | access to local variable obj2 | +| E.cs:162:28:162:28 | SSA param(a) | +| E.cs:164:13:164:40 | Int32 n = ... | +| E.cs:164:29:164:29 | 0 | +| E.cs:165:25:165:25 | access to local variable i | +| E.cs:165:32:165:32 | access to local variable i | +| E.cs:166:9:170:9 | {...} | +| E.cs:167:21:167:21 | access to parameter a | +| E.cs:173:29:173:31 | SSA param(obj) | +| E.cs:173:29:173:31 | SSA param(obj) | +| E.cs:175:14:175:42 | Boolean b2 = ... | +| E.cs:175:33:175:37 | false | +| E.cs:177:9:179:9 | {...} | +| E.cs:178:13:178:15 | access to parameter obj | +| E.cs:180:9:183:9 | if (...) ... | +| E.cs:181:9:183:9 | {...} | +| E.cs:184:9:187:9 | if (...) ... | +| E.cs:186:13:186:15 | access to parameter obj | +| E.cs:190:29:190:29 | SSA param(o) | +| E.cs:192:17:192:17 | access to parameter o | +| E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) | +| E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) | +| E.cs:201:11:201:11 | access to local variable o | +| E.cs:203:11:203:11 | access to local variable o | +| E.cs:206:28:206:28 | SSA param(s) | +| E.cs:210:16:210:16 | access to parameter s | +| E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | +| E.cs:218:9:218:9 | access to local variable x | +| E.cs:220:13:220:13 | access to local variable x | +| E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | +| E.cs:229:13:229:13 | access to local variable x | +| E.cs:230:9:230:9 | access to local variable x | +| E.cs:233:26:233:26 | SSA param(i) | +| E.cs:235:16:235:16 | access to parameter i | +| E.cs:238:26:238:26 | SSA param(i) | +| E.cs:240:21:240:21 | access to parameter i | +| E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) | +| E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) | +| E.cs:285:9:285:9 | access to local variable o | +| E.cs:285:9:285:9 | access to local variable o | +| Forwarding.cs:7:16:7:23 | SSA def(s) | +| Forwarding.cs:14:9:17:9 | if (...) ... | +| Forwarding.cs:19:9:22:9 | if (...) ... | +| Forwarding.cs:24:9:27:9 | if (...) ... | +| Forwarding.cs:29:9:32:9 | if (...) ... | +| Forwarding.cs:34:9:37:9 | if (...) ... | +| Forwarding.cs:35:9:37:9 | {...} | +| Forwarding.cs:36:31:36:31 | access to local variable s | +| Forwarding.cs:40:27:40:27 | access to local variable s | +| GuardedString.cs:7:16:7:32 | SSA def(s) | +| GuardedString.cs:14:9:17:9 | if (...) ... | +| GuardedString.cs:19:9:20:40 | if (...) ... | +| GuardedString.cs:19:26:19:26 | 0 | +| GuardedString.cs:22:9:23:40 | if (...) ... | +| GuardedString.cs:22:25:22:25 | 0 | +| GuardedString.cs:25:9:26:40 | if (...) ... | +| GuardedString.cs:25:26:25:26 | 0 | +| GuardedString.cs:28:9:29:40 | if (...) ... | +| GuardedString.cs:28:25:28:26 | 10 | +| GuardedString.cs:31:9:32:40 | if (...) ... | +| GuardedString.cs:31:26:31:27 | 10 | +| GuardedString.cs:34:9:37:40 | if (...) ... | +| GuardedString.cs:34:26:34:26 | 0 | +| GuardedString.cs:35:31:35:31 | access to local variable s | +| NullAlwaysBad.cs:7:29:7:29 | SSA param(s) | +| NullAlwaysBad.cs:9:30:9:30 | access to parameter s | +| NullMaybeBad.cs:7:27:7:27 | access to parameter o | +| NullMaybeBad.cs:13:17:13:20 | null | +| StringConcatenation.cs:14:16:14:23 | SSA def(s) | +| StringConcatenation.cs:15:16:15:16 | access to local variable s | +| StringConcatenation.cs:16:17:16:17 | access to local variable s | +edges +| A.cs:7:16:7:40 | SSA def(synchronizedAlways) | A.cs:8:15:8:32 | access to local variable synchronizedAlways | +| A.cs:7:16:7:40 | SSA def(synchronizedAlways) | A.cs:10:13:10:30 | access to local variable synchronizedAlways | +| A.cs:16:15:16:30 | SSA def(arrayNull) | A.cs:17:9:17:17 | access to local variable arrayNull | +| A.cs:26:15:26:32 | SSA def(arrayAccess) | A.cs:31:27:31:37 | access to local variable arrayAccess | +| A.cs:26:15:26:32 | SSA def(arrayAccess) | A.cs:36:27:36:37 | access to local variable arrayAccess | +| A.cs:27:18:27:35 | SSA def(fieldAccess) | A.cs:32:27:32:37 | access to local variable fieldAccess | +| A.cs:27:18:27:35 | SSA def(fieldAccess) | A.cs:37:27:37:37 | access to local variable fieldAccess | +| A.cs:28:16:28:34 | SSA def(methodAccess) | A.cs:33:28:33:39 | access to local variable methodAccess | +| A.cs:28:16:28:34 | SSA def(methodAccess) | A.cs:38:15:38:26 | access to local variable methodAccess | +| A.cs:29:16:29:32 | SSA def(methodCall) | A.cs:34:27:34:36 | access to local variable methodCall | +| A.cs:29:16:29:32 | SSA def(methodCall) | A.cs:39:27:39:36 | access to local variable methodCall | +| A.cs:48:16:48:28 | SSA def(varRef) | A.cs:50:9:50:14 | access to local variable varRef | +| Assert.cs:13:9:13:25 | [b (line 7): false] SSA def(s) | Assert.cs:15:27:15:27 | access to local variable s | +| Assert.cs:13:9:13:25 | [b (line 7): true] SSA def(s) | Assert.cs:15:27:15:27 | access to local variable s | +| Assert.cs:21:9:21:25 | [b (line 7): false] SSA def(s) | Assert.cs:23:27:23:27 | access to local variable s | +| Assert.cs:21:9:21:25 | [b (line 7): true] SSA def(s) | Assert.cs:23:27:23:27 | access to local variable s | +| Assert.cs:29:9:29:25 | [b (line 7): false] SSA def(s) | Assert.cs:31:27:31:27 | access to local variable s | +| Assert.cs:29:9:29:25 | [b (line 7): true] SSA def(s) | Assert.cs:31:27:31:27 | access to local variable s | +| Assert.cs:45:9:45:25 | [b (line 7): false] SSA def(s) | Assert.cs:46:36:46:36 | [b (line 7): false] access to parameter b | +| Assert.cs:45:9:45:25 | [b (line 7): true] SSA def(s) | Assert.cs:46:36:46:36 | [b (line 7): true] access to parameter b | +| Assert.cs:46:36:46:36 | [b (line 7): false] access to parameter b | Assert.cs:47:27:47:27 | access to local variable s | +| Assert.cs:46:36:46:36 | [b (line 7): true] access to parameter b | Assert.cs:47:27:47:27 | access to local variable s | +| Assert.cs:49:9:49:25 | SSA def(s) | Assert.cs:50:37:50:37 | access to parameter b | +| Assert.cs:50:37:50:37 | access to parameter b | Assert.cs:51:27:51:27 | access to local variable s | +| B.cs:7:11:7:29 | SSA def(eqCallAlways) | B.cs:13:13:13:24 | access to local variable eqCallAlways | +| B.cs:10:11:10:30 | SSA def(neqCallAlways) | B.cs:13:13:13:36 | ...; | +| B.cs:10:11:10:30 | SSA def(neqCallAlways) | B.cs:15:9:16:26 | if (...) ... | +| B.cs:13:13:13:36 | ...; | B.cs:15:9:16:26 | if (...) ... | +| B.cs:15:9:16:26 | if (...) ... | B.cs:16:13:16:26 | ...; | +| B.cs:15:9:16:26 | if (...) ... | B.cs:18:9:20:26 | if (...) ... | +| B.cs:16:13:16:26 | ...; | B.cs:18:9:20:26 | if (...) ... | +| B.cs:18:9:20:26 | if (...) ... | B.cs:18:25:18:27 | {...} | +| B.cs:18:9:20:26 | if (...) ... | B.cs:20:13:20:26 | ...; | +| B.cs:18:25:18:27 | {...} | B.cs:22:9:24:37 | if (...) ... | +| B.cs:20:13:20:26 | ...; | B.cs:22:9:24:37 | if (...) ... | +| B.cs:22:9:24:37 | if (...) ... | B.cs:24:13:24:25 | access to local variable neqCallAlways | +| C.cs:10:16:10:23 | SSA def(o) | C.cs:16:9:19:9 | if (...) ... | +| C.cs:16:9:19:9 | if (...) ... | C.cs:18:13:18:13 | access to local variable o | +| C.cs:40:13:40:35 | SSA def(s) | C.cs:42:9:42:9 | access to local variable s | +| C.cs:55:13:55:36 | SSA def(o2) | C.cs:57:9:57:10 | access to local variable o2 | +| C.cs:62:13:62:46 | SSA def(o1) | C.cs:64:9:64:10 | access to local variable o1 | +| C.cs:66:13:66:46 | SSA def(o2) | C.cs:68:9:68:10 | access to local variable o2 | +| C.cs:95:13:95:45 | SSA def(o) | C.cs:96:15:96:15 | access to local variable o | +| C.cs:95:13:95:45 | SSA def(o) | C.cs:97:13:97:13 | access to local variable o | +| C.cs:103:13:103:23 | SSA def(list) | C.cs:104:27:104:30 | access to parameter list | +| C.cs:103:13:103:23 | SSA def(list) | C.cs:104:27:104:30 | access to parameter list | +| C.cs:104:9:108:9 | foreach (... ... in ...) ... | C.cs:104:22:104:22 | Int32 x | +| C.cs:104:9:108:9 | foreach (... ... in ...) ... | C.cs:107:13:107:16 | access to parameter list | +| C.cs:104:22:104:22 | Int32 x | C.cs:104:9:108:9 | foreach (... ... in ...) ... | +| C.cs:104:27:104:30 | access to parameter list | C.cs:104:9:108:9 | foreach (... ... in ...) ... | +| C.cs:160:9:160:16 | SSA def(s) | C.cs:163:13:163:13 | access to local variable s | +| C.cs:168:9:168:16 | SSA def(s) | C.cs:171:13:171:13 | access to local variable s | +| C.cs:179:13:179:20 | SSA def(s) | C.cs:178:13:178:13 | access to local variable s | +| C.cs:194:9:194:16 | SSA def(s) | C.cs:197:13:197:13 | access to local variable s | +| C.cs:198:13:198:20 | [b (line 193): true] SSA def(s) | C.cs:197:13:197:13 | access to local variable s | +| C.cs:205:13:205:20 | SSA def(s) | C.cs:204:13:204:13 | access to local variable s | +| C.cs:211:13:211:35 | SSA def(s) | C.cs:218:9:219:25 | if (...) ... | +| C.cs:215:13:215:20 | SSA def(s) | C.cs:218:9:219:25 | if (...) ... | +| C.cs:218:9:219:25 | if (...) ... | C.cs:219:13:219:13 | access to local variable s | +| C.cs:223:13:223:20 | SSA def(s) | C.cs:224:9:224:9 | access to local variable s | +| C.cs:230:22:230:22 | access to local variable s | C.cs:234:9:234:9 | access to local variable s | +| C.cs:230:33:230:40 | SSA def(s) | C.cs:230:22:230:22 | access to local variable s | +| C.cs:236:14:236:21 | SSA def(s) | C.cs:236:24:236:24 | access to local variable s | +| C.cs:236:24:236:24 | access to local variable s | C.cs:238:13:238:13 | access to local variable s | +| C.cs:236:35:236:42 | SSA def(s) | C.cs:236:24:236:24 | access to local variable s | +| C.cs:241:24:241:31 | SSA def(s) | C.cs:243:13:243:13 | access to local variable s | +| C.cs:249:15:249:22 | SSA def(a) | C.cs:250:9:250:9 | access to local variable a | +| C.cs:258:15:258:23 | SSA def(ia) | C.cs:261:9:261:10 | access to local variable ia | +| C.cs:258:15:258:23 | SSA def(ia) | C.cs:264:9:264:10 | access to local variable ia | +| C.cs:259:18:259:26 | SSA def(sa) | C.cs:262:20:262:21 | access to local variable sa | +| C.cs:259:18:259:26 | SSA def(sa) | C.cs:265:16:265:17 | access to local variable sa | +| D.cs:17:17:17:20 | null | D.cs:23:9:23:13 | access to parameter param | +| D.cs:26:32:26:36 | SSA param(param) | D.cs:32:9:32:13 | access to parameter param | +| D.cs:58:13:58:41 | SSA def(o5) | D.cs:61:9:62:26 | if (...) ... | +| D.cs:61:9:62:26 | if (...) ... | D.cs:62:13:62:14 | access to local variable o5 | +| D.cs:68:13:68:34 | SSA def(o7) | D.cs:69:13:69:36 | Boolean ok = ... | +| D.cs:69:13:69:36 | Boolean ok = ... | D.cs:73:13:73:14 | access to local variable o7 | +| D.cs:75:13:75:34 | SSA def(o8) | D.cs:76:34:76:35 | 42 | +| D.cs:76:13:76:43 | Int32 track = ... | D.cs:79:9:80:26 | if (...) ... | +| D.cs:76:34:76:35 | 42 | D.cs:76:13:76:43 | Int32 track = ... | +| D.cs:79:9:80:26 | if (...) ... | D.cs:81:9:82:26 | if (...) ... | +| D.cs:81:9:82:26 | if (...) ... | D.cs:82:13:82:14 | access to local variable o8 | +| D.cs:81:9:82:26 | if (...) ... | D.cs:82:13:82:26 | ...; | +| D.cs:81:9:82:26 | if (...) ... | D.cs:83:9:84:26 | if (...) ... | +| D.cs:82:13:82:26 | ...; | D.cs:83:9:84:26 | if (...) ... | +| D.cs:83:9:84:26 | if (...) ... | D.cs:84:13:84:14 | access to local variable o8 | +| D.cs:89:15:89:44 | SSA def(xs) | D.cs:91:13:91:14 | access to local variable xs | +| D.cs:89:15:89:44 | SSA def(xs) | D.cs:91:13:91:22 | ...; | +| D.cs:89:15:89:44 | SSA def(xs) | D.cs:93:9:94:30 | if (...) ... | +| D.cs:91:13:91:22 | ...; | D.cs:93:9:94:30 | if (...) ... | +| D.cs:93:9:94:30 | if (...) ... | D.cs:94:13:94:30 | ...; | +| D.cs:93:9:94:30 | if (...) ... | D.cs:94:21:94:22 | access to local variable xs | +| D.cs:93:9:94:30 | if (...) ... | D.cs:96:9:99:9 | if (...) ... | +| D.cs:94:13:94:30 | ...; | D.cs:96:9:99:9 | if (...) ... | +| D.cs:96:9:99:9 | if (...) ... | D.cs:97:9:99:9 | {...} | +| D.cs:96:9:99:9 | if (...) ... | D.cs:98:21:98:22 | access to local variable xs | +| D.cs:96:9:99:9 | if (...) ... | D.cs:101:9:102:35 | if (...) ... | +| D.cs:97:9:99:9 | {...} | D.cs:101:9:102:35 | if (...) ... | +| D.cs:101:9:102:35 | if (...) ... | D.cs:102:31:102:32 | access to local variable xs | +| D.cs:101:9:102:35 | if (...) ... | D.cs:102:31:102:32 | access to local variable xs | +| D.cs:101:9:102:35 | if (...) ... | D.cs:104:9:106:30 | if (...) ... | +| D.cs:102:13:102:35 | foreach (... ... in ...) ... | D.cs:102:35:102:35 | ; | +| D.cs:102:13:102:35 | foreach (... ... in ...) ... | D.cs:104:9:106:30 | if (...) ... | +| D.cs:102:31:102:32 | access to local variable xs | D.cs:102:13:102:35 | foreach (... ... in ...) ... | +| D.cs:102:35:102:35 | ; | D.cs:102:13:102:35 | foreach (... ... in ...) ... | +| D.cs:104:9:106:30 | if (...) ... | D.cs:105:19:105:20 | access to local variable xs | +| D.cs:104:9:106:30 | if (...) ... | D.cs:106:17:106:18 | access to local variable xs | +| D.cs:118:9:118:30 | SSA def(x) | D.cs:120:13:120:13 | access to local variable x | +| D.cs:125:35:125:35 | SSA param(a) | D.cs:127:32:127:32 | 0 | +| D.cs:125:35:125:35 | SSA param(a) | D.cs:127:32:127:32 | 0 | +| D.cs:125:44:125:44 | SSA param(b) | D.cs:127:32:127:32 | 0 | +| D.cs:125:44:125:44 | SSA param(b) | D.cs:127:36:127:36 | access to parameter a | +| D.cs:127:13:127:43 | Int32 alen = ... | D.cs:128:32:128:32 | 0 | +| D.cs:127:13:127:43 | Int32 alen = ... | D.cs:128:32:128:32 | 0 | +| D.cs:127:13:127:43 | Int32 alen = ... | D.cs:128:36:128:36 | access to parameter b | +| D.cs:127:32:127:32 | 0 | D.cs:127:13:127:43 | Int32 alen = ... | +| D.cs:127:32:127:32 | 0 | D.cs:127:13:127:43 | Int32 alen = ... | +| D.cs:127:36:127:36 | access to parameter a | D.cs:127:13:127:43 | Int32 alen = ... | +| D.cs:128:13:128:43 | Int32 blen = ... | D.cs:131:9:137:9 | {...} | +| D.cs:128:13:128:43 | Int32 blen = ... | D.cs:131:9:137:9 | {...} | +| D.cs:128:13:128:43 | Int32 blen = ... | D.cs:138:9:138:18 | ... ...; | +| D.cs:128:32:128:32 | 0 | D.cs:128:13:128:43 | Int32 blen = ... | +| D.cs:128:32:128:32 | 0 | D.cs:128:13:128:43 | Int32 blen = ... | +| D.cs:128:36:128:36 | access to parameter b | D.cs:128:13:128:43 | Int32 blen = ... | +| D.cs:131:9:137:9 | {...} | D.cs:132:29:132:29 | access to local variable i | +| D.cs:131:9:137:9 | {...} | D.cs:132:29:132:29 | access to local variable i | +| D.cs:132:29:132:29 | access to local variable i | D.cs:133:13:136:13 | {...} | +| D.cs:132:29:132:29 | access to local variable i | D.cs:133:13:136:13 | {...} | +| D.cs:132:29:132:29 | access to local variable i | D.cs:134:24:134:24 | access to parameter a | +| D.cs:132:29:132:29 | access to local variable i | D.cs:135:24:135:24 | access to parameter b | +| D.cs:132:29:132:29 | access to local variable i | D.cs:138:9:138:18 | ... ...; | +| D.cs:133:13:136:13 | {...} | D.cs:132:29:132:29 | access to local variable i | +| D.cs:133:13:136:13 | {...} | D.cs:132:29:132:29 | access to local variable i | +| D.cs:138:9:138:18 | ... ...; | D.cs:142:13:142:22 | ...; | +| D.cs:142:13:142:22 | ...; | D.cs:143:9:146:9 | for (...;...;...) ... | +| D.cs:143:9:146:9 | for (...;...;...) ... | D.cs:143:25:143:25 | access to local variable i | +| D.cs:143:25:143:25 | access to local variable i | D.cs:144:9:146:9 | {...} | +| D.cs:143:25:143:25 | access to local variable i | D.cs:145:20:145:20 | access to parameter a | +| D.cs:144:9:146:9 | {...} | D.cs:143:25:143:25 | access to local variable i | +| D.cs:149:36:149:38 | SSA param(obj) | D.cs:151:9:151:11 | access to parameter obj | +| D.cs:163:16:163:25 | SSA def(obj) | D.cs:168:9:170:9 | [exception: Exception] catch (...) {...} | +| D.cs:168:9:170:9 | [exception: Exception] catch (...) {...} | D.cs:171:9:171:11 | access to local variable obj | +| D.cs:240:9:240:16 | SSA def(o) | D.cs:241:29:241:32 | null | +| D.cs:240:9:240:16 | SSA def(o) | D.cs:241:36:241:37 | "" | +| D.cs:241:13:241:37 | String other = ... | D.cs:244:9:247:25 | if (...) ... | +| D.cs:241:29:241:32 | null | D.cs:241:13:241:37 | String other = ... | +| D.cs:241:36:241:37 | "" | D.cs:241:13:241:37 | String other = ... | +| D.cs:244:9:247:25 | if (...) ... | D.cs:245:13:245:13 | access to local variable o | +| D.cs:244:9:247:25 | if (...) ... | D.cs:247:13:247:13 | access to local variable o | +| D.cs:249:13:249:38 | SSA def(o2) | D.cs:253:13:253:14 | access to local variable o2 | +| D.cs:258:16:258:23 | SSA def(o) | D.cs:266:9:267:25 | if (...) ... | +| D.cs:266:9:267:25 | if (...) ... | D.cs:267:13:267:13 | access to local variable o | +| D.cs:269:9:269:16 | SSA def(o) | D.cs:272:25:272:25 | access to local variable i | +| D.cs:272:25:272:25 | access to local variable i | D.cs:273:9:288:9 | {...} | +| D.cs:272:25:272:25 | access to local variable i | D.cs:290:9:291:25 | if (...) ... | +| D.cs:272:39:272:39 | access to local variable i | D.cs:272:25:272:25 | access to local variable i | +| D.cs:273:9:288:9 | {...} | D.cs:281:13:287:13 | if (...) ... | +| D.cs:281:13:287:13 | if (...) ... | D.cs:272:39:272:39 | access to local variable i | +| D.cs:283:17:283:24 | SSA def(o) | D.cs:285:28:285:30 | {...} | +| D.cs:283:17:283:24 | SSA def(o) | D.cs:286:17:286:30 | ...; | +| D.cs:285:28:285:30 | {...} | D.cs:286:17:286:30 | ...; | +| D.cs:286:17:286:30 | ...; | D.cs:272:39:272:39 | access to local variable i | +| D.cs:290:9:291:25 | if (...) ... | D.cs:291:13:291:13 | access to local variable o | +| D.cs:290:9:291:25 | if (...) ... | D.cs:291:13:291:25 | ...; | +| D.cs:290:9:291:25 | if (...) ... | D.cs:293:9:294:25 | if (...) ... | +| D.cs:291:13:291:25 | ...; | D.cs:293:9:294:25 | if (...) ... | +| D.cs:293:9:294:25 | if (...) ... | D.cs:294:13:294:13 | access to local variable o | +| D.cs:296:16:296:26 | SSA def(prev) | D.cs:297:25:297:25 | access to local variable i | +| D.cs:297:25:297:25 | access to local variable i | D.cs:298:9:302:9 | {...} | +| D.cs:298:9:302:9 | {...} | D.cs:300:17:300:20 | access to local variable prev | +| D.cs:304:16:304:23 | SSA def(s) | D.cs:307:13:311:13 | foreach (... ... in ...) ... | +| D.cs:307:13:311:13 | foreach (... ... in ...) ... | D.cs:312:13:313:29 | if (...) ... | +| D.cs:312:13:313:29 | if (...) ... | D.cs:313:17:313:17 | access to local variable s | +| D.cs:316:16:316:23 | SSA def(r) | D.cs:318:16:318:62 | ... && ... | +| D.cs:318:16:318:62 | ... && ... | D.cs:318:41:318:44 | access to local variable stat | +| D.cs:318:16:318:62 | ... && ... | D.cs:324:9:324:9 | access to local variable r | +| D.cs:318:41:318:44 | access to local variable stat | D.cs:324:9:324:9 | access to local variable r | +| D.cs:351:15:351:22 | SSA def(a) | D.cs:355:9:356:21 | for (...;...;...) ... | +| D.cs:355:9:356:21 | for (...;...;...) ... | D.cs:355:25:355:25 | access to local variable i | +| D.cs:355:25:355:25 | access to local variable i | D.cs:356:13:356:13 | access to local variable a | +| D.cs:355:25:355:25 | access to local variable i | D.cs:356:13:356:21 | ...; | +| D.cs:356:13:356:21 | ...; | D.cs:355:25:355:25 | access to local variable i | +| D.cs:360:20:360:30 | SSA def(last) | D.cs:361:29:361:29 | access to local variable i | +| D.cs:361:29:361:29 | access to local variable i | D.cs:363:13:363:16 | access to local variable last | +| D.cs:366:15:366:47 | SSA def(b) | D.cs:370:9:373:9 | for (...;...;...) ... | +| D.cs:370:9:373:9 | for (...;...;...) ... | D.cs:370:25:370:25 | access to local variable i | +| D.cs:370:25:370:25 | access to local variable i | D.cs:371:9:373:9 | {...} | +| D.cs:370:25:370:25 | access to local variable i | D.cs:372:13:372:13 | access to local variable b | +| D.cs:371:9:373:9 | {...} | D.cs:370:25:370:25 | access to local variable i | +| D.cs:378:19:378:28 | SSA def(ioe) | D.cs:382:9:385:27 | if (...) ... | +| D.cs:382:9:385:27 | if (...) ... | D.cs:385:13:385:15 | access to local variable ioe | +| D.cs:388:36:388:36 | SSA param(a) | D.cs:390:32:390:32 | 0 | +| D.cs:388:45:388:45 | SSA param(b) | D.cs:390:32:390:32 | 0 | +| D.cs:388:45:388:45 | SSA param(b) | D.cs:390:36:390:36 | access to parameter a | +| D.cs:390:13:390:43 | Int32 alen = ... | D.cs:393:21:393:21 | access to local variable i | +| D.cs:390:13:390:43 | Int32 alen = ... | D.cs:393:21:393:21 | access to local variable i | +| D.cs:390:32:390:32 | 0 | D.cs:390:13:390:43 | Int32 alen = ... | +| D.cs:390:32:390:32 | 0 | D.cs:390:13:390:43 | Int32 alen = ... | +| D.cs:390:36:390:36 | access to parameter a | D.cs:390:13:390:43 | Int32 alen = ... | +| D.cs:393:21:393:21 | access to local variable i | D.cs:394:9:396:9 | {...} | +| D.cs:393:21:393:21 | access to local variable i | D.cs:394:9:396:9 | {...} | +| D.cs:393:21:393:21 | access to local variable i | D.cs:395:20:395:20 | access to parameter a | +| D.cs:393:21:393:21 | access to local variable i | D.cs:397:9:397:44 | ... ...; | +| D.cs:394:9:396:9 | {...} | D.cs:393:21:393:21 | access to local variable i | +| D.cs:394:9:396:9 | {...} | D.cs:393:21:393:21 | access to local variable i | +| D.cs:397:9:397:44 | ... ...; | D.cs:397:32:397:32 | 0 | +| D.cs:397:13:397:43 | Int32 blen = ... | D.cs:398:21:398:21 | access to local variable i | +| D.cs:397:32:397:32 | 0 | D.cs:397:13:397:43 | Int32 blen = ... | +| D.cs:398:21:398:21 | access to local variable i | D.cs:399:9:401:9 | {...} | +| D.cs:398:21:398:21 | access to local variable i | D.cs:400:20:400:20 | access to parameter b | +| D.cs:399:9:401:9 | {...} | D.cs:398:21:398:21 | access to local variable i | +| D.cs:405:35:405:35 | SSA param(x) | D.cs:407:42:407:63 | ... && ... | +| D.cs:405:35:405:35 | SSA param(x) | D.cs:407:42:407:63 | ... && ... | +| D.cs:405:35:405:35 | SSA param(x) | D.cs:407:42:407:63 | ... && ... | +| D.cs:405:45:405:45 | SSA param(y) | D.cs:407:42:407:63 | ... && ... | +| D.cs:405:45:405:45 | SSA param(y) | D.cs:407:42:407:63 | ... && ... | +| D.cs:405:45:405:45 | SSA param(y) | D.cs:407:42:407:63 | ... && ... | +| D.cs:407:42:407:63 | ... && ... | D.cs:407:55:407:55 | access to parameter y | +| D.cs:407:42:407:63 | ... && ... | D.cs:407:55:407:55 | access to parameter y | +| D.cs:407:42:407:63 | ... && ... | D.cs:409:9:410:25 | if (...) ... | +| D.cs:407:55:407:55 | access to parameter y | D.cs:409:9:410:25 | if (...) ... | +| D.cs:407:55:407:55 | access to parameter y | D.cs:409:9:410:25 | if (...) ... | +| D.cs:409:9:410:25 | if (...) ... | D.cs:410:13:410:13 | access to parameter y | +| D.cs:409:9:410:25 | if (...) ... | D.cs:411:9:412:25 | if (...) ... | +| D.cs:411:9:412:25 | if (...) ... | D.cs:412:13:412:13 | access to parameter x | +| E.cs:9:18:9:26 | SSA def(a2) | E.cs:10:13:10:54 | Boolean haveA2 = ... | +| E.cs:10:13:10:54 | Boolean haveA2 = ... | E.cs:12:38:12:39 | access to local variable a2 | +| E.cs:11:16:11:24 | SSA def(a3) | E.cs:12:13:12:52 | Boolean haveA3 = ... | +| E.cs:12:13:12:52 | Boolean haveA3 = ... | E.cs:14:13:14:14 | access to local variable a3 | +| E.cs:23:13:23:30 | SSA def(s1) | E.cs:24:33:24:36 | null | +| E.cs:24:13:24:41 | ... = ... | E.cs:26:9:27:26 | if (...) ... | +| E.cs:24:33:24:36 | null | E.cs:24:13:24:41 | ... = ... | +| E.cs:26:9:27:26 | if (...) ... | E.cs:27:13:27:14 | access to local variable s1 | +| E.cs:32:16:32:26 | SSA def(last) | E.cs:33:9:34:21 | foreach (... ... in ...) ... | +| E.cs:33:9:34:21 | foreach (... ... in ...) ... | E.cs:35:9:35:12 | access to local variable last | +| E.cs:37:9:37:19 | SSA def(last) | E.cs:39:9:44:9 | {...} | +| E.cs:39:9:44:9 | {...} | E.cs:40:13:41:25 | foreach (... ... in ...) ... | +| E.cs:40:13:41:25 | foreach (... ... in ...) ... | E.cs:43:13:43:16 | access to local variable last | +| E.cs:51:22:51:33 | SSA def(slice) | E.cs:53:16:53:19 | access to local variable iter | +| E.cs:53:16:53:19 | access to local variable iter | E.cs:54:9:63:9 | {...} | +| E.cs:54:9:63:9 | {...} | E.cs:61:13:61:17 | access to local variable slice | +| E.cs:54:9:63:9 | {...} | E.cs:61:13:61:27 | ...; | +| E.cs:61:13:61:27 | ...; | E.cs:53:16:53:19 | access to local variable iter | +| E.cs:66:40:66:42 | SSA param(arr) | E.cs:70:13:70:50 | ...; | +| E.cs:66:40:66:42 | SSA param(arr) | E.cs:72:9:73:23 | if (...) ... | +| E.cs:70:13:70:49 | ... = ... | E.cs:72:9:73:23 | if (...) ... | +| E.cs:70:13:70:50 | ...; | E.cs:70:36:70:36 | 0 | +| E.cs:70:36:70:36 | 0 | E.cs:70:13:70:49 | ... = ... | +| E.cs:72:9:73:23 | if (...) ... | E.cs:73:13:73:15 | access to parameter arr | +| E.cs:107:15:107:25 | SSA def(arr2) | E.cs:111:9:112:30 | for (...;...;...) ... | +| E.cs:111:9:112:30 | for (...;...;...) ... | E.cs:111:25:111:25 | access to local variable i | +| E.cs:111:25:111:25 | access to local variable i | E.cs:112:13:112:16 | access to local variable arr2 | +| E.cs:111:25:111:25 | access to local variable i | E.cs:112:13:112:30 | ...; | +| E.cs:112:13:112:30 | ...; | E.cs:111:25:111:25 | access to local variable i | +| E.cs:120:16:120:20 | !... | E.cs:121:9:143:9 | {...} | +| E.cs:121:9:143:9 | {...} | E.cs:123:20:123:35 | ... && ... | +| E.cs:123:20:123:35 | ... && ... | E.cs:120:16:120:20 | !... | +| E.cs:123:20:123:35 | ... && ... | E.cs:123:29:123:29 | access to local variable j | +| E.cs:123:29:123:29 | access to local variable j | E.cs:120:16:120:20 | !... | +| E.cs:123:29:123:29 | access to local variable j | E.cs:124:13:142:13 | {...} | +| E.cs:123:29:123:29 | access to local variable j | E.cs:125:33:125:35 | access to local variable obj | +| E.cs:124:13:142:13 | {...} | E.cs:128:21:128:23 | access to local variable obj | +| E.cs:124:13:142:13 | {...} | E.cs:141:17:141:26 | ...; | +| E.cs:137:25:137:34 | SSA def(obj) | E.cs:139:21:139:29 | continue; | +| E.cs:139:21:139:29 | continue; | E.cs:123:20:123:35 | ... && ... | +| E.cs:141:17:141:26 | ...; | E.cs:123:20:123:35 | ... && ... | +| E.cs:152:16:152:26 | SSA def(obj2) | E.cs:158:9:159:28 | if (...) ... | +| E.cs:158:9:159:28 | if (...) ... | E.cs:159:13:159:16 | access to local variable obj2 | +| E.cs:162:28:162:28 | SSA param(a) | E.cs:164:29:164:29 | 0 | +| E.cs:164:13:164:40 | Int32 n = ... | E.cs:165:25:165:25 | access to local variable i | +| E.cs:164:29:164:29 | 0 | E.cs:164:13:164:40 | Int32 n = ... | +| E.cs:165:25:165:25 | access to local variable i | E.cs:166:9:170:9 | {...} | +| E.cs:165:25:165:25 | access to local variable i | E.cs:167:21:167:21 | access to parameter a | +| E.cs:165:32:165:32 | access to local variable i | E.cs:165:25:165:25 | access to local variable i | +| E.cs:166:9:170:9 | {...} | E.cs:165:32:165:32 | access to local variable i | +| E.cs:173:29:173:31 | SSA param(obj) | E.cs:175:33:175:37 | false | +| E.cs:173:29:173:31 | SSA param(obj) | E.cs:175:33:175:37 | false | +| E.cs:175:14:175:42 | Boolean b2 = ... | E.cs:177:9:179:9 | {...} | +| E.cs:175:14:175:42 | Boolean b2 = ... | E.cs:178:13:178:15 | access to parameter obj | +| E.cs:175:14:175:42 | Boolean b2 = ... | E.cs:180:9:183:9 | if (...) ... | +| E.cs:175:33:175:37 | false | E.cs:175:14:175:42 | Boolean b2 = ... | +| E.cs:177:9:179:9 | {...} | E.cs:180:9:183:9 | if (...) ... | +| E.cs:180:9:183:9 | if (...) ... | E.cs:181:9:183:9 | {...} | +| E.cs:181:9:183:9 | {...} | E.cs:184:9:187:9 | if (...) ... | +| E.cs:184:9:187:9 | if (...) ... | E.cs:186:13:186:15 | access to parameter obj | +| E.cs:190:29:190:29 | SSA param(o) | E.cs:192:17:192:17 | access to parameter o | +| E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) | E.cs:203:11:203:11 | access to local variable o | +| E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) | E.cs:201:11:201:11 | access to local variable o | +| E.cs:206:28:206:28 | SSA param(s) | E.cs:210:16:210:16 | access to parameter s | +| E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:218:9:218:9 | access to local variable x | +| E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:220:13:220:13 | access to local variable x | +| E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | E.cs:229:13:229:13 | access to local variable x | +| E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | E.cs:230:9:230:9 | access to local variable x | +| E.cs:233:26:233:26 | SSA param(i) | E.cs:235:16:235:16 | access to parameter i | +| E.cs:238:26:238:26 | SSA param(i) | E.cs:240:21:240:21 | access to parameter i | +| E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | +| E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | +| Forwarding.cs:7:16:7:23 | SSA def(s) | Forwarding.cs:14:9:17:9 | if (...) ... | +| Forwarding.cs:14:9:17:9 | if (...) ... | Forwarding.cs:19:9:22:9 | if (...) ... | +| Forwarding.cs:19:9:22:9 | if (...) ... | Forwarding.cs:24:9:27:9 | if (...) ... | +| Forwarding.cs:24:9:27:9 | if (...) ... | Forwarding.cs:29:9:32:9 | if (...) ... | +| Forwarding.cs:29:9:32:9 | if (...) ... | Forwarding.cs:34:9:37:9 | if (...) ... | +| Forwarding.cs:34:9:37:9 | if (...) ... | Forwarding.cs:35:9:37:9 | {...} | +| Forwarding.cs:34:9:37:9 | if (...) ... | Forwarding.cs:36:31:36:31 | access to local variable s | +| Forwarding.cs:35:9:37:9 | {...} | Forwarding.cs:40:27:40:27 | access to local variable s | +| GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:14:9:17:9 | if (...) ... | +| GuardedString.cs:14:9:17:9 | if (...) ... | GuardedString.cs:19:9:20:40 | if (...) ... | +| GuardedString.cs:19:9:20:40 | if (...) ... | GuardedString.cs:19:26:19:26 | 0 | +| GuardedString.cs:19:26:19:26 | 0 | GuardedString.cs:22:9:23:40 | if (...) ... | +| GuardedString.cs:22:9:23:40 | if (...) ... | GuardedString.cs:22:25:22:25 | 0 | +| GuardedString.cs:22:25:22:25 | 0 | GuardedString.cs:25:9:26:40 | if (...) ... | +| GuardedString.cs:25:9:26:40 | if (...) ... | GuardedString.cs:25:26:25:26 | 0 | +| GuardedString.cs:25:26:25:26 | 0 | GuardedString.cs:28:9:29:40 | if (...) ... | +| GuardedString.cs:28:9:29:40 | if (...) ... | GuardedString.cs:28:25:28:26 | 10 | +| GuardedString.cs:28:25:28:26 | 10 | GuardedString.cs:31:9:32:40 | if (...) ... | +| GuardedString.cs:31:9:32:40 | if (...) ... | GuardedString.cs:31:26:31:27 | 10 | +| GuardedString.cs:31:26:31:27 | 10 | GuardedString.cs:34:9:37:40 | if (...) ... | +| GuardedString.cs:34:9:37:40 | if (...) ... | GuardedString.cs:34:26:34:26 | 0 | +| GuardedString.cs:34:26:34:26 | 0 | GuardedString.cs:35:31:35:31 | access to local variable s | +| NullAlwaysBad.cs:7:29:7:29 | SSA param(s) | NullAlwaysBad.cs:9:30:9:30 | access to parameter s | +| NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o | +| StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:15:16:15:16 | access to local variable s | +| StringConcatenation.cs:15:16:15:16 | access to local variable s | StringConcatenation.cs:16:17:16:17 | access to local variable s | +#select +| C.cs:64:9:64:10 | access to local variable o1 | C.cs:62:13:62:46 | SSA def(o1) | C.cs:64:9:64:10 | access to local variable o1 | Variable $@ may be null here because of $@ assignment. | C.cs:62:13:62:14 | o1 | o1 | C.cs:62:13:62:46 | Object o1 = ... | this | +| C.cs:68:9:68:10 | access to local variable o2 | C.cs:66:13:66:46 | SSA def(o2) | C.cs:68:9:68:10 | access to local variable o2 | Variable $@ may be null here because of $@ assignment. | C.cs:66:13:66:14 | o2 | o2 | C.cs:66:13:66:46 | Object o2 = ... | this | +| C.cs:96:15:96:15 | access to local variable o | C.cs:95:13:95:45 | SSA def(o) | C.cs:96:15:96:15 | access to local variable o | Variable $@ may be null here because of $@ assignment. | C.cs:95:13:95:13 | o | o | C.cs:95:13:95:45 | Object o = ... | this | +| C.cs:104:27:104:30 | access to parameter list | C.cs:103:13:103:23 | SSA def(list) | C.cs:104:27:104:30 | access to parameter list | Variable $@ may be null here because of $@ assignment. | C.cs:100:42:100:45 | list | list | C.cs:103:13:103:23 | ... = ... | this | +| C.cs:178:13:178:13 | access to local variable s | C.cs:179:13:179:20 | SSA def(s) | C.cs:178:13:178:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:152:13:152:13 | s | s | C.cs:179:13:179:20 | ... = ... | this | +| C.cs:204:13:204:13 | access to local variable s | C.cs:205:13:205:20 | SSA def(s) | C.cs:204:13:204:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:186:13:186:13 | s | s | C.cs:205:13:205:20 | ... = ... | this | +| C.cs:224:9:224:9 | access to local variable s | C.cs:223:13:223:20 | SSA def(s) | C.cs:224:9:224:9 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:211:13:211:13 | s | s | C.cs:223:13:223:20 | ... = ... | this | +| C.cs:243:13:243:13 | access to local variable s | C.cs:241:24:241:31 | SSA def(s) | C.cs:243:13:243:13 | access to local variable s | Variable $@ may be null here because of $@ assignment. | C.cs:229:16:229:16 | s | s | C.cs:241:24:241:31 | ... = ... | this | +| D.cs:23:9:23:13 | access to parameter param | D.cs:17:17:17:20 | null | D.cs:23:9:23:13 | access to parameter param | Variable $@ may be null here because of $@ null argument. | D.cs:21:32:21:36 | param | param | D.cs:17:17:17:20 | null | this | +| D.cs:32:9:32:13 | access to parameter param | D.cs:26:32:26:36 | SSA param(param) | D.cs:32:9:32:13 | access to parameter param | Variable $@ may be null here as suggested by $@ null check. | D.cs:26:32:26:36 | param | param | D.cs:28:13:28:25 | ... != ... | this | +| D.cs:62:13:62:14 | access to local variable o5 | D.cs:58:13:58:41 | SSA def(o5) | D.cs:62:13:62:14 | access to local variable o5 | Variable $@ may be null here because of $@ assignment. | D.cs:58:13:58:14 | o5 | o5 | D.cs:58:13:58:41 | String o5 = ... | this | +| D.cs:73:13:73:14 | access to local variable o7 | D.cs:68:13:68:34 | SSA def(o7) | D.cs:73:13:73:14 | access to local variable o7 | Variable $@ may be null here because of $@ assignment. | D.cs:68:13:68:14 | o7 | o7 | D.cs:68:13:68:34 | String o7 = ... | this | +| D.cs:82:13:82:14 | access to local variable o8 | D.cs:75:13:75:34 | SSA def(o8) | D.cs:82:13:82:14 | access to local variable o8 | Variable $@ may be null here because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this | +| D.cs:84:13:84:14 | access to local variable o8 | D.cs:75:13:75:34 | SSA def(o8) | D.cs:84:13:84:14 | access to local variable o8 | Variable $@ may be null here because of $@ assignment. | D.cs:75:13:75:14 | o8 | o8 | D.cs:75:13:75:34 | String o8 = ... | this | +| D.cs:91:13:91:14 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:91:13:91:14 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | +| D.cs:94:21:94:22 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:94:21:94:22 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | +| D.cs:98:21:98:22 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:98:21:98:22 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | +| D.cs:102:31:102:32 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:102:31:102:32 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | +| D.cs:105:19:105:20 | access to local variable xs | D.cs:89:15:89:44 | SSA def(xs) | D.cs:105:19:105:20 | access to local variable xs | Variable $@ may be null here because of $@ assignment. | D.cs:89:15:89:16 | xs | xs | D.cs:89:15:89:44 | Int32[] xs = ... | this | +| D.cs:134:24:134:24 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this | +| D.cs:134:24:134:24 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:134:24:134:24 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this | +| D.cs:135:24:135:24 | access to parameter b | D.cs:125:44:125:44 | SSA param(b) | D.cs:135:24:135:24 | access to parameter b | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:44:125:44 | b | b | D.cs:128:20:128:28 | ... == ... | this | +| D.cs:145:20:145:20 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:127:20:127:28 | ... == ... | this | +| D.cs:145:20:145:20 | access to parameter a | D.cs:125:35:125:35 | SSA param(a) | D.cs:145:20:145:20 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:125:35:125:35 | a | a | D.cs:139:13:139:21 | ... != ... | this | +| D.cs:151:9:151:11 | access to parameter obj | D.cs:149:36:149:38 | SSA param(obj) | D.cs:151:9:151:11 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | D.cs:149:36:149:38 | obj | obj | D.cs:152:17:152:27 | ... != ... | this | +| D.cs:171:9:171:11 | access to local variable obj | D.cs:163:16:163:25 | SSA def(obj) | D.cs:171:9:171:11 | access to local variable obj | Variable $@ may be null here because of $@ assignment. | D.cs:163:16:163:18 | obj | obj | D.cs:163:16:163:25 | Object obj = ... | this | +| D.cs:245:13:245:13 | access to local variable o | D.cs:240:9:240:16 | SSA def(o) | D.cs:245:13:245:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this | +| D.cs:247:13:247:13 | access to local variable o | D.cs:240:9:240:16 | SSA def(o) | D.cs:247:13:247:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:228:16:228:16 | o | o | D.cs:240:9:240:16 | ... = ... | this | +| D.cs:253:13:253:14 | access to local variable o2 | D.cs:249:13:249:38 | SSA def(o2) | D.cs:253:13:253:14 | access to local variable o2 | Variable $@ may be null here because of $@ assignment. | D.cs:249:13:249:14 | o2 | o2 | D.cs:249:13:249:38 | String o2 = ... | this | +| D.cs:267:13:267:13 | access to local variable o | D.cs:258:16:258:23 | SSA def(o) | D.cs:267:13:267:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:258:16:258:23 | Object o = ... | this | +| D.cs:291:13:291:13 | access to local variable o | D.cs:269:9:269:16 | SSA def(o) | D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this | +| D.cs:291:13:291:13 | access to local variable o | D.cs:283:17:283:24 | SSA def(o) | D.cs:291:13:291:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this | +| D.cs:294:13:294:13 | access to local variable o | D.cs:269:9:269:16 | SSA def(o) | D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:269:9:269:16 | ... = ... | this | +| D.cs:294:13:294:13 | access to local variable o | D.cs:283:17:283:24 | SSA def(o) | D.cs:294:13:294:13 | access to local variable o | Variable $@ may be null here because of $@ assignment. | D.cs:258:16:258:16 | o | o | D.cs:283:17:283:24 | ... = ... | this | +| D.cs:300:17:300:20 | access to local variable prev | D.cs:296:16:296:26 | SSA def(prev) | D.cs:300:17:300:20 | access to local variable prev | Variable $@ may be null here because of $@ assignment. | D.cs:296:16:296:19 | prev | prev | D.cs:296:16:296:26 | Object prev = ... | this | +| D.cs:313:17:313:17 | access to local variable s | D.cs:304:16:304:23 | SSA def(s) | D.cs:313:17:313:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | D.cs:304:16:304:16 | s | s | D.cs:304:16:304:23 | String s = ... | this | +| D.cs:324:9:324:9 | access to local variable r | D.cs:316:16:316:23 | SSA def(r) | D.cs:324:9:324:9 | access to local variable r | Variable $@ may be null here because of $@ assignment. | D.cs:316:16:316:16 | r | r | D.cs:316:16:316:23 | Object r = ... | this | +| D.cs:356:13:356:13 | access to local variable a | D.cs:351:15:351:22 | SSA def(a) | D.cs:356:13:356:13 | access to local variable a | Variable $@ may be null here because of $@ assignment. | D.cs:351:15:351:15 | a | a | D.cs:351:15:351:22 | Int32[] a = ... | this | +| D.cs:363:13:363:16 | access to local variable last | D.cs:360:20:360:30 | SSA def(last) | D.cs:363:13:363:16 | access to local variable last | Variable $@ may be null here because of $@ assignment. | D.cs:360:20:360:23 | last | last | D.cs:360:20:360:30 | String last = ... | this | +| D.cs:372:13:372:13 | access to local variable b | D.cs:366:15:366:47 | SSA def(b) | D.cs:372:13:372:13 | access to local variable b | Variable $@ may be null here because of $@ assignment. | D.cs:366:15:366:15 | b | b | D.cs:366:15:366:47 | Int32[] b = ... | this | +| D.cs:395:20:395:20 | access to parameter a | D.cs:388:36:388:36 | SSA param(a) | D.cs:395:20:395:20 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | D.cs:388:36:388:36 | a | a | D.cs:390:20:390:28 | ... == ... | this | +| D.cs:400:20:400:20 | access to parameter b | D.cs:388:45:388:45 | SSA param(b) | D.cs:400:20:400:20 | access to parameter b | Variable $@ may be null here as suggested by $@ null check. | D.cs:388:45:388:45 | b | b | D.cs:397:20:397:28 | ... == ... | this | +| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:27:407:35 | ... == ... | this | +| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:407:55:407:63 | ... != ... | this | +| D.cs:410:13:410:13 | access to parameter y | D.cs:405:45:405:45 | SSA param(y) | D.cs:410:13:410:13 | access to parameter y | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:45:405:45 | y | y | D.cs:411:13:411:21 | ... != ... | this | +| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:14:407:22 | ... != ... | this | +| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:407:42:407:50 | ... == ... | this | +| D.cs:412:13:412:13 | access to parameter x | D.cs:405:35:405:35 | SSA param(x) | D.cs:412:13:412:13 | access to parameter x | Variable $@ may be null here as suggested by $@ null check. | D.cs:405:35:405:35 | x | x | D.cs:409:13:409:21 | ... != ... | this | +| E.cs:12:38:12:39 | access to local variable a2 | E.cs:9:18:9:26 | SSA def(a2) | E.cs:12:38:12:39 | access to local variable a2 | Variable $@ may be null here because of $@ assignment. | E.cs:9:18:9:19 | a2 | a2 | E.cs:9:18:9:26 | Int64[][] a2 = ... | this | +| E.cs:14:13:14:14 | access to local variable a3 | E.cs:11:16:11:24 | SSA def(a3) | E.cs:14:13:14:14 | access to local variable a3 | Variable $@ may be null here because of $@ assignment. | E.cs:11:16:11:17 | a3 | a3 | E.cs:11:16:11:24 | Int64[] a3 = ... | this | +| E.cs:27:13:27:14 | access to local variable s1 | E.cs:23:13:23:30 | SSA def(s1) | E.cs:27:13:27:14 | access to local variable s1 | Variable $@ may be null here because of $@ assignment. | E.cs:19:13:19:14 | s1 | s1 | E.cs:23:13:23:30 | ... = ... | this | +| E.cs:35:9:35:12 | access to local variable last | E.cs:32:16:32:26 | SSA def(last) | E.cs:35:9:35:12 | access to local variable last | Variable $@ may be null here because of $@ assignment. | E.cs:32:16:32:19 | last | last | E.cs:32:16:32:26 | String last = ... | this | +| E.cs:43:13:43:16 | access to local variable last | E.cs:37:9:37:19 | SSA def(last) | E.cs:43:13:43:16 | access to local variable last | Variable $@ may be null here because of $@ assignment. | E.cs:32:16:32:19 | last | last | E.cs:37:9:37:19 | ... = ... | this | +| E.cs:61:13:61:17 | access to local variable slice | E.cs:51:22:51:33 | SSA def(slice) | E.cs:61:13:61:17 | access to local variable slice | Variable $@ may be null here because of $@ assignment. | E.cs:51:22:51:26 | slice | slice | E.cs:51:22:51:33 | List slice = ... | this | +| E.cs:73:13:73:15 | access to parameter arr | E.cs:66:40:66:42 | SSA param(arr) | E.cs:73:13:73:15 | access to parameter arr | Variable $@ may be null here as suggested by $@ null check. | E.cs:66:40:66:42 | arr | arr | E.cs:70:22:70:32 | ... == ... | this | +| E.cs:112:13:112:16 | access to local variable arr2 | E.cs:107:15:107:25 | SSA def(arr2) | E.cs:112:13:112:16 | access to local variable arr2 | Variable $@ may be null here because of $@ assignment. | E.cs:107:15:107:18 | arr2 | arr2 | E.cs:107:15:107:25 | Int32[] arr2 = ... | this | +| E.cs:125:33:125:35 | access to local variable obj | E.cs:137:25:137:34 | SSA def(obj) | E.cs:125:33:125:35 | access to local variable obj | Variable $@ may be null here because of $@ assignment. | E.cs:119:13:119:15 | obj | obj | E.cs:137:25:137:34 | ... = ... | this | +| E.cs:159:13:159:16 | access to local variable obj2 | E.cs:152:16:152:26 | SSA def(obj2) | E.cs:159:13:159:16 | access to local variable obj2 | Variable $@ may be null here as suggested by $@ null check. | E.cs:152:16:152:19 | obj2 | obj2 | E.cs:153:13:153:24 | ... != ... | this | +| E.cs:167:21:167:21 | access to parameter a | E.cs:162:28:162:28 | SSA param(a) | E.cs:167:21:167:21 | access to parameter a | Variable $@ may be null here as suggested by $@ null check. | E.cs:162:28:162:28 | a | a | E.cs:164:17:164:25 | ... == ... | this | +| E.cs:178:13:178:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this | +| E.cs:178:13:178:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:178:13:178:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this | +| E.cs:186:13:186:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:175:19:175:29 | ... == ... | this | +| E.cs:186:13:186:15 | access to parameter obj | E.cs:173:29:173:31 | SSA param(obj) | E.cs:186:13:186:15 | access to parameter obj | Variable $@ may be null here as suggested by $@ null check. | E.cs:173:29:173:31 | obj | obj | E.cs:180:13:180:23 | ... == ... | this | +| E.cs:192:17:192:17 | access to parameter o | E.cs:190:29:190:29 | SSA param(o) | E.cs:192:17:192:17 | access to parameter o | Variable $@ may be null here as suggested by $@ null check. | E.cs:190:29:190:29 | o | o | E.cs:193:17:193:17 | access to parameter o | this | +| E.cs:201:11:201:11 | access to local variable o | E.cs:198:13:198:29 | [b (line 196): true] SSA def(o) | E.cs:201:11:201:11 | access to local variable o | Variable $@ may be null here because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this | +| E.cs:203:11:203:11 | access to local variable o | E.cs:198:13:198:29 | [b (line 196): false] SSA def(o) | E.cs:203:11:203:11 | access to local variable o | Variable $@ may be null here because of $@ assignment. | E.cs:198:13:198:13 | o | o | E.cs:198:13:198:29 | String o = ... | this | +| E.cs:218:9:218:9 | access to local variable x | E.cs:217:13:217:20 | [b (line 213): true] SSA def(x) | E.cs:218:9:218:9 | access to local variable x | Variable $@ may be null here because of $@ assignment. | E.cs:215:13:215:13 | x | x | E.cs:217:13:217:20 | ... = ... | this | +| E.cs:230:9:230:9 | access to local variable x | E.cs:227:13:227:20 | [b (line 223): true] SSA def(x) | E.cs:230:9:230:9 | access to local variable x | Variable $@ may be null here because of $@ assignment. | E.cs:225:13:225:13 | x | x | E.cs:227:13:227:20 | ... = ... | this | +| E.cs:235:16:235:16 | access to parameter i | E.cs:233:26:233:26 | SSA param(i) | E.cs:235:16:235:16 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:233:26:233:26 | i | i | E.cs:233:26:233:26 | i | this | +| E.cs:240:21:240:21 | access to parameter i | E.cs:238:26:238:26 | SSA param(i) | E.cs:240:21:240:21 | access to parameter i | Variable $@ may be null here because it has a nullable type. | E.cs:238:26:238:26 | i | i | E.cs:238:26:238:26 | i | this | +| E.cs:285:9:285:9 | access to local variable o | E.cs:283:13:283:22 | [b (line 279): false] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this | +| E.cs:285:9:285:9 | access to local variable o | E.cs:283:13:283:22 | [b (line 279): true] SSA def(o) | E.cs:285:9:285:9 | access to local variable o | Variable $@ may be null here as suggested by $@ null check. | E.cs:283:13:283:13 | o | o | E.cs:284:9:284:9 | access to local variable o | this | +| GuardedString.cs:35:31:35:31 | access to local variable s | GuardedString.cs:7:16:7:32 | SSA def(s) | GuardedString.cs:35:31:35:31 | access to local variable s | Variable $@ may be null here because of $@ assignment. | GuardedString.cs:7:16:7:16 | s | s | GuardedString.cs:7:16:7:32 | String s = ... | this | +| NullMaybeBad.cs:7:27:7:27 | access to parameter o | NullMaybeBad.cs:13:17:13:20 | null | NullMaybeBad.cs:7:27:7:27 | access to parameter o | Variable $@ may be null here because of $@ null argument. | NullMaybeBad.cs:5:25:5:25 | o | o | NullMaybeBad.cs:13:17:13:20 | null | this | +| StringConcatenation.cs:16:17:16:17 | access to local variable s | StringConcatenation.cs:14:16:14:23 | SSA def(s) | StringConcatenation.cs:16:17:16:17 | access to local variable s | Variable $@ may be null here because of $@ assignment. | StringConcatenation.cs:14:16:14:16 | s | s | StringConcatenation.cs:14:16:14:23 | String s = ... | this | From 3a5962aa347a34bc08964a29adb2b0e61fbef00a Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Fri, 14 Dec 2018 13:14:26 +0100 Subject: [PATCH 20/69] JS: minor fixups in ClientRequests.qll --- .../src/semmle/javascript/frameworks/ClientRequests.qll | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll index 596e5e3bf1a8..93196d346c6b 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll @@ -67,7 +67,7 @@ private string httpMethodName() { } /** - * Gets the name of a property that likely contains a URL value. + * Gets the name of a property that likely contains a URL value. */ private string urlPropertyName() { result = "uri" or @@ -93,16 +93,13 @@ private class RequestUrlRequest extends CustomClientRequest { ( callee = DataFlow::moduleImport(moduleName) or callee = DataFlow::moduleMember(moduleName, httpMethodName()) - ) and - ( - url = getArgument(0) or - url = getOptionArgument(0, urlPropertyName()) ) ) } override DataFlow::Node getUrl() { - result = url + result = getArgument(0) or + result = getOptionArgument(0, urlPropertyName()) } override DataFlow::Node getADataNode() { From 60fe0176ede763b1b093d08ec6c0e705462b9f97 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Mon, 17 Dec 2018 10:28:01 +0100 Subject: [PATCH 21/69] JS: add ClientRequest::getHost --- .../javascript/frameworks/ClientRequests.qll | 41 ++++++++++++++++++- .../semmle/javascript/frameworks/Electron.qll | 8 ++++ .../javascript/frameworks/NodeJSLib.qll | 8 ++++ .../semmle/javascript/frameworks/jQuery.qll | 2 + .../ClientRequests/ClientRequest.expected | 4 ++ .../ClientRequest_getHost.expected | 4 ++ .../ClientRequests/ClientRequest_getHost.ql | 4 ++ .../ClientRequest_getUrl.expected | 4 ++ .../frameworks/ClientRequests/tst.js | 12 ++++++ 9 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.expected create mode 100644 javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.ql diff --git a/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll b/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll index 93196d346c6b..ee62d6035fc1 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/ClientRequests.qll @@ -21,6 +21,11 @@ abstract class CustomClientRequest extends DataFlow::InvokeNode { */ abstract DataFlow::Node getUrl(); + /** + * Gets the host of the request. + */ + abstract DataFlow::Node getHost(); + /** * Gets a node that contributes to the data-part this request. */ @@ -50,6 +55,13 @@ class ClientRequest extends DataFlow::InvokeNode { result = custom.getUrl() } + /** + * Gets the host of the request. + */ + DataFlow::Node getHost() { + result = custom.getHost() + } + /** * Gets a node that contributes to the data-part this request. */ @@ -102,6 +114,10 @@ private class RequestUrlRequest extends CustomClientRequest { result = getOptionArgument(0, urlPropertyName()) } + override DataFlow::Node getHost() { + none() + } + override DataFlow::Node getADataNode() { result = getArgument(1) } @@ -126,10 +142,18 @@ private class AxiosUrlRequest extends CustomClientRequest { ) } + private DataFlow::Node getOptionArgument(string name) { + // depends on the method name and the call arity, over-approximating slightly in the name of simplicity + result = getOptionArgument([0..2], name) + } + override DataFlow::Node getUrl() { result = getArgument(0) or - // depends on the method name and the call arity, over-approximating slightly in the name of simplicity - result = getOptionArgument([0..2], urlPropertyName()) + result = getOptionArgument(urlPropertyName()) + } + + override DataFlow::Node getHost() { + result = getOptionArgument("host") } override DataFlow::Node getADataNode() { @@ -176,6 +200,8 @@ private class FetchUrlRequest extends CustomClientRequest { result = url } + override DataFlow::Node getHost() { none() } + override DataFlow::Node getADataNode() { exists (string name | name = "headers" or name = "body" | @@ -206,6 +232,14 @@ private class GotUrlRequest extends CustomClientRequest { not exists (getOptionArgument(1, "baseUrl")) } + override DataFlow::Node getHost() { + exists (string name | + name = "host" or + name = "hostname" | + result = getOptionArgument(1, name) + ) + } + override DataFlow::Node getADataNode() { exists (string name | name = "headers" or name = "body" or name = "query" | @@ -235,6 +269,8 @@ private class SuperAgentUrlRequest extends CustomClientRequest { result = url } + override DataFlow::Node getHost() { none() } + override DataFlow::Node getADataNode() { exists (string name | name = "set" or name = "send" or name = "query" | @@ -252,5 +288,6 @@ private class XMLHttpRequest extends CustomClientRequest { override DataFlow::Node getUrl() { result = getAMethodCall("open").getArgument(1) } + override DataFlow::Node getHost() { none() } override DataFlow::Node getADataNode() { result = getAMethodCall("send").getArgument(0) } } diff --git a/javascript/ql/src/semmle/javascript/frameworks/Electron.qll b/javascript/ql/src/semmle/javascript/frameworks/Electron.qll index 454de0a11d7d..fe8010d8fc89 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Electron.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Electron.qll @@ -64,6 +64,14 @@ module Electron { result = getOptionArgument(0, "url") } + override DataFlow::Node getHost() { + exists (string name | + name = "host" or + name = "hostname" | + result = getOptionArgument(0, name) + ) + } + override DataFlow::Node getADataNode() { exists (string name | name = "write" or name = "end" | diff --git a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll index 35091d9c2180..a7355f3c4b37 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/NodeJSLib.qll @@ -737,6 +737,14 @@ module NodeJSLib { result = url } + override DataFlow::Node getHost() { + exists (string name | + name = "host" or + name = "hostname" | + result = getOptionArgument(1, name) + ) + } + override DataFlow::Node getADataNode() { exists (string name | name = "write" or name = "end" | diff --git a/javascript/ql/src/semmle/javascript/frameworks/jQuery.qll b/javascript/ql/src/semmle/javascript/frameworks/jQuery.qll index ab923574207d..92906282d0dc 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/jQuery.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/jQuery.qll @@ -359,5 +359,7 @@ private class JQueryClientRequest extends CustomClientRequest { result = getOptionArgument([0 .. 1], "url") } + override DataFlow::Node getHost() { none() } + override DataFlow::Node getADataNode() { result = getOptionArgument([0 .. 1], "data") } } diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest.expected index a52f0fa500d2..9346e9f7e4b9 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest.expected @@ -32,3 +32,7 @@ | tst.js:77:5:77:32 | $.getJS ... data}) | | tst.js:78:5:78:38 | $.getJS ... data}) | | tst.js:80:15:80:34 | new XMLHttpRequest() | +| tst.js:87:5:87:39 | http.ge ... host}) | +| tst.js:89:5:89:23 | axios({host: host}) | +| tst.js:91:5:91:34 | got(rel ... host}) | +| tst.js:93:5:93:35 | net.req ... host }) | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.expected new file mode 100644 index 000000000000..025cf360ac29 --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.expected @@ -0,0 +1,4 @@ +| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:34:87:37 | host | +| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:18:89:21 | host | +| tst.js:91:5:91:34 | got(rel ... host}) | tst.js:91:29:91:32 | host | +| tst.js:93:5:93:35 | net.req ... host }) | tst.js:93:29:93:32 | host | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.ql b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.ql new file mode 100644 index 000000000000..95d6776570f3 --- /dev/null +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getHost.ql @@ -0,0 +1,4 @@ +import javascript + +from ClientRequest r +select r, r.getHost() \ No newline at end of file diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getUrl.expected b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getUrl.expected index f9e4de1ee213..7bc692a0d7a5 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getUrl.expected +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/ClientRequest_getUrl.expected @@ -38,3 +38,7 @@ | tst.js:78:5:78:38 | $.getJS ... data}) | tst.js:78:15:78:37 | {url: u ... : data} | | tst.js:78:5:78:38 | $.getJS ... data}) | tst.js:78:21:78:23 | url | | tst.js:80:15:80:34 | new XMLHttpRequest() | tst.js:81:17:81:19 | url | +| tst.js:87:5:87:39 | http.ge ... host}) | tst.js:87:14:87:24 | relativeUrl | +| tst.js:89:5:89:23 | axios({host: host}) | tst.js:89:11:89:22 | {host: host} | +| tst.js:91:5:91:34 | got(rel ... host}) | tst.js:91:9:91:19 | relativeUrl | +| tst.js:93:5:93:35 | net.req ... host }) | tst.js:93:17:93:34 | { hostname: host } | diff --git a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js index ee638893a527..34a5bea9ed50 100644 --- a/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js +++ b/javascript/ql/test/library-tests/frameworks/ClientRequests/tst.js @@ -81,3 +81,15 @@ import {ClientRequest, net} from 'electron'; xhr.open(_, url); xhr.send(data); }); + +(function() { + + http.get(relativeUrl, {host: host}); + + axios({host: host}); + + got(relativeUrl, {host: host}); + + net.request({ hostname: host }); + +}); From c6b4e29b93a170ff0c92574adcf2b85dd297706d Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Mon, 17 Dec 2018 10:06:15 +0100 Subject: [PATCH 22/69] JS: add "host" as a sink for `js/request-forgery` --- .../javascript/security/dataflow/RequestForgery.qll | 8 ++++++-- .../query-tests/Security/CWE-918/RequestForgery.expected | 3 +++ javascript/ql/test/query-tests/Security/CWE-918/tst.js | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/RequestForgery.qll b/javascript/ql/src/semmle/javascript/security/dataflow/RequestForgery.qll index 6881382672ab..4a24bff2c28c 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/RequestForgery.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/RequestForgery.qll @@ -72,8 +72,11 @@ module RequestForgery { ClientRequest request; + string kind; + ClientRequestUrlAsSink() { - this = request.getUrl() + this = request.getUrl() and kind = "URL" or + this = request.getHost() and kind = "host" } override DataFlow::Node getARequest() { @@ -81,7 +84,8 @@ module RequestForgery { } override string getKind() { - result = "URL" + result = kind } + } } diff --git a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected index b4368363730a..2947bcf824f6 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected +++ b/javascript/ql/test/query-tests/Security/CWE-918/RequestForgery.expected @@ -13,6 +13,7 @@ nodes | tst.js:26:36:26:42 | tainted | | tst.js:28:13:28:43 | "http:/ ... tainted | | tst.js:28:37:28:43 | tainted | +| tst.js:32:34:32:40 | tainted | edges | tst.js:12:9:12:52 | tainted | tst.js:16:13:16:19 | tainted | | tst.js:12:9:12:52 | tainted | tst.js:18:17:18:23 | tainted | @@ -20,6 +21,7 @@ edges | tst.js:12:9:12:52 | tainted | tst.js:24:25:24:31 | tainted | | tst.js:12:9:12:52 | tainted | tst.js:26:36:26:42 | tainted | | tst.js:12:9:12:52 | tainted | tst.js:28:37:28:43 | tainted | +| tst.js:12:9:12:52 | tainted | tst.js:32:34:32:40 | tainted | | tst.js:12:19:12:42 | url.par ... , true) | tst.js:12:19:12:48 | url.par ... ).query | | tst.js:12:19:12:48 | url.par ... ).query | tst.js:12:19:12:52 | url.par ... ery.url | | tst.js:12:19:12:52 | url.par ... ery.url | tst.js:12:9:12:52 | tainted | @@ -34,3 +36,4 @@ edges | tst.js:24:5:24:32 | request ... ainted) | tst.js:12:29:12:35 | req.url | tst.js:24:13:24:31 | "http://" + tainted | The $@ of this request depends on $@. | tst.js:24:13:24:31 | "http://" + tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value | | tst.js:26:5:26:43 | request ... ainted) | tst.js:12:29:12:35 | req.url | tst.js:26:13:26:42 | "http:/ ... tainted | The $@ of this request depends on $@. | tst.js:26:13:26:42 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value | | tst.js:28:5:28:44 | request ... ainted) | tst.js:12:29:12:35 | req.url | tst.js:28:13:28:43 | "http:/ ... tainted | The $@ of this request depends on $@. | tst.js:28:13:28:43 | "http:/ ... tainted | URL | tst.js:12:29:12:35 | req.url | a user-provided value | +| tst.js:32:5:32:42 | http.ge ... inted}) | tst.js:12:29:12:35 | req.url | tst.js:32:34:32:40 | tainted | The $@ of this request depends on $@. | tst.js:32:34:32:40 | tainted | host | tst.js:12:29:12:35 | req.url | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-918/tst.js b/javascript/ql/test/query-tests/Security/CWE-918/tst.js index b502e56bd12f..3ef100e3960f 100644 --- a/javascript/ql/test/query-tests/Security/CWE-918/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-918/tst.js @@ -28,4 +28,6 @@ var server = http.createServer(function(req, res) { request("http://example.com/" + tainted); // NOT OK request("http://example.com/?" + tainted); // OK + + http.get(relativeUrl, {host: tainted}); // NOT OK }) From 3cd62234d4b4604b563cb853ce33834c40d3b2e9 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Fri, 14 Dec 2018 13:20:29 +0100 Subject: [PATCH 23/69] JS: change notes for `js/request-forgery` improvements --- change-notes/1.20/analysis-javascript.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.20/analysis-javascript.md b/change-notes/1.20/analysis-javascript.md index 69f6613c26cd..d08253753563 100644 --- a/change-notes/1.20/analysis-javascript.md +++ b/change-notes/1.20/analysis-javascript.md @@ -25,6 +25,7 @@ |--------------------------------------------|------------------------------|------------------------------------------------------------------------------| | Client-side cross-site scripting | More results | This rule now recognizes WinJS functions that are vulnerable to HTML injection. | | Insecure randomness | More results | This rule now flags insecure uses of `crypto.pseudoRandomBytes`. | +| Uncontrolled data used in network request | More results | This rule now recognizes host values that are vulnerable to injection. | | Unused parameter | Fewer false-positive results | This rule no longer flags parameters with leading underscore. | | Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that are implictly used by JSX elements, and no longer flags variables with leading underscore. | From ada0115d6aec72a067374df19b9589f1b8ac9e4d Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Fri, 14 Dec 2018 10:14:23 +0000 Subject: [PATCH 24/69] C#: Remove `getUrl()` predicates As described on https://lgtm.com/help/ql/locations#providing-location-information, there is no need to provide a `getUrl()` predicate, when there is a `getLocation()` predicate. Not only is it redundant, but it can also be slow because of string construction. --- csharp/ql/src/semmle/code/cil/Type.qll | 1 - csharp/ql/src/semmle/code/csharp/Location.qll | 16 ++++------------ csharp/ql/src/semmle/code/csharp/Member.qll | 11 ----------- csharp/ql/src/semmle/code/csharp/Type.qll | 1 - .../AnonymousObjectCreation3.expected | 4 ++-- .../namespaces/Namespaces1.expected | 2 +- .../namespaces/Namespaces10.expected | 2 +- .../namespaces/Namespaces2.expected | 2 +- .../namespaces/Namespaces3.expected | 3 ++- .../namespaces/Namespaces4.expected | 2 +- .../namespaces/Namespaces5.expected | 2 +- .../namespaces/Namespaces6.expected | 2 +- .../namespaces/Namespaces7.expected | 2 +- .../namespaces/Namespaces8.expected | 2 +- .../ql/test/library-tests/types/Types27.expected | 2 +- .../ql/test/library-tests/types/Types34.expected | 2 +- .../DefaultToString/DefaultToString.expected | 14 +++++++------- 17 files changed, 25 insertions(+), 45 deletions(-) diff --git a/csharp/ql/src/semmle/code/cil/Type.qll b/csharp/ql/src/semmle/code/cil/Type.qll index 6096d7d6ae5f..e0e64c4a9d17 100644 --- a/csharp/ql/src/semmle/code/cil/Type.qll +++ b/csharp/ql/src/semmle/code/cil/Type.qll @@ -23,7 +23,6 @@ class Namespace extends DotNet::Namespace, TypeContainer, @namespace { override Namespace getParent() { result = this.getParentNamespace() } override Namespace getParentNamespace() { parent_namespace(this, result) } override string getName() { namespaces(this,result) } - string getUrl() { result="" } override Location getLocation() { none() } } diff --git a/csharp/ql/src/semmle/code/csharp/Location.qll b/csharp/ql/src/semmle/code/csharp/Location.qll index 9d48822cfa73..c1983e19ba19 100644 --- a/csharp/ql/src/semmle/code/csharp/Location.qll +++ b/csharp/ql/src/semmle/code/csharp/Location.qll @@ -37,24 +37,16 @@ class Location extends @location string toString() { none() } /** Gets the start line of this location. */ - int getStartLine() { - locations_default(this,_,result,_,_,_) - } + final int getStartLine() { this.hasLocationInfo(_, result, _, _, _) } /** Gets the end line of this location. */ - int getEndLine() { - locations_default(this,_,_,_,result,_) - } + final int getEndLine() { this.hasLocationInfo(_, _, _, result, _) } /** Gets the start column of this location. */ - int getStartColumn() { - locations_default(this,_,_,result,_,_) - } + final int getStartColumn() { this.hasLocationInfo(_, _, result, _, _) } /** Gets the end column of this location. */ - int getEndColumn() { - locations_default(this,_,_,_,_,result) - } + final int getEndColumn() { this.hasLocationInfo(_, _, _, _, result) } } /** diff --git a/csharp/ql/src/semmle/code/csharp/Member.qll b/csharp/ql/src/semmle/code/csharp/Member.qll index bfbb44ac912f..10200635f191 100644 --- a/csharp/ql/src/semmle/code/csharp/Member.qll +++ b/csharp/ql/src/semmle/code/csharp/Member.qll @@ -36,17 +36,6 @@ class Declaration extends DotNet::Declaration, Element, @declaration { result = this.getDeclaringType().getQualifiedName() + "." + this.toStringWithTypes() } - /** Define URL for declarations with no location. */ - string getURL() { - if exists(this.getLocation()) then - exists(string path, int a, int b, int c, int d | - this.getLocation().hasLocationInfo(path, a, b, c, d) | - toUrl(path, a, b, c, d, result) - ) - else - result = "" - } - /** * Holds if this declaration has been generated by the compiler, for example * implicit constructors or accessors. diff --git a/csharp/ql/src/semmle/code/csharp/Type.qll b/csharp/ql/src/semmle/code/csharp/Type.qll index 4dfb7f179a8e..d1da7ddf1811 100644 --- a/csharp/ql/src/semmle/code/csharp/Type.qll +++ b/csharp/ql/src/semmle/code/csharp/Type.qll @@ -751,7 +751,6 @@ class Class extends RefType, @class_type { * ``` */ class AnonymousClass extends Class { - AnonymousClass() { this.getName().matches("<%") } } diff --git a/csharp/ql/test/library-tests/expressions/AnonymousObjectCreation3.expected b/csharp/ql/test/library-tests/expressions/AnonymousObjectCreation3.expected index ac7d5ce915a5..e16c51b69cb4 100644 --- a/csharp/ql/test/library-tests/expressions/AnonymousObjectCreation3.expected +++ b/csharp/ql/test/library-tests/expressions/AnonymousObjectCreation3.expected @@ -1,2 +1,2 @@ -| expressions.cs:417:9:420:9 | object creation of type <>__AnonType0 | | String[] | -| expressions.cs:421:9:424:9 | object creation of type <>__AnonType0 | | String[] | +| expressions.cs:417:9:420:9 | object creation of type <>__AnonType0 | file://:0:0:0:0 | String[] | +| expressions.cs:421:9:424:9 | object creation of type <>__AnonType0 | file://:0:0:0:0 | String[] | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces1.expected b/csharp/ql/test/library-tests/namespaces/Namespaces1.expected index 2f46a087ac9a..783fe121f4e7 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces1.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces1.expected @@ -1 +1 @@ -| | N1.N2 | +| namespaces.cs:5:11:5:15 | N1.N2 | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces10.expected b/csharp/ql/test/library-tests/namespaces/Namespaces10.expected index a1f48b2f4f86..809960852f16 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces10.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces10.expected @@ -1 +1 @@ -| | R1 | namespaces.cs:73:11:73:14 | A<> | namespaces.cs:80:11:80:11 | A | +| namespaces.cs:70:11:70:12 | R1 | namespaces.cs:73:11:73:14 | A<> | namespaces.cs:80:11:80:11 | A | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces2.expected b/csharp/ql/test/library-tests/namespaces/Namespaces2.expected index fa08acd8dbdf..7f7d27c43a37 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces2.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces2.expected @@ -1 +1 @@ -| | M1.M2 | +| namespaces.cs:16:15:16:16 | M1.M2 | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces3.expected b/csharp/ql/test/library-tests/namespaces/Namespaces3.expected index 5445040f4f3c..c3a4c14020fb 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces3.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces3.expected @@ -1 +1,2 @@ -| | P1.P2 | +| namespaces.cs:26:11:26:15 | P1.P2 | +| namespaces.cs:33:11:33:15 | P1.P2 | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces4.expected b/csharp/ql/test/library-tests/namespaces/Namespaces4.expected index fa08acd8dbdf..7f7d27c43a37 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces4.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces4.expected @@ -1 +1 @@ -| | M1.M2 | +| namespaces.cs:16:15:16:16 | M1.M2 | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces5.expected b/csharp/ql/test/library-tests/namespaces/Namespaces5.expected index e8d8d60fb1a0..e2a60e04a6a3 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces5.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces5.expected @@ -1 +1 @@ -| | Empty | +| namespaces.cs:44:11:44:15 | Empty | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces6.expected b/csharp/ql/test/library-tests/namespaces/Namespaces6.expected index 6ed973b5a249..39fee338b4b9 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces6.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces6.expected @@ -1 +1 @@ -| | Q1 | | Q1.Q2 | +| file://:0:0:0:0 | Q1 | namespaces.cs:50:11:50:15 | Q1.Q2 | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces7.expected b/csharp/ql/test/library-tests/namespaces/Namespaces7.expected index e213322d8542..52d04a67cb7d 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces7.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces7.expected @@ -1 +1 @@ -| | Q3 | namespaces.cs:64:11:64:11 | B | namespaces.cs:53:11:53:11 | A | +| namespaces.cs:57:11:57:12 | Q3 | namespaces.cs:64:11:64:11 | B | namespaces.cs:53:11:53:11 | A | diff --git a/csharp/ql/test/library-tests/namespaces/Namespaces8.expected b/csharp/ql/test/library-tests/namespaces/Namespaces8.expected index 8ec2d605524b..9689292b19d7 100644 --- a/csharp/ql/test/library-tests/namespaces/Namespaces8.expected +++ b/csharp/ql/test/library-tests/namespaces/Namespaces8.expected @@ -1 +1 @@ -| | Q3 | namespaces.cs:66:11:66:11 | C | namespaces.cs:53:11:53:11 | A | +| namespaces.cs:57:11:57:12 | Q3 | namespaces.cs:66:11:66:11 | C | namespaces.cs:53:11:53:11 | A | diff --git a/csharp/ql/test/library-tests/types/Types27.expected b/csharp/ql/test/library-tests/types/Types27.expected index 3d7e0b414d6e..9a4a69374f71 100644 --- a/csharp/ql/test/library-tests/types/Types27.expected +++ b/csharp/ql/test/library-tests/types/Types27.expected @@ -1 +1 @@ -| | null | +| file://:0:0:0:0 | null | diff --git a/csharp/ql/test/library-tests/types/Types34.expected b/csharp/ql/test/library-tests/types/Types34.expected index 6e099625069d..37e62f991313 100644 --- a/csharp/ql/test/library-tests/types/Types34.expected +++ b/csharp/ql/test/library-tests/types/Types34.expected @@ -1 +1 @@ -| | Class[][] | | Class[] | +| file://:0:0:0:0 | Class[][] | file://:0:0:0:0 | Class[] | diff --git a/csharp/ql/test/query-tests/Useless Code/DefaultToString/DefaultToString.expected b/csharp/ql/test/query-tests/Useless Code/DefaultToString/DefaultToString.expected index 8ef2e407766e..3c20ab85d525 100644 --- a/csharp/ql/test/query-tests/Useless Code/DefaultToString/DefaultToString.expected +++ b/csharp/ql/test/query-tests/Useless Code/DefaultToString/DefaultToString.expected @@ -1,10 +1,10 @@ | DefaultToString.cs:9:27:9:27 | access to local variable d | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | DefaultToString.cs:4:7:4:21 | DefaultToString | DefaultToString | | DefaultToString.cs:10:28:10:28 | access to local variable d | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | DefaultToString.cs:4:7:4:21 | DefaultToString | DefaultToString | -| DefaultToString.cs:16:27:16:30 | access to local variable ints | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | Int32[] | Int32[] | -| DefaultToString.cs:19:24:19:27 | access to local variable ints | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | Int32[] | Int32[] | +| DefaultToString.cs:16:27:16:30 | access to local variable ints | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | Int32[] | Int32[] | +| DefaultToString.cs:19:24:19:27 | access to local variable ints | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | Int32[] | Int32[] | | DefaultToStringBad.cs:8:35:8:35 | access to local variable p | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | DefaultToStringBad.cs:14:11:14:16 | Person | Person | -| DefaultToStringBad.cs:11:38:11:41 | access to local variable ints | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | Int32[] | Int32[] | -| WriteLineArray.cs:7:23:7:26 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | String[] | String[] | -| WriteLineArray.cs:8:27:8:30 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | String[] | String[] | -| WriteLineArray.cs:10:36:10:39 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | String[] | String[] | -| WriteLineArray.cs:11:40:11:43 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | | String[] | String[] | +| DefaultToStringBad.cs:11:38:11:41 | access to local variable ints | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | Int32[] | Int32[] | +| WriteLineArray.cs:7:23:7:26 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | String[] | String[] | +| WriteLineArray.cs:8:27:8:30 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | String[] | String[] | +| WriteLineArray.cs:10:36:10:39 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | String[] | String[] | +| WriteLineArray.cs:11:40:11:43 | access to parameter args | Default 'ToString()': $@ inherits 'ToString()' from 'Object', and so is not suitable for printing. | file://:0:0:0:0 | String[] | String[] | From 50cba92f5f16c3a040a6abe19e158e08b2e31cb6 Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Mon, 17 Dec 2018 10:58:46 +0100 Subject: [PATCH 25/69] JS: remove slow test Security/heuristics/AdditionalCommandInjections --- .../heuristics/AdditionalCommandInjections.expected | 1 - .../Security/heuristics/AdditionalCommandInjections.ql | 9 --------- .../Security/heuristics/HeuristicSink.expected | 1 - .../Security/heuristics/HeuristicSource.expected | 1 - .../Security/heuristics/additionalCommandInjections.js | 3 --- 5 files changed, 15 deletions(-) delete mode 100644 javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.expected delete mode 100644 javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.ql delete mode 100644 javascript/ql/test/library-tests/Security/heuristics/additionalCommandInjections.js diff --git a/javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.expected b/javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.expected deleted file mode 100644 index d47a2cde28cd..000000000000 --- a/javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.expected +++ /dev/null @@ -1 +0,0 @@ -| additionalCommandInjections.js:2:11:2:45 | "prgm - ... place() | additionalCommandInjections.js:2:28:2:35 | password | diff --git a/javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.ql b/javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.ql deleted file mode 100644 index ad6b6b2172d6..000000000000 --- a/javascript/ql/test/library-tests/Security/heuristics/AdditionalCommandInjections.ql +++ /dev/null @@ -1,9 +0,0 @@ -import javascript -import semmle.javascript.security.dataflow.CommandInjection::CommandInjection - -private import semmle.javascript.heuristics.all -// tests that the imports above changes the behavior of the standard taint tracking query - -from Configuration cfg, Source source, Sink sink -where cfg.hasFlow(source, sink) -select sink, source diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSink.expected b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSink.expected index 9886d1f455b3..b08ba55ddda7 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSink.expected +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSink.expected @@ -1,4 +1,3 @@ -| additionalCommandInjections.js:2:11:2:45 | "prgm - ... place() | | sinks.js:2:14:2:17 | sink | | sinks.js:3:5:3:17 | script + sink | | sinks.js:4:9:4:12 | sink | diff --git a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected index 29877ba9a0b2..52862db346b6 100644 --- a/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected +++ b/javascript/ql/test/library-tests/Security/heuristics/HeuristicSource.expected @@ -1,3 +1,2 @@ -| additionalCommandInjections.js:2:28:2:35 | password | | sources.js:2:5:2:12 | password | | sources.js:3:5:3:20 | JSON.stringify() | diff --git a/javascript/ql/test/library-tests/Security/heuristics/additionalCommandInjections.js b/javascript/ql/test/library-tests/Security/heuristics/additionalCommandInjections.js deleted file mode 100644 index f569215db8c6..000000000000 --- a/javascript/ql/test/library-tests/Security/heuristics/additionalCommandInjections.js +++ /dev/null @@ -1,3 +0,0 @@ -(function() { - o.run("prgm --pass " + password.replace()) -})(); From 4a631b42d43c5a7c9a2e2ae7acd945ebaa1970ff Mon Sep 17 00:00:00 2001 From: Esben Sparre Andreasen Date: Mon, 17 Dec 2018 12:55:34 +0100 Subject: [PATCH 26/69] JS: use `.lastIndexOf` in js/incomplete-url-substring-sanitization --- .../Security/CWE-020/IncompleteUrlSubstringSanitization.ql | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.ql b/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.ql index 8ea0a9106d12..97988dec805d 100644 --- a/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.ql +++ b/javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.ql @@ -15,7 +15,7 @@ private import semmle.javascript.dataflow.InferredTypes from DataFlow::MethodCallNode call, string name, DataFlow::Node substring, string target where - (name = "indexOf" or name = "includes" or name = "startsWith" or name = "endsWith") and + (name = "indexOf" or name = "lastIndexOf" or name = "includes" or name = "startsWith" or name = "endsWith") and call.getMethodName() = name and substring = call.getArgument(0) and substring.mayHaveStringValue(target) and @@ -27,7 +27,7 @@ where ) and // whitelist not ( - name = "indexOf" and + (name = "indexOf" or name = "lastIndexOf") and ( // arithmetic on the indexOf-result any(ArithmeticExpr e).getAnOperand().getUnderlyingValue() = call.asExpr() From 5040d3e26c73eb5ad698657da90c594fde4f1d24 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 14 Dec 2018 15:39:09 +0000 Subject: [PATCH 27/69] JS: add query for loop index bug --- ...djustmentAfterConcurrentModification.qhelp | 68 ++++++++ ...exAdjustmentAfterConcurrentModification.ql | 155 ++++++++++++++++++ ...exAdjustmentAfterConcurrentModification.js | 9 + ...justmentAfterConcurrentModificationGood.js | 10 ++ ...ntAfterConcurrentModificationGoodFilter.js | 3 + ...stmentAfterConcurrentModification.expected | 3 + ...djustmentAfterConcurrentModification.qlref | 1 + .../tst.js | 113 +++++++++++++ 8 files changed, 362 insertions(+) create mode 100644 javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp create mode 100644 javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql create mode 100644 javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModification.js create mode 100644 javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGood.js create mode 100644 javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGoodFilter.js create mode 100644 javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.expected create mode 100644 javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.qlref create mode 100644 javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js diff --git a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp new file mode 100644 index 000000000000..20bf93105d3e --- /dev/null +++ b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp @@ -0,0 +1,68 @@ + + + +

+ Items can be removed from an array using the splice method, but when doing so, + all subseequent items will be shifted to a lower index. If this is done while iterating over + the array, the shifting may cause the loop to skip over the element immediately after the + removed element. +

+ +
+ + +

+Determine what the loop is supposed to do: +

    +
  • + If the intention is to remove every occurence of a certain value, decrement the loop counter after removing an element, to counterbalance + the shift. +
  • +
  • + If the loop is only intended to remove a single value from the array, consider adding a break after the splice call. +
  • +
  • + If the loop is deliberately skipping over elements, consider moving the index increment into the body of the loop, + so it is clear that the loop is not a trivial array iteration loop. +
  • +
+

+ +
+ + +

+In this example, a function is intended to remove ".." parts from a path: +

+ + + +

+However, whenever the input contain two ".." parts right after one another, only the first will be removed. +For example, the string "../../secret.txt" will be mapped to "../secret.txt". After removing +the element at index 0, the loop counter is incremented to 1, but the second ".." string has now been shifted down to +index 0 and will therefore be skipped. +

+ +

+One way to avoid this is to decrement the loop counter after removing an element from the array: +

+ + + +

+Alternatively, use the filter method: +

+ + + +
+ + +
  • MDN: Array.prototype.splice().
  • +
  • MDN: Array.prototype.filter().
  • + +
    +
    diff --git a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql new file mode 100644 index 000000000000..23f19afc127d --- /dev/null +++ b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql @@ -0,0 +1,155 @@ +/** + * @name Missing index adjustment after concurrent modification + * @description Removing elements from an array while iterating over it can cause the loop to skip over some elements, + * unless the loop index is decremented accordingly. + * @kind problem + * @problem.severity warning + * @id js/missing-index-adjustment-after-concurrent-modification + * @tags correctness + * @precision high + */ +import javascript + +/** + * Operation that inserts or removes elements from an array while shifting all elements + * occuring after the insertion/removal point. + * + * Does not include `push` and `pop` since these never shift any elements. + */ +class ArrayShiftingCall extends DataFlow::MethodCallNode { + string name; + + ArrayShiftingCall() { + name = getMethodName() and + (name = "splice" or name = "shift" or name = "unshift") + } + + DataFlow::SourceNode getArray() { + result = getReceiver().getALocalSource() + } +} + +/** + * A call to `splice` on an array. + */ +class SpliceCall extends ArrayShiftingCall { + SpliceCall() { + name = "splice" + } + + /** + * Gets the index from which elements are removed and possibly new elemenst are inserted. + */ + DataFlow::Node getIndex() { + result = getArgument(0) + } + + /** + * Gets the number of removed elements. + */ + int getNumRemovedElements() { + result = getArgument(1).asExpr().getIntValue() and + result >= 0 + } + + /** + * Gets the number of inserted elements. + */ + int getNumInsertedElements() { + result = getNumArgument() - 2 and + result >= 0 + } +} + +/** + * A `for` loop iterating over the indices of an array, in increasing order. + */ +class ArrayIterationLoop extends ForStmt { + DataFlow::SourceNode array; + LocalVariable indexVariable; + + ArrayIterationLoop() { + exists (RelationalComparison compare | compare = getTest() | + compare.getLesserOperand() = indexVariable.getAnAccess() and + compare.getGreaterOperand() = array.getAPropertyRead("length").asExpr()) and + getUpdate().(IncExpr).getOperand() = indexVariable.getAnAccess() + } + + /** + * Gets the variable holding the loop variable and current array index. + */ + LocalVariable getIndexVariable() { + result = indexVariable + } + + /** + * Gets the loop entry point. + */ + ReachableBasicBlock getLoopEntry() { + result = getTest().getFirstControlFlowNode().getBasicBlock() + } + + /** + * Gets a call that potentially shifts the elements of the given array. + */ + ArrayShiftingCall getAnArrayShiftingCall() { + result.getArray() = array + } + + /** + * Gets a call to `splice` that removes elements from the looped-over array at the current index + * + * The `splice` call is not guaranteed to be inside the loop body. + */ + SpliceCall getACandidateSpliceCall() { + result = getAnArrayShiftingCall() and + result.getIndex().asExpr() = getIndexVariable().getAnAccess() and + result.getNumRemovedElements() > result.getNumInsertedElements() + } + + /** + * Holds if `cfg` modifies the index variable or shifts array elements, disturbing the + * relationship between the array and the index variable. + */ + predicate hasIndexingManipulation(ControlFlowNode cfg) { + cfg.(VarDef).getAVariable() = getIndexVariable() or + cfg = getAnArrayShiftingCall().asExpr() + } + + /** + * Holds if there is a `loop entry -> cfg` path that does not involve index manipulation or a successful index equality check. + */ + predicate hasPathTo(ControlFlowNode cfg) { + exists(getACandidateSpliceCall()) and // restrict size of predicate + cfg = getLoopEntry().getFirstNode() + or + hasPathTo(cfg.getAPredecessor()) and + getLoopEntry().dominates(cfg.getBasicBlock()) and + not hasIndexingManipulation(cfg) and + // Ignore splice calls guarded by an index equality check. + // This indicates that the index of an element is the basis for removal, not its value, + // which means it may be okay to skip over elements. + not exists (ConditionGuardNode guard, EqualityTest test | cfg = guard | + test = guard.getTest() and + test.getAnOperand() = getIndexVariable().getAnAccess() and + guard.getOutcome() = test.getPolarity()) + } + + /** + * Holds if there is a `loop entry -> splice -> cfg` path that does not involve index manipulation, + * other than the `splice` call. + */ + predicate hasPathThrough(SpliceCall splice, ControlFlowNode cfg) { + splice = getACandidateSpliceCall() and + cfg = splice.asExpr() and + hasPathTo(cfg.getAPredecessor()) + or + hasPathThrough(splice, cfg.getAPredecessor()) and + getLoopEntry().dominates(cfg.getBasicBlock()) and + not hasIndexingManipulation(cfg) + } +} + +from ArrayIterationLoop loop, SpliceCall splice +where loop.hasPathThrough(splice, loop.getUpdate().getFirstControlFlowNode()) +select splice, "Missing loop index adjustment after removing array item. Some array items will be skipped due to shifting." diff --git a/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModification.js b/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModification.js new file mode 100644 index 000000000000..ccff5c5d208b --- /dev/null +++ b/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModification.js @@ -0,0 +1,9 @@ +function removePathTraversal(path) { + let parts = path.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === '..') { + parts.splice(i, 1); + } + } + return path.join('/'); +} diff --git a/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGood.js b/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGood.js new file mode 100644 index 000000000000..3ebedc7ced91 --- /dev/null +++ b/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGood.js @@ -0,0 +1,10 @@ +function removePathTraversal(path) { + let parts = path.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === '..') { + parts.splice(i, 1); + --i; // adjust for array shift + } + } + return path.join('/'); +} diff --git a/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGoodFilter.js b/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGoodFilter.js new file mode 100644 index 000000000000..eba08d045d2d --- /dev/null +++ b/javascript/ql/src/Statements/examples/MissingIndexAdjustmentAfterConcurrentModificationGoodFilter.js @@ -0,0 +1,3 @@ +function removePathTraversal(path) { + return path.split('/').filter(part => part !== '..').join('/'); +} diff --git a/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.expected b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.expected new file mode 100644 index 000000000000..8348040e8734 --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.expected @@ -0,0 +1,3 @@ +| tst.js:4:27:4:44 | parts.splice(i, 1) | Missing loop index adjustment after removing array item. Some array items will be skipped due to shifting. | +| tst.js:13:29:13:46 | parts.splice(i, 1) | Missing loop index adjustment after removing array item. Some array items will be skipped due to shifting. | +| tst.js:24:9:24:26 | parts.splice(i, 1) | Missing loop index adjustment after removing array item. Some array items will be skipped due to shifting. | diff --git a/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.qlref b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.qlref new file mode 100644 index 000000000000..0367f1f38878 --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/MissingIndexAdjustmentAfterConcurrentModification.qlref @@ -0,0 +1 @@ +Statements/MissingIndexAdjustmentAfterConcurrentModification.ql \ No newline at end of file diff --git a/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js new file mode 100644 index 000000000000..6de02e2c5744 --- /dev/null +++ b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js @@ -0,0 +1,113 @@ +function removeX(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === 'X') parts.splice(i, 1); // NOT OK + } + return parts.join('/'); +} + +function removeXInnerLoop(string, n) { + let parts = string.split('/'); + for (let j = 0; j < n; ++j) { + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === 'X') parts.splice(i, 1); // NOT OK + } + } + return parts.join('/'); +} + +function removeXOuterLoop(string, n) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + for (let j = 0; j < n; ++j) { + if (parts[i] === 'X') { + parts.splice(i, 1); // NOT OK + break; + } + } + } + return parts.join('/'); +} + +function decrementAfter(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === 'X') { + parts.splice(i, 1); // OK + --i; + } + } + return parts.join('/'); +} + +function postDecrementArgument(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === 'X') { + parts.splice(i--, 1); // OK + } + } + return parts.join('/'); +} + + +function breakAfter(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === 'X') { + parts.splice(i, 1); // OK - only removes first occurrence + break; + } + } + return parts.join('/'); +} + +function insertNewElements(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (parts[i] === 'X') { + parts.splice(i, 1, '.'); // OK - no shifting due to insert + } + } + return parts.join('/'); +} + +function spliceAfterLoop(string) { + let parts = string.split('/'); + let i = 0; + for (; i < parts.length; ++i) { + if (parts[i] === 'X') break; + } + if (parts[i] === 'X') { + parts.splice(i, 1); // OK - not inside loop + } + return parts.join('/'); +} + +function spliceAfterLoopNested(string) { + let parts = string.split('/'); + for (let j = 0; j < parts.length; ++j) { + let i = j; + for (; i < parts.length; ++i) { + if (parts[i] === 'X') break; + } + parts.splice(i, 1); // OK - not inside 'i' loop + } + return parts.join('/'); +} + +function removeAtSpecificPlace(string, k) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (i === k && parts[i] === 'X') parts.splice(i, 1); // OK - more complex logic + } + return parts.join('/'); +} + +function removeFirstAndLast(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (i === 0 || i === parts.length - 1) parts.splice(i, 1); // OK - out of scope of this query + } + return parts.join('/'); +} From e822510d6b916176a46e9caa22eb17cb7addc4c7 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 17 Dec 2018 15:33:05 +0100 Subject: [PATCH 28/69] C#: Fix typo --- .../src/semmle/code/csharp/controlflow/ControlFlowElement.qll | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll index 15481f02956c..8738b5b3da88 100644 --- a/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll +++ b/csharp/ql/src/semmle/code/csharp/controlflow/ControlFlowElement.qll @@ -79,7 +79,7 @@ class ControlFlowElement extends ExprOrStmtParent, @control_flow_element { * `pred` ending with this element, and `pred` is an immediate predecessor * of `succ`. * - * Moroever, this control flow element corresponds to multiple control flow nodes, + * Moreover, this control flow element corresponds to multiple control flow nodes, * which is why * * ``` From d3f6362ba2287c3640cf4dc3927324d5c905f426 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Mon, 17 Dec 2018 15:40:46 +0100 Subject: [PATCH 29/69] Java: Add missing override annotations. --- java/ql/src/Metrics/Internal/Extents.qll | 4 ++-- java/ql/src/external/CodeDuplication.qll | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/java/ql/src/Metrics/Internal/Extents.qll b/java/ql/src/Metrics/Internal/Extents.qll index 1f1d1c55eb00..38494b1bd968 100644 --- a/java/ql/src/Metrics/Internal/Extents.qll +++ b/java/ql/src/Metrics/Internal/Extents.qll @@ -15,7 +15,7 @@ import java * including the body (if any), as opposed to the location of its name only. */ class RangeCallable extends Callable { - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { + override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(int elSuper, int ecSuper | super.hasLocationInfo(path, sl, sc, elSuper, ecSuper) | this.getBody().hasLocationInfo(path, _, _, el, ec) or @@ -39,7 +39,7 @@ class RangeCallable extends Callable { * including the range of its members (if any), as opposed to the location of its name only. */ class RangeRefType extends RefType { - predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { + override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) { exists(int elSuper, int ecSuper | super.hasLocationInfo(path, sl, sc, elSuper, ecSuper) | lastMember().hasLocationInfo(path, _, _, el, ec) or diff --git a/java/ql/src/external/CodeDuplication.qll b/java/ql/src/external/CodeDuplication.qll index 243e874cf6a1..ce01160695a9 100644 --- a/java/ql/src/external/CodeDuplication.qll +++ b/java/ql/src/external/CodeDuplication.qll @@ -51,11 +51,13 @@ class Copy extends @duplication_or_similarity { } class DuplicateBlock extends Copy, @duplication { - string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." } + override string toString() { result = "Duplicate code: " + sourceLines() + " duplicated lines." } } class SimilarBlock extends Copy, @similarity { - string toString() { result = "Similar code: " + sourceLines() + " almost duplicated lines." } + override string toString() { + result = "Similar code: " + sourceLines() + " almost duplicated lines." + } } Method sourceMethod() { hasLocation(result, _) and numlines(result, _, _, _) } From 280382e91ecd071d18eb55b05f5d670130ac5b8c Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 17 Dec 2018 15:19:26 +0000 Subject: [PATCH 30/69] JS: whitelist if array access at another index is seen --- ...issingIndexAdjustmentAfterConcurrentModification.ql | 10 +++++++++- .../tst.js | 10 ++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql index 23f19afc127d..23bc456ce6e2 100644 --- a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql +++ b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql @@ -126,13 +126,21 @@ class ArrayIterationLoop extends ForStmt { hasPathTo(cfg.getAPredecessor()) and getLoopEntry().dominates(cfg.getBasicBlock()) and not hasIndexingManipulation(cfg) and + // Ignore splice calls guarded by an index equality check. // This indicates that the index of an element is the basis for removal, not its value, // which means it may be okay to skip over elements. not exists (ConditionGuardNode guard, EqualityTest test | cfg = guard | test = guard.getTest() and test.getAnOperand() = getIndexVariable().getAnAccess() and - guard.getOutcome() = test.getPolarity()) + guard.getOutcome() = test.getPolarity()) and + + // Block flow after inspecting an array element other than that at the current index. + // For example, if the splice happens after inspecting `array[i + 1]`, then the next + // element has already been "looked at" and so it doesn't matter if we skip it. + not exists (IndexExpr index | cfg = index | + array.flowsToExpr(index.getBase()) and + not index.getIndex() = getIndexVariable().getAnAccess()) } /** diff --git a/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js index 6de02e2c5744..cebe8569c087 100644 --- a/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js +++ b/javascript/ql/test/query-tests/Statements/MissingIndexAdjustmentAfterConcurrentModification/tst.js @@ -111,3 +111,13 @@ function removeFirstAndLast(string) { } return parts.join('/'); } + +function inspectNextElement(string) { + let parts = string.split('/'); + for (let i = 0; i < parts.length; ++i) { + if (i < parts.length - 1 && parts[i] === parts[i + 1]) { + parts.splice(i, 1); // OK - next element has been looked at + } + } + return parts.join('/'); +} From d9ae5933d4e0a31fb4938c5b7969ca5a9101d0b6 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Mon, 17 Dec 2018 16:13:25 +0100 Subject: [PATCH 31/69] C#: Remove deprecated predicates --- .../ql/src/semmle/code/csharp/Assignable.qll | 97 --------------- csharp/ql/src/semmle/code/csharp/Stmt.qll | 28 ----- csharp/ql/src/semmle/code/csharp/Type.qll | 22 ---- csharp/ql/src/semmle/code/csharp/XML.qll | 13 -- .../src/semmle/code/csharp/dataflow/SSA.qll | 81 ------------ .../src/semmle/code/csharp/exprs/Access.qll | 82 ------------- .../ql/src/semmle/code/csharp/exprs/Expr.qll | 38 +----- .../code/csharp/frameworks/Microsoft.qll | 4 - .../semmle/code/csharp/frameworks/System.qll | 116 ------------------ .../code/csharp/frameworks/microsoft/Owin.qll | 4 - .../code/csharp/frameworks/system/CodeDom.qll | 4 - .../csharp/frameworks/system/Collections.qll | 16 --- .../code/csharp/frameworks/system/Data.qll | 8 -- .../csharp/frameworks/system/Diagnostics.qll | 12 -- .../code/csharp/frameworks/system/IO.qll | 25 ---- .../csharp/frameworks/system/Reflection.qll | 12 -- .../code/csharp/frameworks/system/Runtime.qll | 4 - .../code/csharp/frameworks/system/Text.qll | 12 -- .../csharp/frameworks/system/Threading.qll | 4 - .../code/csharp/frameworks/system/Web.qll | 20 --- .../code/csharp/frameworks/system/Xml.qll | 4 - .../frameworks/system/codedom/Compiler.qll | 8 -- .../frameworks/system/collections/Generic.qll | 28 ----- .../system/collections/Specialized.qll | 8 -- .../frameworks/system/data/SqlClient.qll | 8 -- .../frameworks/system/io/Compression.qll | 4 - .../system/runtime/InteropServices.qll | 16 --- .../frameworks/system/threading/Tasks.qll | 12 -- .../csharp/frameworks/system/web/Services.qll | 8 -- .../code/csharp/frameworks/system/web/UI.qll | 24 ---- .../frameworks/system/web/ui/WebControls.qll | 8 -- .../csharp/frameworks/test/VisualStudio.qll | 4 - 32 files changed, 3 insertions(+), 731 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/Assignable.qll b/csharp/ql/src/semmle/code/csharp/Assignable.qll index 822a9daa17b0..e6002f5f9dcc 100644 --- a/csharp/ql/src/semmle/code/csharp/Assignable.qll +++ b/csharp/ql/src/semmle/code/csharp/Assignable.qll @@ -113,49 +113,6 @@ class AssignableRead extends AssignableAccess { AssignableRead getAReachableRead() { result = this.getANextRead+() } - - /** - * Gets a next uncertain read of the same underlying assignable. That is, - * a read that can be reached from this read without passing through any other - * reads, and which *may* read the same value. Example: - * - * ``` - * int Field; - * - * void SetField(int i) { - * this.Field = i; - * Use(this.Field); - * if (i > 0) - * this.Field = i - 1; - * else if (i < 0) - * SetField(1); - * Use(this.Field); - * Use(this.Field); - * } - * ``` - * - * - The read of `i` on line 6 is next to the read on line 4. - * - The reads of `i` on lines 7 and 8 are next to the read on line 6. - * - The read of `this.Field` on line 10 is next to the read on line 5. - * (This is the only truly uncertain read.) - * - The read of `this.Field` on line 11 is next to the read on line 10. - */ - deprecated - AssignableRead getANextUncertainRead() { - Ssa::Internal::adjacentReadPair(this, result) - } - - /** - * Gets a next uncertain read of the same underlying assignable. That is, - * a read that can be reached from this read, and which *may* read the same - * value. - * - * This is the transitive closure of `getANextUncertainRead()`. - */ - deprecated - AssignableRead getAReachableUncertainRead() { - result = this.getANextUncertainRead+() - } } /** @@ -484,10 +441,6 @@ class AssignableDefinition extends TAssignableDefinition { */ Expr getExpr() { none() } - /** DEPRECATED: Use `getAControlFlowNode()` instead. */ - deprecated - ControlFlow::Node getControlFlowNode() { result = this.getAControlFlowNode() } - /** Gets the enclosing callable of this definition. */ Callable getEnclosingCallable() { result = this.getExpr().getEnclosingCallable() } @@ -560,56 +513,6 @@ class AssignableDefinition extends TAssignableDefinition { result = this.getAFirstRead().getANextRead*() } - /** - * Gets a first uncertain read of the same underlying assignable. That is, - * a read that can be reached from this definition without passing through any - * other reads, and which *may* read the value assigned in this definition. - * Example: - * - * ``` - * int Field; - * - * void SetField(int i) { - * this.Field = i; - * Use(this.Field); - * if (i > 0) - * this.Field = i - 1; - * else if (i < 0) - * SetField(1); - * Use(this.Field); - * Use(this.Field); - * } - * ``` - * - * - The read of `i` on line 4 is a first read of the implicit parameter definition - * on line 3. - * - The read of `this.Field` on line 5 is a first read of the definition on line 4. - * - The read of `this.Field` on line 10 is a first read of the definition on - * line 7. (This is the only truly uncertain read.) - * - * Subsequent uncertain reads can be found by following the steps defined by - * `AssignableRead.getANextUncertainRead()`. - */ - deprecated - AssignableRead getAFirstUncertainRead() { - exists(Ssa::ExplicitDefinition def | - def.getADefinition() = this | - result = def.getAFirstUncertainRead() - ) - } - - /** - * Gets a reachable uncertain read of the same underlying assignable. That is, - * a read that can be reached from this definition, and which *may* read the - * value assigned in this definition. - * - * This is the equivalent with `getAFirstUncertainRead().getANextUncertainRead*()`. - */ - deprecated - AssignableRead getAReachableUncertainRead() { - result = this.getAFirstUncertainRead().getANextUncertainRead*() - } - /** Gets a textual representation of this assignable definition. */ string toString() { none() } diff --git a/csharp/ql/src/semmle/code/csharp/Stmt.qll b/csharp/ql/src/semmle/code/csharp/Stmt.qll index 0b4ee73ace8a..199030e341a1 100644 --- a/csharp/ql/src/semmle/code/csharp/Stmt.qll +++ b/csharp/ql/src/semmle/code/csharp/Stmt.qll @@ -1190,22 +1190,6 @@ class UsingStmt extends Stmt, @using_stmt { /** Gets a local variable declaration of this `using` statement. */ LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) } - /** DEPRECATED: Use `getVariable(0)` instead. */ - deprecated - LocalVariable getVariable() { result = getVariableDeclExpr().getVariable() } - - /** DEPRECATED: Use `getAVariableDeclExpr()` instead. */ - deprecated - LocalVariableDeclExpr getVariableDeclExpr() { result.getParent() = this } - - /** DEPRECATED: Use `getAnExpr()` instead. */ - deprecated Expr getInitializer() { - if exists(this.getVariableDeclExpr(0)) then - result = this.getVariableDeclExpr(0).getInitializer() - else - result.getParent() = this - } - /** * Gets the expression directly used by this `using` statement, if any. For * example, `f` on line 2 in @@ -1389,14 +1373,6 @@ class FixedStmt extends Stmt, @fixed_stmt { /** Gets a local variable declaration of this `fixed` statement. */ LocalVariableDeclExpr getAVariableDeclExpr() { result = this.getVariableDeclExpr(_) } - /** DEPRECATED: Use `getVariable(0)` instead. */ - deprecated - LocalVariable getVariable() { result = getVariableDeclExpr().getVariable() } - - /** DEPRECATED: Use `getVariableDeclExpr(0) instead. */ - deprecated - LocalVariableDeclExpr getVariableDeclExpr() { result.getParent() = this } - /** Gets the body of this `fixed` statement. */ Stmt getBody() { result.getParent() = this } @@ -1441,10 +1417,6 @@ class LabeledStmt extends Stmt, @labeled_stmt { and result = this.getParent().getChild(i+1)) } - /** DEPRECATED: Use `getStmt()` instead. */ - deprecated - Stmt getReferredStatement() { result = this.getStmt() } - /** Gets the label of this statement. */ string getLabel() { exprorstmt_name(this, result) } diff --git a/csharp/ql/src/semmle/code/csharp/Type.qll b/csharp/ql/src/semmle/code/csharp/Type.qll index 4dfb7f179a8e..b63c2516bda7 100644 --- a/csharp/ql/src/semmle/code/csharp/Type.qll +++ b/csharp/ql/src/semmle/code/csharp/Type.qll @@ -134,12 +134,6 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_ result.hasName(name) } - /** - * DEPRECATED: Use `hasMethod()` instead. - */ - deprecated - predicate inheritsMethod(Method m) { this.hasMethod(m) } - /** * Holds if this type has method `m`, that is, either `m` is declared in this * type, or `m` is inherited by this type. @@ -164,14 +158,6 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_ */ predicate hasMethod(Method m) { this.hasMember(m) } - /** - * DEPRECATED: Use `hasCallable()` instead. - */ - deprecated - predicate inheritsCallable(Callable c) { - this.hasCallable(c) - } - /** * Holds if this type has callable `c`, that is, either `c` is declared in this * type, or `c` is inherited by this type. @@ -202,14 +188,6 @@ class ValueOrRefType extends DotNet::ValueOrRefType, Type, Attributable, @value_ hasMember(c.(Accessor).getDeclaration()) } - /** - * DEPRECATED: Use `hasMember()` instead. - */ - deprecated - predicate inheritsMember(Member m) { - this.hasMember(m) - } - /** * Holds if this type has member `m`, that is, either `m` is declared in this * type, or `m` is inherited by this type. diff --git a/csharp/ql/src/semmle/code/csharp/XML.qll b/csharp/ql/src/semmle/code/csharp/XML.qll index 8e434aa7866d..18be5bbee1f5 100644 --- a/csharp/ql/src/semmle/code/csharp/XML.qll +++ b/csharp/ql/src/semmle/code/csharp/XML.qll @@ -78,19 +78,6 @@ class XMLParent extends @xmlparent { result = count(int pos | xmlChars(_,_,this,pos,_,_)) } - /** - * DEPRECATED: Internal. - * - * Append the character sequences of this XML parent from left to right, separated by a space, - * up to a specified (zero-based) index. - */ - deprecated - string charsSetUpTo(int n) { - (n = 0 and xmlChars(_,result,this,0,_,_)) or - (n > 0 and exists(string chars | xmlChars(_,chars,this,n,_,_) | - result = this.charsSetUpTo(n-1) + " " + chars)) - } - /** Append all the character sequences of this XML parent from left to right, separated by a space. */ string allCharactersString() { result = concat(string chars, int pos | xmlChars(_, chars, this, pos, _, _) | chars, " " order by pos) diff --git a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll index e8fa362ebf89..e1af158d0d4e 100644 --- a/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll +++ b/csharp/ql/src/semmle/code/csharp/dataflow/SSA.qll @@ -758,42 +758,6 @@ module Ssa { ssaRefRank(bb2, i2, v, _) = 1 } - /** - * Holds if the value defined at non-trivial SSA definition `def` can reach `read` - * without passing through any other read, but possibly through pseudo definitions - * and uncertain definitions. - */ - deprecated - predicate firstUncertainRead(TrackedDefinition def, AssignableRead read) { - firstReadSameVar(def, read) - or - exists(TrackedVar v, TrackedDefinition redef, BasicBlock b1, int i1, BasicBlock b2, int i2 | - redef instanceof UncertainDefinition or redef instanceof PseudoDefinition - | - adjacentVarRefs(v, b1, i1, b2, i2) and - definesAt(def, b1, i1, v) and - definesAt(redef, b2, i2, v) and - firstUncertainRead(redef, read) - ) - } - - /** - * INTERNAL: Use `AssignableRead.getANextUncertainRead()` instead. - */ - deprecated - predicate adjacentReadPair(AssignableRead read1, AssignableRead read2) { - adjacentReadPairSameVar(read1, read2) - or - exists(TrackedVar v, TrackedDefinition def, BasicBlock bb1, int i1, BasicBlock bb2, int i2 | - adjacentVarRefs(v, bb1, i1, bb2, i2) and - variableRead(bb1, i1, v, read1.getAControlFlowNode(), _) and - definesAt(def, bb2, i2, v) and - firstUncertainRead(def, read2) | - def instanceof UncertainDefinition or - def instanceof PseudoDefinition - ) - } - private cached module Cached { /** * Holds if `read` is a last read of the non-trivial SSA definition `def`. @@ -2146,47 +2110,6 @@ module Ssa { lastRead(this, result) } - /** - * Gets a first uncertain read of the source variable underlying this - * SSA definition. That is, a read that can be reached from this SSA definition - * without passing through any other reads or SSA definitions, except for - * phi nodes and uncertain updates. Example: - * - * ``` - * int Field; - * - * void SetField(int i) { - * this.Field = i; - * Use(this.Field); - * if (i > 0) - * this.Field = i - 1; - * else if (i < 0) - * SetField(1); - * Use(this.Field); - * Use(this.Field); - * } - * ``` - * - * - The read of `i` on line 4 can be reached from the explicit SSA - * definition (wrapping an implicit entry definition) on line 3. - * - The reads of `i` on lines 6 and 7 are not the first reads of any SSA - * definition. - * - The read of `this.Field` on line 5 can be reached from the explicit SSA - * definition on line 4. - * - The read of `this.Field` on line 10 can be reached from the explicit SSA - * definition on line 7, the implicit SSA definition on line 9, and the phi - * node between lines 9 and 10. - * - The read of `this.Field` on line 11 is not the first read of any SSA - * definition. - * - * Subsequent uncertain reads can be found by following the steps defined by - * `AssignableRead.getANextUncertainRead()`. - */ - deprecated - AssignableRead getAFirstUncertainRead() { - firstUncertainRead(this, result) - } - /** * Gets a definition that ultimately defines this SSA definition and is * not itself a pseudo node. Example: @@ -2459,10 +2382,6 @@ module Ssa { ) } - override AssignableRead getAFirstUncertainRead() { - result = this.getARead() - } - override string toString() { result = getToStringPrefix(this) + "SSA untracked def(" + getSourceVariable() + ")" } diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Access.qll b/csharp/ql/src/semmle/code/csharp/exprs/Access.qll index b03a5b64c7a9..196f1e5fe5cc 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Access.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Access.qll @@ -128,28 +128,6 @@ class MemberAccess extends Access, QualifiableExpr, @member_access_expr { class AssignableAccess extends Access, @assignable_access_expr { override Assignable getTarget() { none() } - /** - * DEPRECATED: use the class `AssignableRead` instead. - */ - deprecated predicate isReadAccess() { - this instanceof AssignableRead - } - - /** - * DEPRECATED: use the class `AssignableWrite` instead. - */ - deprecated predicate isWriteAccess() { - this instanceof AssignableWrite - } - - /** - * DEPRECATED: use the classes `AssignableRead` and `AssignableWrite` instead. - */ - deprecated predicate isReadWriteAccess() { - this instanceof AssignableRead and - this instanceof AssignableWrite - } - /** * Holds if this access passes the assignable being accessed as an `out` * argument in a method call. @@ -207,16 +185,6 @@ class VariableRead extends VariableAccess, AssignableRead { override VariableRead getAReachableRead() { result = AssignableRead.super.getAReachableRead() } - - deprecated - override VariableRead getANextUncertainRead() { - result = AssignableRead.super.getANextUncertainRead() - } - - deprecated - override VariableRead getAReachableUncertainRead() { - result = AssignableRead.super.getAReachableUncertainRead() - } } /** @@ -249,16 +217,6 @@ class LocalScopeVariableRead extends LocalScopeVariableAccess, VariableRead { override LocalScopeVariableRead getAReachableRead() { result = VariableRead.super.getAReachableRead() } - - deprecated - override LocalScopeVariableRead getANextUncertainRead() { - result = VariableRead.super.getANextUncertainRead() - } - - deprecated - override LocalScopeVariableRead getAReachableUncertainRead() { - result = VariableRead.super.getAReachableUncertainRead() - } } /** @@ -305,16 +263,6 @@ class ParameterRead extends ParameterAccess, LocalScopeVariableRead { override ParameterRead getAReachableRead() { result = LocalScopeVariableRead.super.getAReachableRead() } - - deprecated - override ParameterRead getANextUncertainRead() { - result = LocalScopeVariableRead.super.getANextUncertainRead() - } - - deprecated - override ParameterRead getAReachableUncertainRead() { - result = LocalScopeVariableRead.super.getAReachableUncertainRead() - } } /** @@ -372,16 +320,6 @@ class LocalVariableRead extends LocalVariableAccess, LocalScopeVariableRead { override LocalVariableRead getAReachableRead() { result = LocalScopeVariableRead.super.getAReachableRead() } - - deprecated - override LocalVariableRead getANextUncertainRead() { - result = LocalScopeVariableRead.super.getANextUncertainRead() - } - - deprecated - override LocalVariableRead getAReachableUncertainRead() { - result = LocalScopeVariableRead.super.getAReachableUncertainRead() - } } /** @@ -526,16 +464,6 @@ class PropertyRead extends PropertyAccess, AssignableRead { override PropertyRead getAReachableRead() { result = AssignableRead.super.getAReachableRead() } - - deprecated - override PropertyRead getANextUncertainRead() { - result = AssignableRead.super.getANextUncertainRead() - } - - deprecated - override PropertyRead getAReachableUncertainRead() { - result = AssignableRead.super.getAReachableUncertainRead() - } } /** @@ -685,16 +613,6 @@ class IndexerRead extends IndexerAccess, AssignableRead { override IndexerRead getAReachableRead() { result = AssignableRead.super.getAReachableRead() } - - deprecated - override IndexerRead getANextUncertainRead() { - result = AssignableRead.super.getANextUncertainRead() - } - - deprecated - override IndexerRead getAReachableUncertainRead() { - result = AssignableRead.super.getAReachableUncertainRead() - } } /** diff --git a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll index 1f802b84d552..6c2b720dc968 100644 --- a/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll +++ b/csharp/ql/src/semmle/code/csharp/exprs/Expr.qll @@ -275,39 +275,7 @@ class IsExpr extends Expr, @is_expr { */ Expr getExpr() { result = this.getChild(0) } - /** - * Deprecated: Use `IsTypeExpr.getTypeAccess()` instead. - * Gets the type access in this `is` expression, for example `string` in - * `x is string`. - */ - deprecated - TypeAccess getTypeAccess() { none() } - - /** - * Deprecated: Use `IsTypeExpr.getCheckedType()` instead. - * Gets the type being accessed in this `is` expression, for example `string` - * in `x is string`. - */ - deprecated - Type getCheckedType() { none() } - override string toString() { result = "... is ..." } - - /** - * Deprecated: Use `IsPatternExpr.getVariableDeclExpr()` instead. - * Gets the local variable declaration in an `is` pattern expression, - * if any. For example `string s` in `x is string s`. - */ - deprecated - LocalVariableDeclExpr getVariableDeclExpr() { none() } - - /** - * Deprecated: Use `instanceof IsPatternExpr` instead. - * Holds if this `is` expression is an `is` pattern expression, for example - * `x is string s`. - */ - deprecated - predicate isPattern() { this instanceof IsPatternExpr } } /** @@ -322,13 +290,13 @@ class IsTypeExpr extends IsExpr * Gets the type being accessed in this `is` expression, for example `string` * in `x is string`. */ - override Type getCheckedType() { result = typeAccess.getTarget() } + Type getCheckedType() { result = typeAccess.getTarget() } /** * Gets the type access in this `is` expression, for example `string` in * `x is string`. */ - override TypeAccess getTypeAccess() { result = typeAccess } + TypeAccess getTypeAccess() { result = typeAccess } } /** @@ -343,7 +311,7 @@ class IsPatternExpr extends IsTypeExpr * Gets the local variable declaration in this `is` pattern expression. * For example `string s` in `x is string s`. */ - override LocalVariableDeclExpr getVariableDeclExpr() { result = typeDecl } + LocalVariableDeclExpr getVariableDeclExpr() { result = typeDecl } } /** diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/Microsoft.qll b/csharp/ql/src/semmle/code/csharp/frameworks/Microsoft.qll index e174966a8d91..4d353e219ebb 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/Microsoft.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/Microsoft.qll @@ -8,7 +8,3 @@ class MicrosoftNamespace extends Namespace { this.hasName("Microsoft") } } - -/** DEPRECATED. Gets the `Microsoft` namespace. */ -deprecated -MicrosoftNamespace getMicrosoftNamespace() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/System.qll b/csharp/ql/src/semmle/code/csharp/frameworks/System.qll index 27b1e43b5196..823fdef24e59 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/System.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/System.qll @@ -10,10 +10,6 @@ class SystemNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System` namespace. */ -deprecated -SystemNamespace getSystemNamespace() { any() } - /** A class in the `System` namespace. */ class SystemClass extends Class { SystemClass() { @@ -63,10 +59,6 @@ class SystemActionDelegateType extends SystemDelegateType { } } -/** DEPRECATED. Gets the `System.Action` delegate type. */ -deprecated -SystemActionDelegateType getSystemActionDelegateType() { any() } - /** The `System.Action` delegate type. */ class SystemActionTDelegateType extends SystemUnboundGenericDelegateType { SystemActionTDelegateType() { @@ -74,10 +66,6 @@ class SystemActionTDelegateType extends SystemUnboundGenericDelegateType { } } -/** DEPRECATED. Gets a `System.Action` delegate type. */ -deprecated -SystemActionTDelegateType getSystemActionTDelegateType() { any() } - /** `System.Array` class. */ class SystemArrayClass extends SystemClass { SystemArrayClass() { @@ -85,10 +73,6 @@ class SystemArrayClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Array` class. */ -deprecated -SystemArrayClass getSystemArrayClass() { any() } - /** The `System.Boolean` structure. */ class SystemBooleanStruct extends BoolType { /** Gets the `Parse(string)` method. */ @@ -120,10 +104,6 @@ class SystemBooleanStruct extends BoolType { } } -/** DEPRECATED. Gets the `System.Boolean` structure. */ -deprecated -SystemBooleanStruct getSystemBooleanStruct() { any() } - /** The `System.Convert` class. */ class SystemConvertClass extends SystemClass { SystemConvertClass() { @@ -131,10 +111,6 @@ class SystemConvertClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Convert` class. */ -deprecated -SystemConvertClass getSystemConvertClass() { any() } - /** `System.Delegate` class. */ class SystemDelegateClass extends SystemClass { SystemDelegateClass() { @@ -142,10 +118,6 @@ class SystemDelegateClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Delegate` class. */ -deprecated -SystemDelegateClass getSystemDelegateClass() { any() } - /** The `System.DivideByZeroException` class. */ class SystemDivideByZeroExceptionClass extends SystemClass { SystemDivideByZeroExceptionClass() { @@ -153,10 +125,6 @@ class SystemDivideByZeroExceptionClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.DivideByZeroException` class. */ -deprecated -SystemDivideByZeroExceptionClass getSystemDivideByZeroExceptionClass() { any() } - /** The `System.Enum` class. */ class SystemEnumClass extends SystemClass { SystemEnumClass() { @@ -164,10 +132,6 @@ class SystemEnumClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Enum` class. */ -deprecated -SystemEnumClass getSystemEnumClass() { any() } - /** The `System.Exception` class. */ class SystemExceptionClass extends SystemClass { SystemExceptionClass() { @@ -175,10 +139,6 @@ class SystemExceptionClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Exception` class. */ -deprecated -SystemExceptionClass getSystemExceptionClass() { any() } - /** The `System.Func` delegate type. */ class SystemFuncDelegateType extends SystemUnboundGenericDelegateType { SystemFuncDelegateType() { @@ -199,10 +159,6 @@ class SystemFuncDelegateType extends SystemUnboundGenericDelegateType { } } -/** DEPRECATED. Gets a `System.Func` delegate type. */ -deprecated -SystemFuncDelegateType getSystemFuncDelegateType() { any() } - /** The `System.IComparable` interface. */ class SystemIComparableInterface extends SystemInterface { SystemIComparableInterface() { @@ -223,10 +179,6 @@ class SystemIComparableInterface extends SystemInterface { } } -/** DEPRECATED. Gets the `System.IComparable` interface. */ -deprecated -SystemIComparableInterface getSystemIComparableInterface() { any() } - /** The `System.IComparable` interface. */ class SystemIComparableTInterface extends SystemUnboundGenericInterface { SystemIComparableTInterface() { @@ -247,10 +199,6 @@ class SystemIComparableTInterface extends SystemUnboundGenericInterface { } } -/** DEPRECATED. Gets the `System.IComparable` interface. */ -deprecated -SystemIComparableTInterface getSystemIComparableTInterface() { any() } - /** The `System.IEquatable` interface. */ class SystemIEquatableTInterface extends SystemUnboundGenericInterface { SystemIEquatableTInterface() { @@ -271,10 +219,6 @@ class SystemIEquatableTInterface extends SystemUnboundGenericInterface { } } -/** DEPRECATED. Gets the `System.IEquatable` interface. */ -deprecated -SystemIEquatableTInterface getSystemIEquatableTInterface() { any() } - /** The `System.IFormatProvider` interface. */ class SystemIFormatProviderInterface extends SystemInterface { SystemIFormatProviderInterface() { @@ -282,10 +226,6 @@ class SystemIFormatProviderInterface extends SystemInterface { } } -/** DEPRECATED. Gets the `System.IFormatProvider` interface. */ -deprecated -SystemIFormatProviderInterface getSystemIFormatProviderInterface() { any() } - /** The `System.Int32` structure. */ class SystemInt32Struct extends IntType { /** Gets the `Parse(string, ...)` method. */ @@ -313,10 +253,6 @@ class SystemInt32Struct extends IntType { } } -/** DEPRECATED. Gets the `System.Int32` structure. */ -deprecated -SystemInt32Struct getSystemInt32Struct() { any() } - /** The `System.InvalidCastException` class. */ class SystemInvalidCastExceptionClass extends SystemClass { SystemInvalidCastExceptionClass() { @@ -324,10 +260,6 @@ class SystemInvalidCastExceptionClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.InvalidCastException` class. */ -deprecated -SystemInvalidCastExceptionClass getSystemInvalidCastExceptionClass() { any() } - /** The `System.Lazy` class. */ class SystemLazyClass extends SystemUnboundGenericClass { SystemLazyClass() { @@ -346,10 +278,6 @@ class SystemLazyClass extends SystemUnboundGenericClass { } } -/** DEPRECATED. Gets the `System.Lazy` class. */ -deprecated -SystemLazyClass getSystemLazyClass() { any() } - /** The `System.NullReferenceException` class. */ class SystemNullReferenceExceptionClass extends SystemClass { SystemNullReferenceExceptionClass() { @@ -357,10 +285,6 @@ class SystemNullReferenceExceptionClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.NullReferenceException` class. */ -deprecated -SystemNullReferenceExceptionClass getSystemNullReferenceExceptionClass() { any() } - /** The `System.Object` class. */ class SystemObjectClass extends SystemClass { SystemObjectClass() { @@ -448,10 +372,6 @@ class SystemObjectClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Object` class. */ -deprecated -SystemObjectClass getSystemObjectClass() { any() } - /** The `System.OutOfMemoryException` class. */ class SystemOutOfMemoryExceptionClass extends SystemClass { SystemOutOfMemoryExceptionClass() { @@ -459,10 +379,6 @@ class SystemOutOfMemoryExceptionClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.OutOfMemoryException` class. */ -deprecated -SystemOutOfMemoryExceptionClass getSystemOutOfMemoryExceptionClass() { any() } - /** The `System.OverflowException` class. */ class SystemOverflowExceptionClass extends SystemClass { SystemOverflowExceptionClass() { @@ -470,10 +386,6 @@ class SystemOverflowExceptionClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.OverflowException` class. */ -deprecated -SystemOverflowExceptionClass getSystemOverflowExceptionClass() { any() } - /** The `System.Predicate` delegate type. */ class SystemPredicateDelegateType extends SystemUnboundGenericDelegateType { SystemPredicateDelegateType() { @@ -483,10 +395,6 @@ class SystemPredicateDelegateType extends SystemUnboundGenericDelegateType { } } -/** DEPRECATED. Gets the `System.Predicate` delegate type. */ -deprecated -SystemPredicateDelegateType getSystemPredicateDelegateType() { any() } - /** The `System.String` class. */ class SystemStringClass extends StringType { /** Gets the `Equals(object)` method. */ @@ -642,10 +550,6 @@ class SystemStringClass extends StringType { } } -/** DEPRECATED. Gets the `System.String` class. */ -deprecated -SystemStringClass getSystemStringClass() { any() } - /** A `ToString()` method. */ class ToStringMethod extends Method { ToStringMethod() { @@ -693,10 +597,6 @@ class SystemTypeClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Type` class. */ -deprecated -SystemTypeClass getSystemTypeClass() { any() } - /** The `System.Uri` class. */ class SystemUriClass extends SystemClass { SystemUriClass() { @@ -731,10 +631,6 @@ class SystemUriClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.Uri` class. */ -deprecated -SystemUriClass getSystemUriClass() { any() } - /** The `System.ValueType` class. */ class SystemValueTypeClass extends SystemClass { SystemValueTypeClass() { @@ -742,10 +638,6 @@ class SystemValueTypeClass extends SystemClass { } } -/** DEPRECATED. Gets the `System.ValueType` class. */ -deprecated -SystemValueTypeClass getSystemValueTypeClass() { any() } - /** The `System.IntPtr` type. */ class SystemIntPtrType extends ValueType { SystemIntPtrType() { @@ -755,10 +647,6 @@ class SystemIntPtrType extends ValueType { } } -/** DEPRECATED. Gets the `System.IntPtr` type. */ -deprecated -SystemIntPtrType getSystemIntPtrType() { any() } - /** The `System.IDisposable` interface. */ class SystemIDisposableInterface extends SystemInterface { SystemIDisposableInterface() { @@ -777,10 +665,6 @@ class SystemIDisposableInterface extends SystemInterface { } } -/** DEPRECATED. Gets the `System.IDisposable` interface. */ -deprecated -SystemIDisposableInterface getSystemIDisposableInterface() { any() } - /** A method that overrides `int object.GetHashCode()`. */ class GetHashCodeMethod extends Method { GetHashCodeMethod() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/Owin.qll b/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/Owin.qll index 8be2a6cab763..2a54980bc7fc 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/Owin.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/microsoft/Owin.qll @@ -14,10 +14,6 @@ class MicrosoftOwinNamespace extends Namespace { } } -/** DEPRECATED. Gets the `Microsoft.Owin` namespace. */ -deprecated -MicrosoftOwinNamespace getMicrosoftOwinNamespace() { any() } - /** The `Microsoft.Owin.IOwinRequest` class. */ class MicrosoftOwinIOwinRequestClass extends Class { MicrosoftOwinIOwinRequestClass() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/CodeDom.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/CodeDom.qll index eb06a6373fdc..b5e29ee9db11 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/CodeDom.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/CodeDom.qll @@ -9,7 +9,3 @@ class SystemCodeDomNamespace extends Namespace { this.hasName("CodeDom") } } - -/** DEPRECATED. Gets the `System.CodeDom` namespace. */ -deprecated -SystemCodeDomNamespace getSystemCodeDomNamespace() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Collections.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Collections.qll index 76e797bbeeba..2fa9822ced3b 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Collections.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Collections.qll @@ -10,10 +10,6 @@ class SystemCollectionsNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Collections` namespace. */ -deprecated -SystemCollectionsNamespace getSystemCollectionsNamespace() { any() } - /** An interface in the `System.Collections` namespace. */ class SystemCollectionsInterface extends Interface { SystemCollectionsInterface() { @@ -43,10 +39,6 @@ class SystemCollectionsIComparerInterface extends SystemCollectionsInterface { } } -/** DEPRECATED. Gets the `System.Collections.IComparer` interface. */ -deprecated -SystemCollectionsIComparerInterface getSystemCollectionsIComparerInterface() { any() } - /** The `System.Collections.IEnumerable` interface. */ class SystemCollectionsIEnumerableInterface extends SystemCollectionsInterface { SystemCollectionsIEnumerableInterface() { @@ -54,10 +46,6 @@ class SystemCollectionsIEnumerableInterface extends SystemCollectionsInterface { } } -/** DEPRECATED. Gets the `System.Collections.IEnumerable` interface. */ -deprecated -SystemCollectionsIEnumerableInterface getSystemCollectionsIEnumerableInterface() { any() } - /** The `System.Collections.IEnumerator` interface. */ class SystemCollectionsIEnumeratorInterface extends SystemCollectionsInterface { SystemCollectionsIEnumeratorInterface() { @@ -74,10 +62,6 @@ class SystemCollectionsIEnumeratorInterface extends SystemCollectionsInterface { } } -/** DEPRECATED. Gets the `System.Collections.IEnumerator` interface. */ -deprecated -SystemCollectionsIEnumeratorInterface getSystemCollectionsIEnumeratorInterface() { any() } - /** The `System.Collections.ICollection` interface. */ class SystemCollectionsICollectionInterface extends SystemCollectionsInterface { SystemCollectionsICollectionInterface() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Data.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Data.qll index 18be7b7e9269..09f54916024a 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Data.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Data.qll @@ -10,10 +10,6 @@ class SystemDataNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Data` namespace. */ -deprecated -SystemDataNamespace getSystemDataNamespace() { any() } - /** An interface in the `System.Data` namespace. */ class SystemDataInterface extends Interface { SystemDataInterface() { @@ -37,10 +33,6 @@ class SystemDataIDbCommandInterface extends SystemDataInterface { } } -/** DEPRECATED. Gets the `System.Data.IDbCommand` interface. */ -deprecated -SystemDataIDbCommandInterface getSystemDataIDbCommandInterface() { any() } - /** The `System.Data.IDbConnection` interface. */ class SystemDataIDbConnectionInterface extends SystemDataInterface { SystemDataIDbConnectionInterface() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Diagnostics.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Diagnostics.qll index 182812cf71a3..48119f599d85 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Diagnostics.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Diagnostics.qll @@ -10,10 +10,6 @@ class SystemDiagnosticsNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Diagnostics` namespace. */ -deprecated -SystemDiagnosticsNamespace getSystemDiagnosticsNamespace() { any() } - /** A class in the `System.Diagnostics` namespace. */ class SystemDiagnosticsClass extends Class { SystemDiagnosticsClass() { @@ -40,10 +36,6 @@ class SystemDiagnosticsDebugClass extends SystemDiagnosticsClass { } } -/** DEPRECATED. Gets the `System.Diagnostics.Debug` class. */ -deprecated -SystemDiagnosticsDebugClass getSystemDiagnosticsDebugClass() { any() } - /** The `System.Diagnostics.ProcessStartInfo` class. */ class SystemDiagnosticsProcessStartInfoClass extends SystemDiagnosticsClass { SystemDiagnosticsProcessStartInfoClass() { @@ -73,7 +65,3 @@ class SystemDiagnosticsProcessClass extends SystemDiagnosticsClass { result.getReturnType() instanceof SystemDiagnosticsProcessClass } } - -/** DEPRECATED. Gets the `System.Diagnostics.Process` class. */ -deprecated -SystemDiagnosticsProcessClass getSystemDiagnosticsProcessClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/IO.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/IO.qll index cf3d62bdae9e..f645df32b2c2 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/IO.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/IO.qll @@ -10,10 +10,6 @@ class SystemIONamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.IO` namespace. */ -deprecated -SystemIONamespace getSystemIONamespace() { any() } - /** A class in the `System.IO` namespace. */ class SystemIOClass extends Class { SystemIOClass() { @@ -35,11 +31,6 @@ class SystemIOFileClass extends SystemIOClass { } } -/** DEPRECATED. Gets the `System.IO.File` class. */ -deprecated -SystemIOFileClass getSystemIOFileClass() { any() } - - /** The `System.IO.FileStream` class. */ class SystemIOFileStreamClass extends SystemIOClass { SystemIOFileStreamClass() { @@ -61,10 +52,6 @@ class SystemIOPathClass extends SystemIOClass { } } -/** DEPRECATED. Gets the `System.IO.Path` class. */ -deprecated -SystemIOPathClass getSystemIOPathClass() { any() } - /** The `System.IO.StringReader` class. */ class SystemIOStringReaderClass extends SystemIOClass { SystemIOStringReaderClass() { @@ -72,10 +59,6 @@ class SystemIOStringReaderClass extends SystemIOClass { } } -/** DEPRECATED. Gets the `System.IO.StringReader` class. */ -deprecated -SystemIOStringReaderClass getSystemIOStringReaderClass() { any() } - /** The `System.IO.Stream` class. */ class SystemIOStreamClass extends SystemIOClass { SystemIOStreamClass() { @@ -123,10 +106,6 @@ class SystemIOStreamClass extends SystemIOClass { } } -/** DEPRECATED. Gets the `System.IO.Stream` class. */ -deprecated -SystemIOStreamClass getSystemIOStreamClass() { any() } - /** The `System.IO.MemoryStream` class. */ class SystemIOMemoryStreamClass extends SystemIOClass { SystemIOMemoryStreamClass() { @@ -139,7 +118,3 @@ class SystemIOMemoryStreamClass extends SystemIOClass { result.hasName("ToArray") } } - -/** DEPRECATED. Gets the `System.IO.MemoryStream` class. */ -deprecated -SystemIOMemoryStreamClass getSystemIOMemoryStreamClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Reflection.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Reflection.qll index f13887c854de..a4e5bfaf5a6f 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Reflection.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Reflection.qll @@ -10,10 +10,6 @@ class SystemReflectionNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Reflection` namespace. */ -deprecated -SystemReflectionNamespace getSystemReflectionNamespace() { any() } - /** A class in the `System.Reflection` namespace. */ class SystemReflectionClass extends Class { SystemReflectionClass() { @@ -58,17 +54,9 @@ class SystemReflectionMethodBaseClass extends SystemReflectionClass { } } -/** DEPRECATED. Gets the `System.Reflection.MethodBase` class. */ -deprecated -SystemReflectionMethodBaseClass getSystemReflectionMethodBaseClass() { any() } - /** The `System.Reflection.MethodInfo` class. */ class SystemReflectionMethodInfoClass extends SystemReflectionClass { SystemReflectionMethodInfoClass() { this.hasName("MethodInfo") } } - -/** DEPRECATED. Gets the `System.Reflection.MethodInfo` class. */ -deprecated -SystemReflectionMethodInfoClass getSystemReflectionMethodInfoClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Runtime.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Runtime.qll index 0de50d85ca66..8c03fc494202 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Runtime.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Runtime.qll @@ -9,7 +9,3 @@ class SystemRuntimeNamespace extends Namespace { this.hasName("Runtime") } } - -/** DEPRECATED. Gets the `System.Runtime` namespace. */ -deprecated -SystemRuntimeNamespace getSystemRuntimeNamespace() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Text.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Text.qll index 9f9173ea10ca..4b50128cf1df 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Text.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Text.qll @@ -10,10 +10,6 @@ class SystemTextNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Text` namespace. */ -deprecated -SystemTextNamespace getSystemTextNamespace() { any() } - /** A class in the `System.Text` namespace. */ class SystemTextClass extends Class { SystemTextClass() { @@ -33,10 +29,6 @@ class SystemTextStringBuilderClass extends SystemTextClass { } } -/** DEPRECATED. Gets the `System.Text.StringBuilder` class. */ -deprecated -SystemTextStringBuilderClass getSystemTextStringBuilderClass() { any() } - /** The `System.Text.Encoding` class. */ class SystemTextEncodingClass extends SystemTextClass { SystemTextEncodingClass() { @@ -58,7 +50,3 @@ class SystemTextEncodingClass extends SystemTextClass { result = this.getAMethod("GetChars") } } - -/** DEPRECATED. Gets the `System.Text.Encoding` class. */ -deprecated -SystemTextEncodingClass getSystemTextEncodingClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Threading.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Threading.qll index be5d225f35b9..3c147882d194 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Threading.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Threading.qll @@ -9,7 +9,3 @@ class SystemThreadingNamespace extends Namespace { this.hasName("Threading") } } - -/** DEPRECATED. Gets the `System.Threading` namespace. */ -deprecated -SystemThreadingNamespace getSystemThreadingNamespace() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Web.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Web.qll index fc0d2e3b8f69..a46926c8342a 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Web.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Web.qll @@ -11,10 +11,6 @@ class SystemWebNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Web` namespace. */ -deprecated -SystemWebNamespace getSystemWebNamespace() { any() } - /** A class in the `System.Web` namespace. */ class SystemWebClass extends Class { SystemWebClass() { @@ -288,19 +284,3 @@ class SystemWebHtmlString extends SystemWebClass { this.hasName("HtmlString") } } - -/** DEPRECATED. Gets the `System.Web.HttpRequest` class. */ -deprecated -SystemWebHttpRequestClass getSystemWebHttpRequestClass() { any() } - -/** DEPRECATED. Gets the `System.Web.UnvalidatedRequestValues` class. */ -deprecated -SystemWebUnvalidatedRequestValues getSystemWebUnvalidatedRequestValues() { any() } - -/** DEPRECATED. Gets the `System.Web.HttpRequestMessage` class. */ -deprecated -SystemWebHttpRequestMessageClass getSystemWebHttpRequestMessageClass() { any() } - -/** DEPRECATED. Gets the `System.Web.HttpResponse` class. */ -deprecated -SystemWebHttpResponseClass getSystemWebHttpResponseClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/Xml.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/Xml.qll index eba7beb3a088..cb8c855b0206 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/Xml.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/Xml.qll @@ -18,10 +18,6 @@ class SystemXmlSchemaNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Xml` namespace. */ -deprecated -SystemXmlNamespace getSystemXmlNamespace() { any() } - /** A class in the `System.Xml` namespace. */ class SystemXmlClass extends Class { SystemXmlClass() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/codedom/Compiler.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/codedom/Compiler.qll index 72610a13ebca..6a1da6be8731 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/codedom/Compiler.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/codedom/Compiler.qll @@ -10,10 +10,6 @@ class SystemCodeDomCompilerNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.CodeDom.Compiler` namespace. */ -deprecated -SystemCodeDomCompilerNamespace getSystemCodeDomCompilerNamespace() { any() } - /** A reference type in the `System.CodeDom.Compiler` namespace. */ class SystemCodeDomCompilerClass extends RefType { SystemCodeDomCompilerClass() { @@ -28,10 +24,6 @@ class SystemCodeDomCompilerGeneratedCodeAttributeClass extends SystemCodeDomComp } } -/** DEPRECATED. Gets the `System.CodeDom.Compiler.GeneratedCodeAttribute` class. */ -deprecated -SystemCodeDomCompilerGeneratedCodeAttributeClass getSystemCodeDomCompilerGeneratedCodeAttributeClass() { any() } - /** The `System.CodeDom.Compiler.ICodeCompiler` class. */ class SystemCodeDomCompilerICodeCompilerClass extends SystemCodeDomCompilerClass { SystemCodeDomCompilerICodeCompilerClass() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Generic.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Generic.qll index 9179a2b58fe0..17358fbac1d0 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Generic.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Generic.qll @@ -10,10 +10,6 @@ class SystemCollectionsGenericNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Collections.Generic` namespace. */ -deprecated -SystemCollectionsGenericNamespace getSystemCollectionsGenericNamespace() { any() } - /** An unbound generic interface in the `System.Collections.Generic` namespace. */ class SystemCollectionsGenericUnboundGenericInterface extends UnboundGenericInterface { SystemCollectionsGenericUnboundGenericInterface() { @@ -50,10 +46,6 @@ class SystemCollectionsGenericIComparerTInterface extends SystemCollectionsGener } } -/** DEPRECATED. Gets the `System.Collections.Generic.IComparer` interface. */ -deprecated -SystemCollectionsGenericIComparerTInterface getSystemCollectionsGenericIComparerTInterface() { any() } - /** The `System.Collections.Generic.IEqualityComparer` interface. */ class SystemCollectionsGenericIEqualityComparerTInterface extends SystemCollectionsGenericUnboundGenericInterface { SystemCollectionsGenericIEqualityComparerTInterface() { @@ -76,10 +68,6 @@ class SystemCollectionsGenericIEqualityComparerTInterface extends SystemCollecti } } -/** DEPRECATED. Gets the `System.Collections.Generic.IEqualityComparer` interface. */ -deprecated -SystemCollectionsGenericIEqualityComparerTInterface getSystemCollectionsGenericIEqualityComparerTInterface() { any() } - /** The `System.Collections.Generic.IEnumerable` interface. */ class SystemCollectionsGenericIEnumerableTInterface extends SystemCollectionsGenericUnboundGenericInterface { SystemCollectionsGenericIEnumerableTInterface() { @@ -89,10 +77,6 @@ class SystemCollectionsGenericIEnumerableTInterface extends SystemCollectionsGen } } -/** DEPRECATED. Gets the `System.Collections.Generic.IEnumerable` interface. */ -deprecated -SystemCollectionsGenericIEnumerableTInterface getSystemCollectionsGenericIEnumerableTInterface() { any() } - /** The `System.Collections.Generic.IEnumerator` interface. */ class SystemCollectionsGenericIEnumeratorInterface extends SystemCollectionsGenericUnboundGenericInterface { SystemCollectionsGenericIEnumeratorInterface() { @@ -111,10 +95,6 @@ class SystemCollectionsGenericIEnumeratorInterface extends SystemCollectionsGene } } -/** DEPRECATED. Gets the `System.Collections.Generic.IEnumerator` interface. */ -deprecated -SystemCollectionsGenericIEnumeratorInterface getSystemCollectionsGenericIEnumeratorInterface() { any() } - /** The `System.Collections.Generic.IList` interface. */ class SystemCollectionsGenericIListTInterface extends SystemCollectionsGenericUnboundGenericInterface { SystemCollectionsGenericIListTInterface() { @@ -124,10 +104,6 @@ class SystemCollectionsGenericIListTInterface extends SystemCollectionsGenericUn } } -/** DEPRECATED. Gets the `System.Collections.Generic.IList` interface. */ -deprecated -SystemCollectionsGenericIListTInterface getSystemCollectionsGenericIListTInterface() { any() } - /** The `System.Collections.Generic.KeyValuePair` structure. */ class SystemCollectionsGenericKeyValuePairStruct extends SystemCollectionsGenericUnboundGenericStruct { SystemCollectionsGenericKeyValuePairStruct() { @@ -155,10 +131,6 @@ class SystemCollectionsGenericKeyValuePairStruct extends SystemCollectionsGeneri } } -/** DEPRECATED. Gets the `System.Collections.Generic.KeyValuePair` structure. */ -deprecated -SystemCollectionsGenericKeyValuePairStruct getSystemCollectionsGenericKeyValuePairStruct() { any() } - /** The `System.Collections.Generic.ICollection<>` interface. */ class SystemCollectionsGenericICollectionInterface extends SystemCollectionsGenericUnboundGenericInterface { SystemCollectionsGenericICollectionInterface() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Specialized.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Specialized.qll index d99633ec0394..4d36a558ea54 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Specialized.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/collections/Specialized.qll @@ -10,10 +10,6 @@ class SystemCollectionsSpecializedNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Collections.Specialized` namespace. */ -deprecated -SystemCollectionsSpecializedNamespace getSystemCollectionsSpecializedNamespace() { any() } - /** A class in the `System.Collections.Specialized` namespace. */ class SystemCollectionsSpecializedClass extends Class { SystemCollectionsSpecializedClass() { @@ -27,7 +23,3 @@ class SystemCollectionsSpecializedNameValueCollectionClass extends SystemCollect this.hasName("NameValueCollection") } } - -/** DEPRECATED. Gets the `System.Collections.Specialized.NameValueCollection` class. */ -deprecated -SystemCollectionsSpecializedNameValueCollectionClass getSystemCollectionsSpecializedNameValueCollectionClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/data/SqlClient.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/data/SqlClient.qll index 3a6e6f6c4fa2..8961aad8f612 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/data/SqlClient.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/data/SqlClient.qll @@ -10,10 +10,6 @@ class SystemDataSqlClientNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Data.SqlClient` namespace. */ -deprecated -SystemDataSqlClientNamespace getSystemDataSqlClientNamespace() { any() } - /** A class in the `System.Data.SqlClient` namespace. */ class SystemDataSqlClientClass extends Class { SystemDataSqlClientClass() { @@ -28,10 +24,6 @@ class SystemDataSqlClientSqlDataAdapterClass extends SystemDataSqlClientClass { } } -/** DEPRECATED. Gets the `System.Data.SqlClient.SqlDataAdapter` class. */ -deprecated -SystemDataSqlClientSqlDataAdapterClass getSystemDataSqlClientSqlDataAdapterClass() { any() } - /** The `System.Data.SqlClient.SqlConnection` class. */ class SystemDataSqlClientSqlConnectionClass extends SystemDataSqlClientClass { SystemDataSqlClientSqlConnectionClass() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/io/Compression.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/io/Compression.qll index 95ad2c3b5ad7..14b42dadf10f 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/io/Compression.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/io/Compression.qll @@ -10,10 +10,6 @@ class SystemIOCompressionNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.IO` namespace. */ -deprecated -SystemIOCompressionNamespace getSystemIOCompressionNamespace() { any() } - /** A class in the `System.IO.Compression` namespace. */ class SystemIOCompressionClass extends Class { SystemIOCompressionClass() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/runtime/InteropServices.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/runtime/InteropServices.qll index a2ce047a0c90..48b55e97324f 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/runtime/InteropServices.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/runtime/InteropServices.qll @@ -11,10 +11,6 @@ class SystemRuntimeInteropServicesNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Runtime.InteropServices` namespace. */ -deprecated -SystemRuntimeInteropServicesNamespace getSystemRuntimeInteropServicesNamespace() { any() } - /** A class in the `System.Runtime.InteropServices` namespace. */ class SystemRuntimeInteropServicesClass extends Class { SystemRuntimeInteropServicesClass() { @@ -29,10 +25,6 @@ class SystemRuntimeInteropServicesDllImportAttributeClass extends SystemRuntimeI } } -/** DEPRECATED. Gets the `System.Runtime.InteropServices.DllImportAttribute` class. */ -deprecated -SystemRuntimeInteropServicesDllImportAttributeClass getSystemRuntimeInteropServicesDllImportAttributeClass() { any() } - /** The `System.Runtime.InteropServices.Marshal` class. */ class SystemRuntimeInteropServicesMarshalClass extends SystemRuntimeInteropServicesClass { SystemRuntimeInteropServicesMarshalClass() { @@ -70,17 +62,9 @@ class SystemRuntimeInteropServicesMarshalClass extends SystemRuntimeInteropServi } } -/** DEPRECATED. Gets the `System.Runtime.InteropServices.Marshal` class. */ -deprecated -SystemRuntimeInteropServicesMarshalClass getSystemRuntimeInteropServicesMarshalClass() { any() } - /** The `System.Runtime.InteropServices.ComImportAttribute` class. */ class SystemRuntimeInteropServicesComImportAttributeClass extends SystemRuntimeInteropServicesClass { SystemRuntimeInteropServicesComImportAttributeClass() { this.hasName("ComImportAttribute") } } - -/** DEPRECATED. Gets the `System.Runtime.InteropServices.ComImportAttribute` class. */ -deprecated -SystemRuntimeInteropServicesComImportAttributeClass getSystemRuntimeInteropServicesComImportAttributeClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/threading/Tasks.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/threading/Tasks.qll index d6e0ac818e55..2e5e4739afdc 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/threading/Tasks.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/threading/Tasks.qll @@ -10,10 +10,6 @@ class SystemThreadingTasksNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Threading.Tasks` namespace. */ -deprecated -SystemThreadingTasksNamespace getSystemThreadingTasksNamespace() { any() } - /** A class in the `System.Threading.Tasks` namespace. */ class SystemThreadingTasksClass extends Class { SystemThreadingTasksClass() { @@ -35,10 +31,6 @@ class SystemThreadingTasksTaskClass extends SystemThreadingTasksClass { } } -/** DEPRECATED. Gets the `System.Threading.Tasks.Task` class. */ -deprecated -SystemThreadingTasksTaskClass getSystemThreadingTasksTaskClass() { any() } - /** The `System.Threading.Tasks.Task` class. */ class SystemThreadingTasksTaskTClass extends SystemThreadingTasksUnboundGenericClass { SystemThreadingTasksTaskTClass() { @@ -54,7 +46,3 @@ class SystemThreadingTasksTaskTClass extends SystemThreadingTasksUnboundGenericC result.getType() = this.getTypeParameter(0) } } - -/** DEPRECATED. Gets the `System.Threading.Tasks.Task` class. */ -deprecated -SystemThreadingTasksTaskTClass getSystemThreadingTasksTaskTClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/web/Services.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/web/Services.qll index 0f8da33e29df..21bc2c269ad6 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/web/Services.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/web/Services.qll @@ -10,10 +10,6 @@ class SystemWebServicesNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Web.Services` namespace. */ -deprecated -SystemWebServicesNamespace getSystemWebServicesNamespace() { any() } - /** A class in the `System.Web.Services` namespace. */ class SystemWebServicesClass extends Class { SystemWebServicesClass() { @@ -27,7 +23,3 @@ class SystemWebServicesWebMethodAttributeClass extends SystemWebServicesClass { this.hasName("WebMethodAttribute") } } - -/** DEPRECATED. Gets the `System.Web.Services.WebMethodAttribute` class. */ -deprecated -SystemWebServicesWebMethodAttributeClass getSystemWebServicesWebMethodAttributeClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/web/UI.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/web/UI.qll index 82f814a38d24..ff1627e6b83a 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/web/UI.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/web/UI.qll @@ -10,10 +10,6 @@ class SystemWebUINamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Web.UI` namespace. */ -deprecated -SystemWebUINamespace getSystemWebUINamespace() { any() } - /** A class in the `System.Web.UI` namespace. */ class SystemWebUIClass extends Class { SystemWebUIClass() { @@ -28,10 +24,6 @@ class SystemWebUIControlClass extends SystemWebUIClass { } } -/** DEPRECATED. Gets the `System.UI.Control` class. */ -deprecated -SystemWebUIControlClass getSystemWebUIControlClass() { any() } - /** The `System.Web.UI.Page` class. */ class SystemWebUIPageClass extends SystemWebUIClass { SystemWebUIPageClass() { @@ -75,10 +67,6 @@ class SystemWebUIPageClass extends SystemWebUIClass { } } -/** DEPRECATED. Gets the `System.UI.Page` class. */ -deprecated -SystemWebUIPageClass getSystemWebUIPageClass() { any() } - /** The `System.Web.UI.HtmlTextWriter` class. */ class SystemWebUIHtmlTextWriterClass extends SystemWebUIClass { SystemWebUIHtmlTextWriterClass() { @@ -116,10 +104,6 @@ class SystemWebUIHtmlTextWriterClass extends SystemWebUIClass { } } -/** DEPRECATED. Gets the `System.UI.HtmlTextWriter` class. */ -deprecated -SystemWebUIHtmlTextWriterClass getSystemWebUIHtmlTextWriterClass() { any() } - /** The `System.Web.UI.AttributeCollection` class. */ class SystemWebUIAttributeCollectionClass extends SystemWebUIClass { SystemWebUIAttributeCollectionClass() { @@ -139,10 +123,6 @@ class SystemWebUIAttributeCollectionClass extends SystemWebUIClass { } } -/** DEPRECATED. Gets the `System.UI.AttributeCollection` class. */ -deprecated -SystemWebUIAttributeCollectionClass getSystemWebUIAttributeCollectionClass() { any() } - /** The `System.Web.UI.ClientScriptManager` class. */ class SystemWebUIClientScriptManagerClass extends SystemWebUIClass { SystemWebUIClientScriptManagerClass() { @@ -161,7 +141,3 @@ class SystemWebUIClientScriptManagerClass extends SystemWebUIClass { result.hasName("RegisterClientScriptBlock") } } - -/** DEPRECATED. Gets the `System.UI.ClientScriptManager` class. */ -deprecated -SystemWebUIClientScriptManagerClass getSystemWebUIClientScriptManagerClass() { any() } diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll b/csharp/ql/src/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll index 05a577dd4bd5..5dad4dc72bdd 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/system/web/ui/WebControls.qll @@ -10,10 +10,6 @@ class SystemWebUIWebControlsNamespace extends Namespace { } } -/** DEPRECATED. Gets the `System.Web.UI.WebControls` namespace. */ -deprecated -SystemWebUIWebControlsNamespace getSystemWebUIWebControlsNamespace() { any() } - /** A class in the `System.Web.UI.WebControls` namespace. */ class SystemWebUIWebControlsClass extends Class { SystemWebUIWebControlsClass() { @@ -37,10 +33,6 @@ class SystemWebUIWebControlsTextBoxClass extends SystemWebUIWebControlsClass { } } -/** DEPRECATED. Gets the `System.Web.UI.WebControls.TextBox` class. */ -deprecated -SystemWebUIWebControlsTextBoxClass getSystemWebUIWebControlsTextBoxClass() { any() } - /** The `System.Web.UI.WebControls.Label` class. */ class SystemWebUIWebControlsLabelClass extends SystemWebUIWebControlsClass { SystemWebUIWebControlsLabelClass() { diff --git a/csharp/ql/src/semmle/code/csharp/frameworks/test/VisualStudio.qll b/csharp/ql/src/semmle/code/csharp/frameworks/test/VisualStudio.qll index 062b6e584b21..9e73c73f0a06 100644 --- a/csharp/ql/src/semmle/code/csharp/frameworks/test/VisualStudio.qll +++ b/csharp/ql/src/semmle/code/csharp/frameworks/test/VisualStudio.qll @@ -114,7 +114,3 @@ class AssertFailedExceptionClass extends ExceptionClass { this.hasName("AssertFailedException") } } - -/** DEPRECATED. Gets the `Microsoft.VisualStudio.TestTools.UnitTesting.Assert` class. */ -deprecated -VSTestAssertClass getVSTestAssertClass() { any() } From d595f20cb1971f3357e55881ab255646a52beb13 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 17 Dec 2018 15:29:10 +0000 Subject: [PATCH 32/69] JS: add to correctness-more suite --- javascript/config/suites/javascript/correctness-more | 1 + 1 file changed, 1 insertion(+) diff --git a/javascript/config/suites/javascript/correctness-more b/javascript/config/suites/javascript/correctness-more index 2e57bcd7327b..540f88387b69 100644 --- a/javascript/config/suites/javascript/correctness-more +++ b/javascript/config/suites/javascript/correctness-more @@ -12,6 +12,7 @@ + semmlecode-javascript-queries/LanguageFeatures/InconsistentNew.ql: /Correctness/Language Features + semmlecode-javascript-queries/LanguageFeatures/SpuriousArguments.ql: /Correctness/Language Features + semmlecode-javascript-queries/Statements/MisleadingIndentationAfterControlStmt.ql: /Correctness/Statements ++ semmlecode-javascript-queries/Statements/MissingIndexAdjustmentAfterConcurrentModification.ql: /Correctness/Statements + semmlecode-javascript-queries/Statements/ReturnOutsideFunction.ql: /Correctness/Statements + semmlecode-javascript-queries/Statements/SuspiciousUnusedLoopIterationVariable.ql: /Correctness/Statements + semmlecode-javascript-queries/Statements/UselessConditional.ql: /Correctness/Statements From e1c25c81f657a41789e4f385030deaafd13175e7 Mon Sep 17 00:00:00 2001 From: Asger F Date: Mon, 17 Dec 2018 16:34:18 +0000 Subject: [PATCH 33/69] JS: add change note --- change-notes/1.20/analysis-javascript.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.20/analysis-javascript.md b/change-notes/1.20/analysis-javascript.md index 14a4104c7ddc..f31fd00787e1 100644 --- a/change-notes/1.20/analysis-javascript.md +++ b/change-notes/1.20/analysis-javascript.md @@ -13,6 +13,7 @@ | Double escaping or unescaping (`js/double-escaping`) | correctness, security, external/cwe/cwe-116 | Highlights potential double escaping or unescaping of special characters, indicating a possible violation of [CWE-116](https://cwe.mitre.org/data/definitions/116.html). Results are shown on LGTM by default. | | Incomplete URL substring sanitization | correctness, security, external/cwe/cwe-020 | Highlights URL sanitizers that are likely to be incomplete, indicating a violation of [CWE-020](https://cwe.mitre.org/data/definitions/20.html). Results shown on LGTM by default. | | Incorrect suffix check (`js/incorrect-suffix-check`) | correctness, security, external/cwe/cwe-020 | Highlights error-prone suffix checks based on `indexOf`, indicating a potential violation of [CWE-20](https://cwe.mitre.org/data/definitions/20.html). Results are shown on LGTM by default. | +| Missing index adjustment after concurrent modification (`js/missing-index-adjustment-after-concurrent-modification`) | correctness | Highlights code that removes an element from an array while iterating over it, causing the loop to skip over some elements. Results are shown on LGTM by default. | | Useless comparison test (`js/useless-comparison-test`) | correctness | Highlights code that is unreachable due to a numeric comparison that is always true or always false. Results are shown on LGTM by default. | ## Changes to existing queries From edf1df1577312d4fb1ff6b7e7a8214f04a16c892 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Tue, 18 Dec 2018 10:43:12 +0100 Subject: [PATCH 34/69] C#: Remove tests for deprecated predicates --- .../ssa/DefAdjacentUncertainRead.expected | 200 ----------- .../dataflow/ssa/DefAdjacentUncertainRead.ql | 5 - .../ssa/ReadAdjacentUncertainRead.expected | 145 -------- .../dataflow/ssa/ReadAdjacentUncertainRead.ql | 5 - .../ssa/SsaAdjacentUncertainRead.expected | 334 ------------------ .../dataflow/ssa/SsaAdjacentUncertainRead.ql | 5 - 6 files changed, 694 deletions(-) delete mode 100644 csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.expected delete mode 100644 csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.ql delete mode 100644 csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.expected delete mode 100644 csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.ql delete mode 100644 csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.expected delete mode 100644 csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.ql diff --git a/csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.expected deleted file mode 100644 index e710a6e870fb..000000000000 --- a/csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.expected +++ /dev/null @@ -1,200 +0,0 @@ -WARNING: Predicate getAFirstUncertainRead has been deprecated and may be removed in future (DefAdjacentUncertainRead.ql:4,18-40) -| Capture.cs:6:16:6:16 | i | Capture.cs:6:16:6:16 | i | Capture.cs:8:17:8:17 | access to parameter i | -| Capture.cs:6:16:6:16 | i | Capture.cs:13:13:13:17 | ... = ... | Capture.cs:14:17:14:17 | access to parameter i | -| Capture.cs:8:13:8:13 | x | Capture.cs:8:13:8:17 | Int32 x = ... | Capture.cs:34:13:34:13 | access to local variable x | -| Capture.cs:8:13:8:13 | x | Capture.cs:15:13:15:17 | ... = ... | Capture.cs:16:17:16:17 | access to local variable x | -| Capture.cs:8:13:8:13 | x | Capture.cs:43:9:43:13 | ... = ... | Capture.cs:44:11:44:11 | access to local variable x | -| Capture.cs:10:16:10:16 | a | Capture.cs:10:16:27:9 | Action a = ... | Capture.cs:38:9:38:9 | access to local variable a | -| Capture.cs:17:17:17:17 | y | Capture.cs:17:17:17:21 | Int32 y = ... | Capture.cs:26:17:26:17 | access to local variable y | -| Capture.cs:19:20:19:20 | b | Capture.cs:19:20:23:13 | Action b = ... | Capture.cs:25:13:25:13 | access to local variable b | -| Capture.cs:29:13:29:13 | z | Capture.cs:29:13:29:17 | Int32 z = ... | Capture.cs:35:13:35:13 | access to local variable z | -| Capture.cs:29:13:29:13 | z | Capture.cs:37:9:37:13 | ... = ... | Capture.cs:41:13:41:13 | access to local variable z | -| Capture.cs:30:16:30:16 | c | Capture.cs:30:16:30:35 | Action c = ... | Capture.cs:32:9:32:9 | access to local variable c | -| Capture.cs:50:20:50:20 | a | Capture.cs:50:20:50:20 | a | Capture.cs:54:9:54:9 | access to parameter a | -| Capture.cs:52:16:52:16 | b | Capture.cs:52:16:52:43 | Action b = ... | Capture.cs:53:9:53:9 | access to local variable b | -| Capture.cs:57:57:57:63 | strings | Capture.cs:57:57:57:63 | strings | Capture.cs:61:9:61:15 | access to parameter strings | -| Capture.cs:59:13:59:13 | i | Capture.cs:59:13:59:17 | Int32 i = ... | Capture.cs:62:13:62:13 | access to local variable i | -| Capture.cs:60:27:60:27 | e | Capture.cs:60:27:60:38 | Func e = ... | Capture.cs:61:24:61:24 | access to local variable e | -| Capture.cs:65:45:65:51 | strings | Capture.cs:65:45:65:51 | strings | Capture.cs:68:18:68:24 | access to parameter strings | -| Capture.cs:68:32:68:32 | s | Capture.cs:68:32:68:32 | s | Capture.cs:68:37:68:37 | access to parameter s | -| Capture.cs:69:25:69:25 | s | Capture.cs:69:25:69:25 | s | Capture.cs:69:59:69:59 | access to parameter s | -| Capture.cs:73:67:73:73 | strings | Capture.cs:73:67:73:73 | strings | Capture.cs:77:9:77:15 | access to parameter strings | -| Capture.cs:75:13:75:13 | i | Capture.cs:75:13:75:17 | Int32 i = ... | Capture.cs:78:13:78:13 | access to local variable i | -| Capture.cs:76:63:76:63 | e | Capture.cs:76:63:76:81 | Expression> e = ... | Capture.cs:77:24:77:24 | access to local variable e | -| Capture.cs:81:28:81:28 | i | Capture.cs:81:28:81:28 | i | Capture.cs:81:34:81:34 | access to parameter i | -| Capture.cs:83:65:83:71 | strings | Capture.cs:83:65:83:71 | strings | Capture.cs:87:9:87:15 | access to parameter strings | -| Capture.cs:86:64:86:64 | e | Capture.cs:86:64:86:73 | Expression> e = ... | Capture.cs:87:23:87:23 | access to local variable e | -| Capture.cs:92:18:92:18 | d | Capture.cs:92:18:92:18 | d | Capture.cs:92:24:92:24 | access to parameter d | -| Capture.cs:98:17:98:17 | x | Capture.cs:98:17:98:21 | Int32 x = ... | Capture.cs:99:20:99:20 | access to local variable x | -| Capture.cs:102:13:102:13 | z | Capture.cs:105:13:105:17 | ... = ... | Capture.cs:106:20:106:20 | access to local variable z | -| Capture.cs:117:17:117:17 | x | Capture.cs:117:17:117:21 | Int32 x = ... | Capture.cs:118:17:118:17 | access to local variable x | -| Capture.cs:122:13:122:13 | b | Capture.cs:125:13:125:17 | ... = ... | Capture.cs:126:17:126:17 | access to local variable b | -| Capture.cs:130:13:130:13 | c | Capture.cs:130:13:130:18 | Int32 c = ... | Capture.cs:137:13:137:13 | access to local variable c | -| Capture.cs:130:13:130:13 | c | Capture.cs:133:13:133:17 | ... = ... | Capture.cs:134:17:134:17 | access to local variable c | -| Capture.cs:139:13:139:13 | d | Capture.cs:139:13:139:18 | Int32 d = ... | Capture.cs:145:13:145:13 | access to local variable d | -| Capture.cs:154:13:154:13 | f | Capture.cs:154:13:154:18 | Int32 f = ... | Capture.cs:155:13:155:13 | access to local variable f | -| Capture.cs:168:13:168:13 | h | Capture.cs:171:13:171:17 | ... = ... | Capture.cs:177:17:177:17 | access to local variable h | -| Capture.cs:198:28:198:29 | eh | Capture.cs:198:28:198:44 | MyEventHandler eh = ... | Capture.cs:199:27:199:28 | access to local variable eh | -| Capture.cs:203:28:203:30 | eh2 | Capture.cs:203:28:203:45 | MyEventHandler eh2 = ... | Capture.cs:204:27:204:29 | access to local variable eh2 | -| Capture.cs:210:24:210:24 | p | Capture.cs:210:24:210:59 | Process p = ... | Capture.cs:213:17:213:17 | access to local variable p | -| Capture.cs:212:30:212:35 | exited | Capture.cs:212:30:212:71 | EventHandler exited = ... | Capture.cs:213:29:213:34 | access to local variable exited | -| Capture.cs:229:13:229:13 | i | Capture.cs:232:9:232:13 | ... = ... | Capture.cs:237:34:237:34 | access to local variable i | -| Consistency.cs:7:25:7:25 | b | Consistency.cs:7:25:7:25 | b | Consistency.cs:11:17:11:17 | access to parameter b | -| Consistency.cs:15:17:15:17 | i | Consistency.cs:15:17:15:21 | Int32 i = ... | Consistency.cs:16:17:16:17 | access to local variable i | -| Consistency.cs:25:29:25:29 | c | Consistency.cs:25:29:25:29 | Consistency c | Consistency.cs:26:13:26:13 | access to local variable c | -| Consistency.cs:30:30:30:30 | c | Consistency.cs:32:9:32:29 | ... = ... | Consistency.cs:33:9:33:9 | access to parameter c | -| Consistency.cs:38:13:38:13 | i | Consistency.cs:39:28:39:32 | ... = ... | Consistency.cs:39:39:39:39 | access to local variable i | -| Consistency.cs:44:11:44:11 | s | Consistency.cs:44:11:44:11 | S s | Consistency.cs:45:9:45:9 | access to local variable s | -| Consistency.cs:49:30:49:30 | a | Consistency.cs:49:30:49:30 | a | Consistency.cs:49:47:49:47 | access to parameter a | -| Consistency.cs:49:37:49:37 | i | Consistency.cs:49:37:49:37 | i | Consistency.cs:49:49:49:49 | access to parameter i | -| Consistency.cs:51:20:51:20 | a | Consistency.cs:51:20:51:20 | a | Consistency.cs:53:28:53:28 | access to parameter a | -| DefUse.cs:3:26:3:26 | w | DefUse.cs:3:26:3:26 | w | DefUse.cs:9:13:9:13 | access to parameter w | -| DefUse.cs:3:26:3:26 | w | DefUse.cs:19:13:19:18 | ... = ... | DefUse.cs:20:17:20:17 | access to parameter w | -| DefUse.cs:3:26:3:26 | w | DefUse.cs:29:13:29:18 | ... = ... | DefUse.cs:35:13:35:13 | access to parameter w | -| DefUse.cs:5:13:5:13 | x | DefUse.cs:5:13:5:17 | Int32 x = ... | DefUse.cs:11:13:11:13 | access to local variable x | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:6:14:6:19 | Int64 y = ... | DefUse.cs:8:13:8:13 | access to local variable y | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:13:13:13:18 | ... = ... | DefUse.cs:14:17:14:17 | access to local variable y | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:18:13:18:18 | ... = ... | DefUse.cs:23:13:23:13 | access to local variable y | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:28:13:28:18 | ... = ... | DefUse.cs:34:13:34:13 | access to local variable y | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:39:13:39:18 | ... = ... | DefUse.cs:42:13:42:13 | access to local variable y | -| DefUse.cs:44:13:44:13 | z | DefUse.cs:44:13:44:17 | Int32 z = ... | DefUse.cs:45:13:45:13 | access to local variable z | -| DefUse.cs:44:13:44:13 | z | DefUse.cs:47:23:47:23 | access to local variable z | DefUse.cs:48:13:48:13 | access to local variable z | -| DefUse.cs:44:13:44:13 | z | DefUse.cs:50:23:50:23 | access to local variable z | DefUse.cs:51:13:51:13 | access to local variable z | -| DefUse.cs:59:13:59:13 | i | DefUse.cs:59:13:59:17 | Int32 i = ... | DefUse.cs:61:13:61:13 | access to local variable i | -| DefUse.cs:59:13:59:13 | i | DefUse.cs:71:9:71:13 | ... = ... | DefUse.cs:72:9:72:9 | access to local variable i | -| DefUse.cs:59:13:59:13 | i | DefUse.cs:72:9:72:11 | ...++ | DefUse.cs:73:13:73:13 | access to local variable i | -| DefUse.cs:59:13:59:13 | i | DefUse.cs:75:9:75:13 | ... = ... | DefUse.cs:76:9:76:9 | access to local variable i | -| DefUse.cs:59:13:59:13 | i | DefUse.cs:76:9:76:11 | ...-- | DefUse.cs:77:13:77:13 | access to local variable i | -| DefUse.cs:67:19:67:20 | tc | DefUse.cs:67:19:67:27 | TestClass tc = ... | DefUse.cs:68:9:68:10 | access to local variable tc | -| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:79:13:79:18 | Int32 x1 = ... | DefUse.cs:80:30:80:31 | access to local variable x1 | -| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:30:80:31 | access to local variable x1 | DefUse.cs:80:30:80:31 | access to local variable x1 | -| DefUse.cs:79:13:79:14 | x1 | DefUse.cs:80:30:80:31 | access to local variable x1 | DefUse.cs:81:13:81:14 | access to local variable x1 | -| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:83:13:83:18 | Int32 x2 = ... | DefUse.cs:85:15:85:16 | access to local variable x2 | -| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:85:15:85:16 | access to local variable x2 | DefUse.cs:87:13:87:14 | access to local variable x2 | -| DefUse.cs:83:13:83:14 | x2 | DefUse.cs:86:15:86:16 | access to local variable x2 | DefUse.cs:87:13:87:14 | access to local variable x2 | -| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:89:13:89:18 | Int32 x3 = ... | DefUse.cs:92:15:92:16 | access to local variable x3 | -| DefUse.cs:89:13:89:14 | x3 | DefUse.cs:92:15:92:16 | access to local variable x3 | DefUse.cs:94:13:94:14 | access to local variable x3 | -| DefUse.cs:90:13:90:14 | x4 | DefUse.cs:93:15:93:16 | access to local variable x4 | DefUse.cs:95:13:95:14 | access to local variable x4 | -| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:97:13:97:18 | Int32 x5 = ... | DefUse.cs:98:16:98:17 | access to local variable x5 | -| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:101:13:101:23 | ... = ... | DefUse.cs:98:16:98:17 | access to local variable x5 | -| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:104:9:104:15 | ... = ... | DefUse.cs:105:13:105:14 | access to local variable x5 | -| DefUse.cs:118:45:118:45 | i | DefUse.cs:118:45:118:45 | i | DefUse.cs:118:65:118:65 | access to parameter i | -| DefUse.cs:120:17:120:21 | Field | DefUse.cs:53:9:53:17 | ... = ... | DefUse.cs:54:13:54:17 | access to field Field | -| DefUse.cs:122:16:122:21 | Field2 | DefUse.cs:63:9:63:18 | ... = ... | DefUse.cs:64:13:64:18 | access to field Field2 | -| DefUse.cs:124:16:124:21 | Field3 | DefUse.cs:66:9:66:18 | ... = ... | DefUse.cs:69:13:69:18 | access to field Field3 | -| DefUse.cs:126:16:126:19 | Prop | DefUse.cs:56:9:56:16 | ... = ... | DefUse.cs:57:13:57:16 | access to property Prop | -| DefUse.cs:128:19:128:19 | i | DefUse.cs:128:19:128:19 | i | DefUse.cs:129:19:129:19 | access to parameter i | -| DefUse.cs:134:22:134:22 | d | DefUse.cs:134:22:134:22 | d | DefUse.cs:135:14:135:14 | access to parameter d | -| DefUse.cs:142:68:142:69 | ie | DefUse.cs:142:68:142:69 | ie | DefUse.cs:144:27:144:28 | access to parameter ie | -| DefUse.cs:144:22:144:22 | x | DefUse.cs:144:22:144:22 | String x | DefUse.cs:146:17:146:17 | access to local variable x | -| DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:155:9:155:18 | ... = ... | DefUse.cs:156:13:156:18 | access to field Field4 | -| DefUse.cs:166:9:166:14 | Field5 | DefUse.cs:184:9:184:18 | ... = ... | DefUse.cs:185:13:185:18 | access to field Field5 | -| DefUse.cs:166:9:166:14 | Field5 | DefUse.cs:188:13:188:22 | ... = ... | DefUse.cs:189:17:189:22 | access to field Field5 | -| DefUse.cs:167:23:167:23 | i | DefUse.cs:167:23:167:23 | i | DefUse.cs:169:13:169:13 | access to parameter i | -| DefUse.cs:167:23:167:23 | i | DefUse.cs:170:9:170:13 | ... = ... | DefUse.cs:182:13:182:13 | access to parameter i | -| DefUse.cs:167:23:167:23 | i | DefUse.cs:173:13:173:17 | ... = ... | DefUse.cs:174:17:174:17 | access to parameter i | -| DefUse.cs:171:23:171:23 | a | DefUse.cs:171:23:180:9 | Action a = ... | DefUse.cs:181:9:181:9 | access to local variable a | -| DefUse.cs:171:23:171:23 | a | DefUse.cs:186:9:190:9 | ... = ... | DefUse.cs:191:9:191:9 | access to local variable a | -| Example.cs:4:9:4:13 | Field | Example.cs:8:9:8:22 | ... = ... | Example.cs:9:13:9:22 | access to field Field | -| Example.cs:4:9:4:13 | Field | Example.cs:11:13:11:30 | ... = ... | Example.cs:14:13:14:22 | access to field Field | -| Example.cs:6:23:6:23 | i | Example.cs:6:23:6:23 | i | Example.cs:8:22:8:22 | access to parameter i | -| Example.cs:18:16:18:16 | p | Example.cs:18:16:18:16 | p | Example.cs:22:17:22:17 | access to parameter p | -| Example.cs:18:16:18:16 | p | Example.cs:18:16:18:16 | p | Example.cs:25:13:25:13 | access to parameter p | -| Example.cs:18:16:18:16 | p | Example.cs:23:13:23:17 | ... = ... | Example.cs:25:13:25:13 | access to parameter p | -| Example.cs:18:24:18:24 | b | Example.cs:18:24:18:24 | b | Example.cs:20:13:20:13 | access to parameter b | -| Fields.cs:5:18:5:19 | xs | Fields.cs:24:9:24:23 | ... = ... | Fields.cs:25:13:25:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:42:9:42:23 | ... = ... | Fields.cs:44:13:44:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:45:9:45:25 | ... = ... | Fields.cs:46:13:46:16 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:80:9:80:25 | ... = ... | Fields.cs:82:19:82:22 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:83:9:83:25 | ... = ... | Fields.cs:85:19:85:22 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:85:9:85:22 | ... = ... | Fields.cs:86:9:86:15 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:87:9:87:22 | ... = ... | Fields.cs:89:9:89:15 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:88:9:88:25 | ... = ... | Fields.cs:90:19:90:22 | access to field xs | -| Fields.cs:18:15:18:15 | x | Fields.cs:20:9:20:14 | ... = ... | Fields.cs:21:13:21:13 | access to local variable x | -| Fields.cs:30:13:30:13 | f | Fields.cs:30:13:30:28 | Fields f = ... | Fields.cs:31:19:31:19 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:49:13:49:28 | ... = ... | Fields.cs:50:13:50:13 | access to local variable f | -| Fields.cs:32:15:32:15 | z | Fields.cs:47:9:47:14 | ... = ... | Fields.cs:48:13:48:13 | access to local variable z | -| Fields.cs:77:13:77:13 | f | Fields.cs:77:13:77:45 | Fields f = ... | Fields.cs:80:9:80:9 | access to local variable f | -| Fields.cs:78:23:78:23 | a | Fields.cs:78:23:78:54 | Action a = ... | Fields.cs:81:9:81:9 | access to local variable a | -| Fields.cs:79:23:79:23 | b | Fields.cs:79:23:79:35 | Action b = ... | Fields.cs:84:9:84:9 | access to local variable b | -| Fields.cs:93:19:93:23 | Field | Fields.cs:97:9:97:30 | ... = ... | Fields.cs:98:20:98:26 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:102:9:102:28 | ... = ... | Fields.cs:104:16:104:25 | access to field Field | -| Fields.cs:95:19:95:19 | f | Fields.cs:95:19:95:19 | f | Fields.cs:97:9:97:9 | access to parameter f | -| Fields.cs:107:33:107:33 | f | Fields.cs:107:33:107:33 | f | Fields.cs:107:38:107:38 | access to parameter f | -| OutRef.cs:5:9:5:13 | Field | OutRef.cs:13:28:13:32 | access to field Field | OutRef.cs:15:13:15:17 | access to field Field | -| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:21:16:25 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field | -| OutRef.cs:5:9:5:13 | Field | OutRef.cs:16:32:16:36 | access to field Field | OutRef.cs:17:13:17:17 | access to field Field | -| OutRef.cs:5:9:5:13 | Field | OutRef.cs:19:21:19:25 | access to field Field | OutRef.cs:20:13:20:17 | access to field Field | -| OutRef.cs:5:9:5:13 | Field | OutRef.cs:19:32:19:38 | access to field Field | OutRef.cs:21:13:21:19 | access to field Field | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:9:13:9:17 | Int32 j = ... | OutRef.cs:10:32:10:32 | access to local variable j | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:10:32:10:32 | access to local variable j | OutRef.cs:12:13:12:13 | access to local variable j | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:22:22:22:22 | access to local variable j | OutRef.cs:23:13:23:13 | access to local variable j | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | access to local variable j | OutRef.cs:25:13:25:13 | access to local variable j | -| OutRef.cs:10:25:10:25 | i | OutRef.cs:10:25:10:25 | Int32 i | OutRef.cs:11:13:11:13 | access to local variable i | -| OutRef.cs:10:25:10:25 | i | OutRef.cs:13:21:13:21 | access to local variable i | OutRef.cs:14:13:14:13 | access to local variable i | -| OutRef.cs:18:13:18:13 | t | OutRef.cs:18:13:18:28 | OutRef t = ... | OutRef.cs:19:32:19:32 | access to local variable t | -| OutRef.cs:28:37:28:37 | j | OutRef.cs:28:37:28:37 | j | OutRef.cs:30:13:30:13 | access to parameter j | -| OutRef.cs:34:38:34:38 | j | OutRef.cs:34:38:34:38 | j | OutRef.cs:36:13:36:13 | access to parameter j | -| OutRef.cs:39:24:39:24 | b | OutRef.cs:39:24:39:24 | b | OutRef.cs:41:13:41:13 | access to parameter b | -| Patterns.cs:7:16:7:16 | o | Patterns.cs:7:16:7:23 | Object o = ... | Patterns.cs:8:13:8:13 | access to local variable o | -| Patterns.cs:8:22:8:23 | i1 | Patterns.cs:8:18:8:23 | Int32 i1 | Patterns.cs:10:38:10:39 | access to local variable i1 | -| Patterns.cs:12:30:12:31 | s1 | Patterns.cs:12:23:12:31 | String s1 | Patterns.cs:14:41:14:42 | access to local variable s1 | -| Patterns.cs:24:22:24:23 | i2 | Patterns.cs:24:18:24:23 | Int32 i2 | Patterns.cs:24:30:24:31 | access to local variable i2 | -| Patterns.cs:27:22:27:23 | i3 | Patterns.cs:27:18:27:23 | Int32 i3 | Patterns.cs:28:42:28:43 | access to local variable i3 | -| Patterns.cs:30:25:30:26 | s2 | Patterns.cs:30:18:30:26 | String s2 | Patterns.cs:31:45:31:46 | access to local variable s2 | -| Properties.cs:5:18:5:19 | xs | Properties.cs:24:9:24:23 | ... = ... | Properties.cs:25:13:25:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:42:9:42:23 | ... = ... | Properties.cs:44:13:44:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:45:9:45:25 | ... = ... | Properties.cs:46:13:46:16 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:76:9:76:25 | ... = ... | Properties.cs:78:19:78:22 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:79:9:79:25 | ... = ... | Properties.cs:81:19:81:22 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:81:9:81:22 | ... = ... | Properties.cs:82:9:82:15 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:83:9:83:22 | ... = ... | Properties.cs:85:9:85:15 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:84:9:84:25 | ... = ... | Properties.cs:86:19:86:22 | access to property xs | -| Properties.cs:18:15:18:15 | x | Properties.cs:20:9:20:14 | ... = ... | Properties.cs:21:13:21:13 | access to local variable x | -| Properties.cs:30:13:30:13 | f | Properties.cs:30:13:30:32 | Properties f = ... | Properties.cs:31:19:31:19 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:49:13:49:32 | ... = ... | Properties.cs:50:13:50:13 | access to local variable f | -| Properties.cs:32:15:32:15 | z | Properties.cs:47:9:47:14 | ... = ... | Properties.cs:48:13:48:13 | access to local variable z | -| Properties.cs:61:23:61:23 | i | Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:16 | access to parameter i | -| Properties.cs:61:23:61:23 | i | Properties.cs:63:16:63:18 | ...-- | Properties.cs:63:16:63:16 | access to parameter i | -| Properties.cs:73:13:73:13 | f | Properties.cs:73:13:73:32 | Properties f = ... | Properties.cs:76:9:76:9 | access to local variable f | -| Properties.cs:74:23:74:23 | a | Properties.cs:74:23:74:54 | Action a = ... | Properties.cs:77:9:77:9 | access to local variable a | -| Properties.cs:75:23:75:23 | b | Properties.cs:75:23:75:35 | Action b = ... | Properties.cs:80:9:80:9 | access to local variable b | -| Properties.cs:106:37:106:37 | p | Properties.cs:106:37:106:37 | p | Properties.cs:106:42:106:42 | access to parameter p | -| Test.cs:3:9:3:13 | field | Test.cs:7:9:7:17 | ... = ... | Test.cs:33:13:33:17 | access to field field | -| Test.cs:3:9:3:13 | field | Test.cs:21:13:21:22 | ... = ... | Test.cs:33:13:33:17 | access to field field | -| Test.cs:3:9:3:13 | field | Test.cs:57:9:57:17 | ... = ... | Test.cs:58:13:58:17 | access to field field | -| Test.cs:5:15:5:20 | param1 | Test.cs:5:15:5:20 | param1 | Test.cs:11:13:11:18 | access to parameter param1 | -| Test.cs:5:15:5:20 | param1 | Test.cs:27:17:27:24 | ...++ | Test.cs:27:17:27:22 | access to parameter param1 | -| Test.cs:5:15:5:20 | param1 | Test.cs:27:17:27:24 | ...++ | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:5:15:5:20 | param1 | Test.cs:41:13:41:23 | ... = ... | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:5:67:5:72 | param2 | Test.cs:5:67:5:72 | param2 | Test.cs:39:27:39:32 | access to parameter param2 | -| Test.cs:8:13:8:13 | x | Test.cs:8:13:8:17 | Int32 x = ... | Test.cs:13:13:13:13 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:8:13:8:17 | Int32 x = ... | Test.cs:25:16:25:16 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:13:13:13:15 | ...++ | Test.cs:14:19:14:19 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:14:17:14:19 | ++... | Test.cs:25:16:25:16 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:36:13:36:18 | ... = ... | Test.cs:36:13:36:13 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:36:13:36:18 | ... = ... | Test.cs:43:16:43:16 | access to local variable x | -| Test.cs:9:13:9:13 | y | Test.cs:14:13:14:19 | ... = ... | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:9:13:9:13 | y | Test.cs:19:13:19:17 | ... = ... | Test.cs:20:13:20:13 | access to local variable y | -| Test.cs:9:13:9:13 | y | Test.cs:20:13:20:18 | ... = ... | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:9:13:9:13 | y | Test.cs:31:13:31:18 | ... = ... | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:10:13:10:13 | z | Test.cs:15:13:15:17 | ... = ... | Test.cs:24:13:24:13 | access to local variable z | -| Test.cs:10:13:10:13 | z | Test.cs:22:13:22:17 | ... = ... | Test.cs:24:13:24:13 | access to local variable z | -| Test.cs:34:18:34:18 | i | Test.cs:34:18:34:22 | Int32 i = ... | Test.cs:34:25:34:25 | access to local variable i | -| Test.cs:34:18:34:18 | i | Test.cs:34:33:34:35 | ...++ | Test.cs:34:25:34:25 | access to local variable i | -| Test.cs:39:22:39:22 | w | Test.cs:39:22:39:22 | Int32 w | Test.cs:41:23:41:23 | access to local variable w | -| Test.cs:46:16:46:18 | in | Test.cs:46:16:46:18 | in | Test.cs:48:13:48:15 | access to parameter in | -| Test.cs:68:45:68:45 | e | Test.cs:68:45:68:45 | DivideByZeroException e | Test.cs:70:17:70:17 | access to local variable e | -| Tuples.cs:5:9:5:13 | Field | Tuples.cs:20:9:20:34 | ... = ... | Tuples.cs:22:13:22:17 | access to field Field | -| Tuples.cs:5:9:5:13 | Field | Tuples.cs:26:9:26:33 | ... = ... | Tuples.cs:27:13:27:17 | access to field Field | -| Tuples.cs:5:9:5:13 | Field | Tuples.cs:26:9:26:33 | ... = ... | Tuples.cs:28:13:28:19 | access to field Field | -| Tuples.cs:6:9:6:16 | Property | Tuples.cs:20:9:20:34 | ... = ... | Tuples.cs:21:13:21:20 | access to property Property | -| Tuples.cs:10:14:10:14 | x | Tuples.cs:10:9:10:54 | ... = ... | Tuples.cs:11:13:11:13 | access to local variable x | -| Tuples.cs:10:14:10:14 | x | Tuples.cs:14:9:14:32 | ... = ... | Tuples.cs:15:13:15:13 | access to local variable x | -| Tuples.cs:10:14:10:14 | x | Tuples.cs:23:9:23:37 | ... = ... | Tuples.cs:24:13:24:13 | access to local variable x | -| Tuples.cs:10:23:10:23 | b | Tuples.cs:10:9:10:54 | ... = ... | Tuples.cs:12:13:12:13 | access to local variable b | -| Tuples.cs:10:23:10:23 | b | Tuples.cs:14:9:14:32 | ... = ... | Tuples.cs:16:13:16:13 | access to local variable b | -| Tuples.cs:10:33:10:33 | s | Tuples.cs:10:9:10:54 | ... = ... | Tuples.cs:13:13:13:13 | access to local variable s | -| Tuples.cs:10:33:10:33 | s | Tuples.cs:14:9:14:32 | ... = ... | Tuples.cs:17:13:17:13 | access to local variable s | -| Tuples.cs:18:40:18:44 | tuple | Tuples.cs:18:40:18:57 | (Int32,(Boolean,String)) tuple = ... | Tuples.cs:19:13:19:17 | access to local variable tuple | -| Tuples.cs:25:13:25:13 | t | Tuples.cs:25:13:25:28 | Tuples t = ... | Tuples.cs:26:17:26:17 | access to local variable t | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.ql b/csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.ql deleted file mode 100644 index 4953c57f3406..000000000000 --- a/csharp/ql/test/library-tests/dataflow/ssa/DefAdjacentUncertainRead.ql +++ /dev/null @@ -1,5 +0,0 @@ -import csharp - -from AssignableDefinition def, AssignableRead read -where read = def.getAFirstUncertainRead() -select def.getTarget(), def, read diff --git a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.expected deleted file mode 100644 index d6a74cb33d2b..000000000000 --- a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.expected +++ /dev/null @@ -1,145 +0,0 @@ -WARNING: Predicate getANextUncertainRead has been deprecated and may be removed in future (ReadAdjacentUncertainRead.ql:4,21-42) -| Capture.cs:6:16:6:16 | i | Capture.cs:8:17:8:17 | access to parameter i | Capture.cs:33:13:33:13 | access to parameter i | -| Capture.cs:6:16:6:16 | i | Capture.cs:33:13:33:13 | access to parameter i | Capture.cs:39:13:39:13 | access to parameter i | -| Capture.cs:8:13:8:13 | x | Capture.cs:16:17:16:17 | access to local variable x | Capture.cs:17:21:17:21 | access to local variable x | -| Capture.cs:8:13:8:13 | x | Capture.cs:34:13:34:13 | access to local variable x | Capture.cs:40:13:40:13 | access to local variable x | -| Capture.cs:8:13:8:13 | x | Capture.cs:44:11:44:11 | access to local variable x | Capture.cs:45:13:45:13 | access to local variable x | -| Capture.cs:8:13:8:13 | x | Capture.cs:45:13:45:13 | access to local variable x | Capture.cs:47:13:47:13 | access to local variable x | -| Capture.cs:10:16:10:16 | a | Capture.cs:38:9:38:9 | access to local variable a | Capture.cs:46:12:46:12 | access to local variable a | -| Capture.cs:65:45:65:51 | strings | Capture.cs:68:18:68:24 | access to parameter strings | Capture.cs:70:9:70:15 | access to parameter strings | -| Consistency.cs:5:9:5:13 | Field | Consistency.cs:26:13:26:19 | access to field Field | Consistency.cs:27:13:27:19 | access to field Field | -| Consistency.cs:25:29:25:29 | c | Consistency.cs:26:13:26:13 | access to local variable c | Consistency.cs:27:13:27:13 | access to local variable c | -| Consistency.cs:44:11:44:11 | s | Consistency.cs:45:9:45:9 | access to local variable s | Consistency.cs:46:13:46:13 | access to local variable s | -| Consistency.cs:51:20:51:20 | a | Consistency.cs:53:28:53:28 | access to parameter a | Consistency.cs:55:36:55:36 | access to parameter a | -| Consistency.cs:51:20:51:20 | a | Consistency.cs:55:36:55:36 | access to parameter a | Consistency.cs:56:36:56:36 | access to parameter a | -| DefUse.cs:3:26:3:26 | w | DefUse.cs:9:13:9:13 | access to parameter w | DefUse.cs:24:13:24:13 | access to parameter w | -| DefUse.cs:3:26:3:26 | w | DefUse.cs:20:17:20:17 | access to parameter w | DefUse.cs:24:13:24:13 | access to parameter w | -| DefUse.cs:3:26:3:26 | w | DefUse.cs:35:13:35:13 | access to parameter w | DefUse.cs:53:17:53:17 | access to parameter w | -| DefUse.cs:5:13:5:13 | x | DefUse.cs:11:13:11:13 | access to local variable x | DefUse.cs:26:13:26:13 | access to local variable x | -| DefUse.cs:5:13:5:13 | x | DefUse.cs:26:13:26:13 | access to local variable x | DefUse.cs:37:13:37:13 | access to local variable x | -| DefUse.cs:5:13:5:13 | x | DefUse.cs:37:13:37:13 | access to local variable x | DefUse.cs:44:17:44:17 | access to local variable x | -| DefUse.cs:5:13:5:13 | x | DefUse.cs:44:17:44:17 | access to local variable x | DefUse.cs:56:16:56:16 | access to local variable x | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:14:17:14:17 | access to local variable y | DefUse.cs:23:13:23:13 | access to local variable y | -| DefUse.cs:6:14:6:14 | y | DefUse.cs:34:13:34:13 | access to local variable y | DefUse.cs:42:13:42:13 | access to local variable y | -| DefUse.cs:44:13:44:13 | z | DefUse.cs:48:13:48:13 | access to local variable z | DefUse.cs:50:23:50:23 | access to local variable z | -| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:16:98:17 | access to local variable x5 | DefUse.cs:100:17:100:18 | access to local variable x5 | -| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:98:16:98:17 | access to local variable x5 | DefUse.cs:104:9:104:10 | access to local variable x5 | -| DefUse.cs:97:13:97:14 | x5 | DefUse.cs:100:17:100:18 | access to local variable x5 | DefUse.cs:101:18:101:19 | access to local variable x5 | -| DefUse.cs:122:16:122:21 | Field2 | DefUse.cs:64:13:64:18 | access to field Field2 | DefUse.cs:80:37:80:42 | access to field Field2 | -| DefUse.cs:122:16:122:21 | Field2 | DefUse.cs:80:37:80:42 | access to field Field2 | DefUse.cs:80:37:80:42 | access to field Field2 | -| DefUse.cs:144:22:144:22 | x | DefUse.cs:146:17:146:17 | access to local variable x | DefUse.cs:147:17:147:17 | access to local variable x | -| DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:156:13:156:18 | access to field Field4 | DefUse.cs:157:13:157:18 | access to field Field4 | -| DefUse.cs:152:9:152:14 | Field4 | DefUse.cs:162:13:162:18 | access to field Field4 | DefUse.cs:163:13:163:18 | access to field Field4 | -| DefUse.cs:166:9:166:14 | Field5 | DefUse.cs:185:13:185:18 | access to field Field5 | DefUse.cs:192:13:192:18 | access to field Field5 | -| DefUse.cs:167:23:167:23 | i | DefUse.cs:177:21:177:21 | access to parameter i | DefUse.cs:178:21:178:21 | access to parameter i | -| Example.cs:4:9:4:13 | Field | Example.cs:9:13:9:22 | access to field Field | Example.cs:14:13:14:22 | access to field Field | -| Example.cs:4:9:4:13 | Field | Example.cs:14:13:14:22 | access to field Field | Example.cs:15:13:15:22 | access to field Field | -| Example.cs:6:23:6:23 | i | Example.cs:8:22:8:22 | access to parameter i | Example.cs:10:13:10:13 | access to parameter i | -| Example.cs:6:23:6:23 | i | Example.cs:10:13:10:13 | access to parameter i | Example.cs:11:26:11:26 | access to parameter i | -| Example.cs:6:23:6:23 | i | Example.cs:10:13:10:13 | access to parameter i | Example.cs:12:18:12:18 | access to parameter i | -| Fields.cs:5:18:5:19 | xs | Fields.cs:18:19:18:20 | access to field xs | Fields.cs:20:13:20:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:20:13:20:14 | access to field xs | Fields.cs:23:13:23:19 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:31:19:31:22 | access to field xs | Fields.cs:35:13:35:16 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:32:19:32:20 | access to field xs | Fields.cs:36:13:36:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:35:13:35:16 | access to field xs | Fields.cs:39:13:39:16 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:36:13:36:14 | access to field xs | Fields.cs:40:13:40:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:39:13:39:16 | access to field xs | Fields.cs:43:13:43:16 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:44:13:44:14 | access to field xs | Fields.cs:47:13:47:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:46:13:46:16 | access to field xs | Fields.cs:50:13:50:16 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:47:13:47:14 | access to field xs | Fields.cs:53:13:53:14 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:50:13:50:16 | access to field xs | Fields.cs:52:13:52:16 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:85:19:85:22 | access to field xs | Fields.cs:87:19:87:22 | access to field xs | -| Fields.cs:5:18:5:19 | xs | Fields.cs:116:21:116:39 | access to field xs | Fields.cs:117:17:117:35 | access to field xs | -| Fields.cs:6:25:6:28 | stat | Fields.cs:33:19:33:22 | access to field stat | Fields.cs:37:13:37:16 | access to field stat | -| Fields.cs:6:25:6:28 | stat | Fields.cs:37:13:37:16 | access to field stat | Fields.cs:41:13:41:16 | access to field stat | -| Fields.cs:6:25:6:28 | stat | Fields.cs:41:13:41:16 | access to field stat | Fields.cs:54:13:54:16 | access to field stat | -| Fields.cs:30:13:30:13 | f | Fields.cs:31:19:31:19 | access to local variable f | Fields.cs:35:13:35:13 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:35:13:35:13 | access to local variable f | Fields.cs:38:9:38:9 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:38:9:38:9 | access to local variable f | Fields.cs:39:13:39:13 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:39:13:39:13 | access to local variable f | Fields.cs:43:13:43:13 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:43:13:43:13 | access to local variable f | Fields.cs:45:9:45:9 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:45:9:45:9 | access to local variable f | Fields.cs:46:13:46:13 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:46:13:46:13 | access to local variable f | Fields.cs:50:13:50:13 | access to local variable f | -| Fields.cs:30:13:30:13 | f | Fields.cs:50:13:50:13 | access to local variable f | Fields.cs:52:13:52:13 | access to local variable f | -| Fields.cs:57:9:57:17 | LoopField | Fields.cs:65:24:65:32 | access to field LoopField | Fields.cs:65:24:65:32 | access to field LoopField | -| Fields.cs:77:13:77:13 | f | Fields.cs:80:9:80:9 | access to local variable f | Fields.cs:82:19:82:19 | access to local variable f | -| Fields.cs:77:13:77:13 | f | Fields.cs:82:19:82:19 | access to local variable f | Fields.cs:83:9:83:9 | access to local variable f | -| Fields.cs:77:13:77:13 | f | Fields.cs:83:9:83:9 | access to local variable f | Fields.cs:85:19:85:19 | access to local variable f | -| Fields.cs:77:13:77:13 | f | Fields.cs:85:19:85:19 | access to local variable f | Fields.cs:87:19:87:19 | access to local variable f | -| Fields.cs:77:13:77:13 | f | Fields.cs:87:19:87:19 | access to local variable f | Fields.cs:88:9:88:9 | access to local variable f | -| Fields.cs:77:13:77:13 | f | Fields.cs:88:9:88:9 | access to local variable f | Fields.cs:90:19:90:19 | access to local variable f | -| Fields.cs:93:19:93:23 | Field | Fields.cs:98:20:98:26 | access to field Field | Fields.cs:99:16:99:22 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:98:20:98:32 | access to field Field | Fields.cs:99:16:99:28 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:99:16:99:22 | access to field Field | Fields.cs:100:16:100:22 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:99:16:99:28 | access to field Field | Fields.cs:100:16:100:28 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:99:16:99:34 | access to field Field | Fields.cs:100:16:100:34 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:100:16:100:22 | access to field Field | Fields.cs:101:16:101:22 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:100:16:100:28 | access to field Field | Fields.cs:101:16:101:28 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:100:16:100:34 | access to field Field | Fields.cs:101:16:101:34 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:100:16:100:40 | access to field Field | Fields.cs:101:16:101:40 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:101:16:101:22 | access to field Field | Fields.cs:102:22:102:28 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:115:20:115:29 | access to field Field | Fields.cs:116:21:116:30 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:115:20:115:35 | access to field Field | Fields.cs:116:21:116:36 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:116:21:116:30 | access to field Field | Fields.cs:117:17:117:26 | access to field Field | -| Fields.cs:93:19:93:23 | Field | Fields.cs:116:21:116:36 | access to field Field | Fields.cs:117:17:117:32 | access to field Field | -| Fields.cs:95:19:95:19 | f | Fields.cs:97:9:97:9 | access to parameter f | Fields.cs:98:20:98:20 | access to parameter f | -| Fields.cs:95:19:95:19 | f | Fields.cs:98:20:98:20 | access to parameter f | Fields.cs:99:16:99:16 | access to parameter f | -| Fields.cs:95:19:95:19 | f | Fields.cs:99:16:99:16 | access to parameter f | Fields.cs:100:16:100:16 | access to parameter f | -| Fields.cs:95:19:95:19 | f | Fields.cs:100:16:100:16 | access to parameter f | Fields.cs:101:16:101:16 | access to parameter f | -| Fields.cs:95:19:95:19 | f | Fields.cs:101:16:101:16 | access to parameter f | Fields.cs:102:22:102:22 | access to parameter f | -| OutRef.cs:5:9:5:13 | Field | OutRef.cs:15:13:15:17 | access to field Field | OutRef.cs:16:32:16:36 | access to field Field | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:12:13:12:13 | access to local variable j | OutRef.cs:22:29:22:29 | access to local variable j | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:23:13:23:13 | access to local variable j | OutRef.cs:24:29:24:29 | access to local variable j | -| OutRef.cs:9:13:9:13 | j | OutRef.cs:24:29:24:29 | access to local variable j | OutRef.cs:25:13:25:13 | access to local variable j | -| OutRef.cs:18:13:18:13 | t | OutRef.cs:19:32:19:32 | access to local variable t | OutRef.cs:21:13:21:13 | access to local variable t | -| Patterns.cs:7:16:7:16 | o | Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:12:18:12:18 | access to local variable o | -| Patterns.cs:7:16:7:16 | o | Patterns.cs:8:13:8:13 | access to local variable o | Patterns.cs:20:17:20:17 | access to local variable o | -| Patterns.cs:7:16:7:16 | o | Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:16:18:16:18 | access to local variable o | -| Patterns.cs:7:16:7:16 | o | Patterns.cs:12:18:12:18 | access to local variable o | Patterns.cs:20:17:20:17 | access to local variable o | -| Patterns.cs:7:16:7:16 | o | Patterns.cs:16:18:16:18 | access to local variable o | Patterns.cs:20:17:20:17 | access to local variable o | -| Patterns.cs:24:22:24:23 | i2 | Patterns.cs:24:30:24:31 | access to local variable i2 | Patterns.cs:25:47:25:48 | access to local variable i2 | -| Properties.cs:5:18:5:19 | xs | Properties.cs:18:19:18:20 | access to property xs | Properties.cs:20:13:20:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:20:13:20:14 | access to property xs | Properties.cs:23:13:23:19 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:31:19:31:22 | access to property xs | Properties.cs:35:13:35:16 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:32:19:32:20 | access to property xs | Properties.cs:36:13:36:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:35:13:35:16 | access to property xs | Properties.cs:39:13:39:16 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:36:13:36:14 | access to property xs | Properties.cs:40:13:40:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:39:13:39:16 | access to property xs | Properties.cs:43:13:43:16 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:44:13:44:14 | access to property xs | Properties.cs:47:13:47:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:46:13:46:16 | access to property xs | Properties.cs:50:13:50:16 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:47:13:47:14 | access to property xs | Properties.cs:53:13:53:14 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:50:13:50:16 | access to property xs | Properties.cs:52:13:52:16 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:81:19:81:22 | access to property xs | Properties.cs:83:19:83:22 | access to property xs | -| Properties.cs:5:18:5:19 | xs | Properties.cs:115:21:115:39 | access to property xs | Properties.cs:116:17:116:35 | access to property xs | -| Properties.cs:6:25:6:28 | stat | Properties.cs:33:19:33:22 | access to property stat | Properties.cs:37:13:37:16 | access to property stat | -| Properties.cs:6:25:6:28 | stat | Properties.cs:37:13:37:16 | access to property stat | Properties.cs:41:13:41:16 | access to property stat | -| Properties.cs:6:25:6:28 | stat | Properties.cs:41:13:41:16 | access to property stat | Properties.cs:54:13:54:16 | access to property stat | -| Properties.cs:30:13:30:13 | f | Properties.cs:31:19:31:19 | access to local variable f | Properties.cs:35:13:35:13 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:35:13:35:13 | access to local variable f | Properties.cs:38:9:38:9 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:38:9:38:9 | access to local variable f | Properties.cs:39:13:39:13 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:39:13:39:13 | access to local variable f | Properties.cs:43:13:43:13 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:43:13:43:13 | access to local variable f | Properties.cs:45:9:45:9 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:45:9:45:9 | access to local variable f | Properties.cs:46:13:46:13 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:46:13:46:13 | access to local variable f | Properties.cs:50:13:50:13 | access to local variable f | -| Properties.cs:30:13:30:13 | f | Properties.cs:50:13:50:13 | access to local variable f | Properties.cs:52:13:52:13 | access to local variable f | -| Properties.cs:57:16:57:23 | LoopProp | Properties.cs:65:24:65:31 | access to property LoopProp | Properties.cs:65:24:65:31 | access to property LoopProp | -| Properties.cs:73:13:73:13 | f | Properties.cs:76:9:76:9 | access to local variable f | Properties.cs:78:19:78:19 | access to local variable f | -| Properties.cs:73:13:73:13 | f | Properties.cs:78:19:78:19 | access to local variable f | Properties.cs:79:9:79:9 | access to local variable f | -| Properties.cs:73:13:73:13 | f | Properties.cs:79:9:79:9 | access to local variable f | Properties.cs:81:19:81:19 | access to local variable f | -| Properties.cs:73:13:73:13 | f | Properties.cs:81:19:81:19 | access to local variable f | Properties.cs:83:19:83:19 | access to local variable f | -| Properties.cs:73:13:73:13 | f | Properties.cs:83:19:83:19 | access to local variable f | Properties.cs:84:9:84:9 | access to local variable f | -| Properties.cs:73:13:73:13 | f | Properties.cs:84:9:84:9 | access to local variable f | Properties.cs:86:19:86:19 | access to local variable f | -| Properties.cs:104:16:104:20 | Props | Properties.cs:114:20:114:29 | access to field Props | Properties.cs:115:21:115:30 | access to field Props | -| Properties.cs:104:16:104:20 | Props | Properties.cs:114:20:114:35 | access to field Props | Properties.cs:115:21:115:36 | access to field Props | -| Properties.cs:104:16:104:20 | Props | Properties.cs:115:21:115:30 | access to field Props | Properties.cs:116:17:116:26 | access to field Props | -| Properties.cs:104:16:104:20 | Props | Properties.cs:115:21:115:36 | access to field Props | Properties.cs:116:17:116:32 | access to field Props | -| Test.cs:5:15:5:20 | param1 | Test.cs:11:13:11:18 | access to parameter param1 | Test.cs:27:17:27:22 | access to parameter param1 | -| Test.cs:5:15:5:20 | param1 | Test.cs:11:13:11:18 | access to parameter param1 | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:8:13:8:13 | x | Test.cs:25:16:25:16 | access to local variable x | Test.cs:25:16:25:16 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:25:16:25:16 | access to local variable x | Test.cs:36:13:36:13 | access to local variable x | -| Test.cs:8:13:8:13 | x | Test.cs:25:16:25:16 | access to local variable x | Test.cs:43:16:43:16 | access to local variable x | -| Test.cs:9:13:9:13 | y | Test.cs:25:20:25:20 | access to local variable y | Test.cs:31:13:31:13 | access to local variable y | -| Test.cs:9:13:9:13 | y | Test.cs:25:20:25:20 | access to local variable y | Test.cs:43:20:43:20 | access to local variable y | -| Test.cs:34:18:34:18 | i | Test.cs:34:25:34:25 | access to local variable i | Test.cs:36:18:36:18 | access to local variable i | -| Test.cs:34:18:34:18 | i | Test.cs:36:18:36:18 | access to local variable i | Test.cs:34:33:34:33 | access to local variable i | -| Tuples.cs:25:13:25:13 | t | Tuples.cs:26:17:26:17 | access to local variable t | Tuples.cs:28:13:28:13 | access to local variable t | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.ql b/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.ql deleted file mode 100644 index 2e3040dbf57e..000000000000 --- a/csharp/ql/test/library-tests/dataflow/ssa/ReadAdjacentUncertainRead.ql +++ /dev/null @@ -1,5 +0,0 @@ -import csharp - -from AssignableRead read1, AssignableRead read2 -where read2 = read1.getANextUncertainRead() -select read1.getTarget(), read1, read2 diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.expected b/csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.expected deleted file mode 100644 index 0a37dac36d27..000000000000 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.expected +++ /dev/null @@ -1,334 +0,0 @@ -WARNING: Predicate getAFirstUncertainRead has been deprecated and may be removed in future (SsaAdjacentUncertainRead.ql:4,18-40) -| Capture.cs:6:16:6:16 | SSA param(i) | Capture.cs:8:17:8:17 | access to parameter i | -| Capture.cs:8:13:8:17 | SSA def(x) | Capture.cs:34:13:34:13 | access to local variable x | -| Capture.cs:10:16:27:9 | SSA def(a) | Capture.cs:38:9:38:9 | access to local variable a | -| Capture.cs:10:20:27:9 | SSA capture def(i) | Capture.cs:12:17:12:17 | access to parameter i | -| Capture.cs:13:13:13:17 | SSA def(i) | Capture.cs:14:17:14:17 | access to parameter i | -| Capture.cs:15:13:15:17 | SSA def(x) | Capture.cs:16:17:16:17 | access to local variable x | -| Capture.cs:17:17:17:21 | SSA def(y) | Capture.cs:26:17:26:17 | access to local variable y | -| Capture.cs:19:20:23:13 | SSA def(b) | Capture.cs:25:13:25:13 | access to local variable b | -| Capture.cs:19:24:23:13 | SSA capture def(x) | Capture.cs:21:21:21:21 | access to local variable x | -| Capture.cs:19:24:23:13 | SSA capture def(y) | Capture.cs:22:21:22:21 | access to local variable y | -| Capture.cs:29:13:29:17 | SSA def(z) | Capture.cs:35:13:35:13 | access to local variable z | -| Capture.cs:30:16:30:35 | SSA def(c) | Capture.cs:32:9:32:9 | access to local variable c | -| Capture.cs:32:9:32:11 | SSA call def(z) | Capture.cs:35:13:35:13 | access to local variable z | -| Capture.cs:37:9:37:13 | SSA def(z) | Capture.cs:41:13:41:13 | access to local variable z | -| Capture.cs:38:9:38:11 | SSA call def(i) | Capture.cs:39:13:39:13 | access to parameter i | -| Capture.cs:38:9:38:11 | SSA call def(x) | Capture.cs:40:13:40:13 | access to local variable x | -| Capture.cs:43:9:43:13 | SSA def(x) | Capture.cs:44:11:44:11 | access to local variable x | -| Capture.cs:44:9:44:12 | SSA call def(x) | Capture.cs:45:13:45:13 | access to local variable x | -| Capture.cs:50:20:50:20 | SSA param(a) | Capture.cs:54:9:54:9 | access to parameter a | -| Capture.cs:52:16:52:43 | SSA def(b) | Capture.cs:53:9:53:9 | access to local variable b | -| Capture.cs:53:9:53:11 | SSA call def(a) | Capture.cs:54:9:54:9 | access to parameter a | -| Capture.cs:57:57:57:63 | SSA param(strings) | Capture.cs:61:9:61:15 | access to parameter strings | -| Capture.cs:59:13:59:17 | SSA def(i) | Capture.cs:62:13:62:13 | access to local variable i | -| Capture.cs:60:27:60:38 | SSA def(e) | Capture.cs:61:24:61:24 | access to local variable e | -| Capture.cs:60:31:60:38 | SSA capture def(i) | Capture.cs:60:36:60:36 | access to local variable i | -| Capture.cs:61:9:61:25 | SSA call def(i) | Capture.cs:62:13:62:13 | access to local variable i | -| Capture.cs:65:45:65:51 | SSA param(strings) | Capture.cs:68:18:68:24 | access to parameter strings | -| Capture.cs:68:32:68:32 | SSA param(s) | Capture.cs:68:37:68:37 | access to parameter s | -| Capture.cs:68:32:68:49 | SSA capture def(c) | Capture.cs:68:48:68:48 | access to local variable c | -| Capture.cs:69:9:69:62 | SSA capture def(c) | Capture.cs:69:48:69:48 | access to local variable c | -| Capture.cs:69:25:69:25 | SSA param(s) | Capture.cs:69:59:69:59 | access to parameter s | -| Capture.cs:73:67:73:73 | SSA param(strings) | Capture.cs:77:9:77:15 | access to parameter strings | -| Capture.cs:75:13:75:17 | SSA def(i) | Capture.cs:78:13:78:13 | access to local variable i | -| Capture.cs:76:63:76:81 | SSA def(e) | Capture.cs:77:24:77:24 | access to local variable e | -| Capture.cs:76:67:76:81 | SSA capture def(i) | Capture.cs:76:80:76:80 | access to local variable i | -| Capture.cs:77:9:77:25 | SSA call def(i) | Capture.cs:78:13:78:13 | access to local variable i | -| Capture.cs:81:28:81:28 | SSA param(i) | Capture.cs:81:34:81:34 | access to parameter i | -| Capture.cs:83:65:83:71 | SSA param(strings) | Capture.cs:87:9:87:15 | access to parameter strings | -| Capture.cs:86:64:86:73 | SSA def(e) | Capture.cs:87:23:87:23 | access to local variable e | -| Capture.cs:86:68:86:73 | SSA capture def(b) | Capture.cs:86:73:86:73 | access to local variable b | -| Capture.cs:92:18:92:18 | SSA param(d) | Capture.cs:92:24:92:24 | access to parameter d | -| Capture.cs:96:12:100:9 | SSA capture def(y) | Capture.cs:98:21:98:21 | access to local variable y | -| Capture.cs:98:17:98:21 | SSA def(x) | Capture.cs:99:20:99:20 | access to local variable x | -| Capture.cs:105:13:105:17 | SSA def(z) | Capture.cs:106:20:106:20 | access to local variable z | -| Capture.cs:115:9:119:9 | SSA capture def(a) | Capture.cs:117:21:117:21 | access to local variable a | -| Capture.cs:117:17:117:21 | SSA def(x) | Capture.cs:118:17:118:17 | access to local variable x | -| Capture.cs:125:13:125:17 | SSA def(b) | Capture.cs:126:17:126:17 | access to local variable b | -| Capture.cs:130:13:130:18 | SSA def(c) | Capture.cs:137:13:137:13 | access to local variable c | -| Capture.cs:133:13:133:17 | SSA def(c) | Capture.cs:134:17:134:17 | access to local variable c | -| Capture.cs:136:9:136:12 | SSA call def(c) | Capture.cs:137:13:137:13 | access to local variable c | -| Capture.cs:139:13:139:18 | SSA def(d) | Capture.cs:145:13:145:13 | access to local variable d | -| Capture.cs:144:9:144:12 | SSA call def(d) | Capture.cs:145:13:145:13 | access to local variable d | -| Capture.cs:148:9:152:9 | SSA capture def(e) | Capture.cs:150:17:150:17 | access to local variable e | -| Capture.cs:154:13:154:18 | SSA def(f) | Capture.cs:155:13:155:13 | access to local variable f | -| Capture.cs:163:9:166:9 | SSA capture def(g) | Capture.cs:165:17:165:17 | access to local variable g | -| Capture.cs:171:13:171:17 | SSA def(h) | Capture.cs:177:17:177:17 | access to local variable h | -| Capture.cs:176:13:176:16 | SSA call def(h) | Capture.cs:177:17:177:17 | access to local variable h | -| Capture.cs:183:13:186:13 | SSA capture def(i) | Capture.cs:185:21:185:21 | access to local variable i | -| Capture.cs:198:28:198:44 | SSA def(eh) | Capture.cs:199:27:199:28 | access to local variable eh | -| Capture.cs:198:33:198:44 | SSA capture def(i) | Capture.cs:198:43:198:43 | access to local variable i | -| Capture.cs:203:28:203:45 | SSA def(eh2) | Capture.cs:204:27:204:29 | access to local variable eh2 | -| Capture.cs:203:34:203:45 | SSA capture def(i) | Capture.cs:203:44:203:44 | access to local variable i | -| Capture.cs:210:24:210:59 | SSA def(p) | Capture.cs:213:17:213:17 | access to local variable p | -| Capture.cs:212:30:212:71 | SSA def(exited) | Capture.cs:213:29:213:34 | access to local variable exited | -| Capture.cs:212:39:212:71 | SSA capture def(i) | Capture.cs:212:70:212:70 | access to local variable i | -| Capture.cs:231:9:231:49 | SSA capture def(i) | Capture.cs:231:47:231:47 | access to local variable i | -| Capture.cs:232:9:232:13 | SSA def(i) | Capture.cs:237:34:237:34 | access to local variable i | -| Capture.cs:236:9:236:12 | SSA call def(i) | Capture.cs:237:34:237:34 | access to local variable i | -| Consistency.cs:7:25:7:25 | SSA param(b) | Consistency.cs:11:17:11:17 | access to parameter b | -| Consistency.cs:15:17:15:21 | SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i | -| Consistency.cs:15:17:15:21 | [finally: exception(Exception)] SSA def(i) | Consistency.cs:16:17:16:17 | access to local variable i | -| Consistency.cs:25:29:25:29 | SSA def(c) | Consistency.cs:26:13:26:13 | access to local variable c | -| Consistency.cs:25:29:25:29 | SSA qualifier def(c.Field) | Consistency.cs:26:13:26:19 | access to field Field | -| Consistency.cs:32:9:32:29 | SSA def(c) | Consistency.cs:33:9:33:9 | access to parameter c | -| Consistency.cs:39:28:39:32 | SSA def(i) | Consistency.cs:39:39:39:39 | access to local variable i | -| Consistency.cs:44:11:44:11 | SSA def(s) | Consistency.cs:45:9:45:9 | access to local variable s | -| Consistency.cs:49:30:49:30 | SSA param(a) | Consistency.cs:49:47:49:47 | access to parameter a | -| Consistency.cs:49:37:49:37 | SSA param(i) | Consistency.cs:49:49:49:49 | access to parameter i | -| Consistency.cs:51:20:51:20 | SSA param(a) | Consistency.cs:53:28:53:28 | access to parameter a | -| DefUse.cs:3:26:3:26 | SSA param(w) | DefUse.cs:9:13:9:13 | access to parameter w | -| DefUse.cs:5:13:5:17 | SSA def(x) | DefUse.cs:11:13:11:13 | access to local variable x | -| DefUse.cs:6:14:6:19 | SSA def(y) | DefUse.cs:8:13:8:13 | access to local variable y | -| DefUse.cs:13:13:13:18 | SSA def(y) | DefUse.cs:14:17:14:17 | access to local variable y | -| DefUse.cs:18:13:18:18 | SSA def(y) | DefUse.cs:23:13:23:13 | access to local variable y | -| DefUse.cs:19:13:19:18 | SSA def(w) | DefUse.cs:20:17:20:17 | access to parameter w | -| DefUse.cs:23:9:23:15 | SSA phi(w) | DefUse.cs:24:13:24:13 | access to parameter w | -| DefUse.cs:23:9:23:15 | SSA phi(y) | DefUse.cs:23:13:23:13 | access to local variable y | -| DefUse.cs:28:13:28:18 | SSA def(y) | DefUse.cs:34:13:34:13 | access to local variable y | -| DefUse.cs:29:13:29:18 | SSA def(w) | DefUse.cs:35:13:35:13 | access to parameter w | -| DefUse.cs:39:13:39:18 | SSA def(y) | DefUse.cs:42:13:42:13 | access to local variable y | -| DefUse.cs:42:9:42:15 | SSA phi(y) | DefUse.cs:42:13:42:13 | access to local variable y | -| DefUse.cs:44:13:44:17 | SSA def(z) | DefUse.cs:45:13:45:13 | access to local variable z | -| DefUse.cs:47:23:47:23 | SSA def(z) | DefUse.cs:48:13:48:13 | access to local variable z | -| DefUse.cs:50:23:50:23 | SSA def(z) | DefUse.cs:51:13:51:13 | access to local variable z | -| DefUse.cs:53:9:53:17 | SSA def(this.Field) | DefUse.cs:54:13:54:17 | access to field Field | -| DefUse.cs:56:9:56:16 | SSA def(this.Prop) | DefUse.cs:57:13:57:16 | access to property Prop | -| DefUse.cs:59:13:59:17 | SSA def(i) | DefUse.cs:61:13:61:13 | access to local variable i | -| DefUse.cs:63:9:63:18 | SSA def(this.Field2) | DefUse.cs:64:13:64:18 | access to field Field2 | -| DefUse.cs:66:9:66:18 | SSA def(this.Field3) | DefUse.cs:69:13:69:18 | access to field Field3 | -| DefUse.cs:67:19:67:27 | SSA def(tc) | DefUse.cs:68:9:68:10 | access to local variable tc | -| DefUse.cs:71:9:71:13 | SSA def(i) | DefUse.cs:72:9:72:9 | access to local variable i | -| DefUse.cs:72:9:72:11 | SSA def(i) | DefUse.cs:73:13:73:13 | access to local variable i | -| DefUse.cs:75:9:75:13 | SSA def(i) | DefUse.cs:76:9:76:9 | access to local variable i | -| DefUse.cs:76:9:76:11 | SSA def(i) | DefUse.cs:77:13:77:13 | access to local variable i | -| DefUse.cs:79:13:79:18 | SSA def(x1) | DefUse.cs:80:30:80:31 | access to local variable x1 | -| DefUse.cs:80:16:80:46 | SSA phi(x1) | DefUse.cs:80:30:80:31 | access to local variable x1 | -| DefUse.cs:80:30:80:31 | SSA def(x1) | DefUse.cs:80:30:80:31 | access to local variable x1 | -| DefUse.cs:80:30:80:31 | SSA def(x1) | DefUse.cs:81:13:81:14 | access to local variable x1 | -| DefUse.cs:83:13:83:18 | SSA def(x2) | DefUse.cs:85:15:85:16 | access to local variable x2 | -| DefUse.cs:85:15:85:16 | SSA def(x2) | DefUse.cs:87:13:87:14 | access to local variable x2 | -| DefUse.cs:89:13:89:18 | SSA def(x3) | DefUse.cs:92:15:92:16 | access to local variable x3 | -| DefUse.cs:92:15:92:16 | SSA def(x3) | DefUse.cs:94:13:94:14 | access to local variable x3 | -| DefUse.cs:93:15:93:16 | SSA def(x4) | DefUse.cs:95:13:95:14 | access to local variable x4 | -| DefUse.cs:97:13:97:18 | SSA def(x5) | DefUse.cs:98:16:98:17 | access to local variable x5 | -| DefUse.cs:98:16:98:17 | SSA phi(x5) | DefUse.cs:98:16:98:17 | access to local variable x5 | -| DefUse.cs:101:13:101:23 | SSA def(x5) | DefUse.cs:98:16:98:17 | access to local variable x5 | -| DefUse.cs:104:9:104:15 | SSA def(x5) | DefUse.cs:105:13:105:14 | access to local variable x5 | -| DefUse.cs:118:45:118:45 | SSA param(i) | DefUse.cs:118:65:118:65 | access to parameter i | -| DefUse.cs:128:19:128:19 | SSA param(i) | DefUse.cs:129:19:129:19 | access to parameter i | -| DefUse.cs:134:22:134:22 | SSA param(d) | DefUse.cs:135:14:135:14 | access to parameter d | -| DefUse.cs:142:68:142:69 | SSA param(ie) | DefUse.cs:144:27:144:28 | access to parameter ie | -| DefUse.cs:144:22:144:22 | SSA def(x) | DefUse.cs:146:17:146:17 | access to local variable x | -| DefUse.cs:155:9:155:18 | SSA def(this.Field4) | DefUse.cs:156:13:156:18 | access to field Field4 | -| DefUse.cs:160:10:160:16 | SSA entry def(this.Field4) | DefUse.cs:162:13:162:18 | access to field Field4 | -| DefUse.cs:167:23:167:23 | SSA param(i) | DefUse.cs:169:13:169:13 | access to parameter i | -| DefUse.cs:170:9:170:13 | SSA def(i) | DefUse.cs:182:13:182:13 | access to parameter i | -| DefUse.cs:171:23:180:9 | SSA def(a) | DefUse.cs:181:9:181:9 | access to local variable a | -| DefUse.cs:173:13:173:17 | SSA def(i) | DefUse.cs:174:17:174:17 | access to parameter i | -| DefUse.cs:175:32:179:13 | SSA capture def(i) | DefUse.cs:177:21:177:21 | access to parameter i | -| DefUse.cs:181:9:181:11 | SSA call def(i) | DefUse.cs:182:13:182:13 | access to parameter i | -| DefUse.cs:184:9:184:18 | SSA def(this.Field5) | DefUse.cs:185:13:185:18 | access to field Field5 | -| DefUse.cs:186:9:190:9 | SSA def(a) | DefUse.cs:191:9:191:9 | access to local variable a | -| DefUse.cs:188:13:188:22 | SSA def(this.Field5) | DefUse.cs:189:17:189:22 | access to field Field5 | -| DefUse.cs:191:9:191:11 | SSA call def(this.Field5) | DefUse.cs:192:13:192:18 | access to field Field5 | -| Example.cs:6:23:6:23 | SSA param(i) | Example.cs:8:22:8:22 | access to parameter i | -| Example.cs:8:9:8:22 | SSA def(this.Field) | Example.cs:9:13:9:22 | access to field Field | -| Example.cs:11:13:11:30 | SSA def(this.Field) | Example.cs:14:13:14:22 | access to field Field | -| Example.cs:13:13:13:23 | SSA call def(this.Field) | Example.cs:14:13:14:22 | access to field Field | -| Example.cs:14:9:14:24 | SSA phi(this.Field) | Example.cs:14:13:14:22 | access to field Field | -| Example.cs:18:16:18:16 | SSA param(p) | Example.cs:22:17:22:17 | access to parameter p | -| Example.cs:18:16:18:16 | SSA param(p) | Example.cs:25:13:25:13 | access to parameter p | -| Example.cs:18:24:18:24 | SSA param(b) | Example.cs:20:13:20:13 | access to parameter b | -| Example.cs:23:13:23:17 | SSA def(p) | Example.cs:25:13:25:13 | access to parameter p | -| Example.cs:25:9:25:15 | SSA phi(p) | Example.cs:25:13:25:13 | access to parameter p | -| Fields.cs:16:17:16:17 | SSA entry def(this.xs) | Fields.cs:18:19:18:20 | access to field xs | -| Fields.cs:19:9:19:13 | SSA call def(this.xs) | Fields.cs:20:13:20:14 | access to field xs | -| Fields.cs:20:9:20:14 | SSA def(x) | Fields.cs:21:13:21:13 | access to local variable x | -| Fields.cs:22:13:22:17 | SSA call def(this.xs) | Fields.cs:23:13:23:19 | access to field xs | -| Fields.cs:23:9:23:20 | SSA phi(this.xs) | Fields.cs:23:13:23:19 | access to field xs | -| Fields.cs:24:9:24:23 | SSA def(this.xs) | Fields.cs:25:13:25:14 | access to field xs | -| Fields.cs:28:17:28:17 | SSA entry def(Fields.stat) | Fields.cs:33:19:33:22 | access to field stat | -| Fields.cs:28:17:28:17 | SSA entry def(this.xs) | Fields.cs:32:19:32:20 | access to field xs | -| Fields.cs:30:13:30:28 | SSA def(f) | Fields.cs:31:19:31:19 | access to local variable f | -| Fields.cs:30:13:30:28 | SSA qualifier def(f.xs) | Fields.cs:31:19:31:22 | access to field xs | -| Fields.cs:30:17:30:28 | SSA call def(Fields.stat) | Fields.cs:33:19:33:22 | access to field stat | -| Fields.cs:34:9:34:16 | SSA call def(Fields.stat) | Fields.cs:37:13:37:16 | access to field stat | -| Fields.cs:34:9:34:16 | SSA call def(f.xs) | Fields.cs:35:13:35:16 | access to field xs | -| Fields.cs:34:9:34:16 | SSA call def(this.xs) | Fields.cs:36:13:36:14 | access to field xs | -| Fields.cs:38:9:38:13 | SSA call def(Fields.stat) | Fields.cs:41:13:41:16 | access to field stat | -| Fields.cs:38:9:38:13 | SSA call def(f.xs) | Fields.cs:39:13:39:16 | access to field xs | -| Fields.cs:38:9:38:13 | SSA call def(this.xs) | Fields.cs:40:13:40:14 | access to field xs | -| Fields.cs:42:9:42:23 | SSA def(this.xs) | Fields.cs:44:13:44:14 | access to field xs | -| Fields.cs:45:9:45:25 | SSA def(f.xs) | Fields.cs:46:13:46:16 | access to field xs | -| Fields.cs:47:9:47:14 | SSA def(z) | Fields.cs:48:13:48:13 | access to local variable z | -| Fields.cs:49:13:49:28 | SSA def(f) | Fields.cs:50:13:50:13 | access to local variable f | -| Fields.cs:49:13:49:28 | SSA qualifier def(f.xs) | Fields.cs:50:13:50:16 | access to field xs | -| Fields.cs:49:17:49:28 | SSA call def(Fields.stat) | Fields.cs:54:13:54:16 | access to field stat | -| Fields.cs:50:9:50:17 | SSA phi(Fields.stat) | Fields.cs:54:13:54:16 | access to field stat | -| Fields.cs:50:9:50:17 | SSA phi(f) | Fields.cs:50:13:50:13 | access to local variable f | -| Fields.cs:50:9:50:17 | SSA phi(f.xs) | Fields.cs:50:13:50:16 | access to field xs | -| Fields.cs:51:9:51:20 | SSA call def(Fields.stat) | Fields.cs:54:13:54:16 | access to field stat | -| Fields.cs:61:17:61:17 | SSA entry def(this.LoopField) | Fields.cs:65:24:65:32 | access to field LoopField | -| Fields.cs:63:16:63:28 | SSA untracked def(this.VolatileField) | Fields.cs:63:16:63:28 | access to field VolatileField | -| Fields.cs:69:21:69:33 | SSA untracked def(this.VolatileField) | Fields.cs:69:21:69:33 | access to field VolatileField | -| Fields.cs:71:17:71:35 | SSA untracked def(this.SingleAccessedField) | Fields.cs:71:17:71:35 | access to field SingleAccessedField | -| Fields.cs:76:20:76:38 | SSA untracked def(this.SingleAccessedField) | Fields.cs:76:20:76:38 | access to field SingleAccessedField | -| Fields.cs:77:13:77:45 | SSA def(f) | Fields.cs:80:9:80:9 | access to local variable f | -| Fields.cs:78:23:78:54 | SSA def(a) | Fields.cs:81:9:81:9 | access to local variable a | -| Fields.cs:78:27:78:54 | SSA capture def(f) | Fields.cs:78:35:78:35 | access to local variable f | -| Fields.cs:79:23:79:35 | SSA def(b) | Fields.cs:84:9:84:9 | access to local variable b | -| Fields.cs:80:9:80:25 | SSA def(f.xs) | Fields.cs:82:19:82:22 | access to field xs | -| Fields.cs:81:9:81:11 | SSA call def(f.xs) | Fields.cs:82:19:82:22 | access to field xs | -| Fields.cs:83:9:83:25 | SSA def(f.xs) | Fields.cs:85:19:85:22 | access to field xs | -| Fields.cs:85:9:85:22 | SSA def(this.xs) | Fields.cs:86:9:86:15 | access to field xs | -| Fields.cs:86:9:86:47 | SSA call def(f.xs) | Fields.cs:87:19:87:22 | access to field xs | -| Fields.cs:86:24:86:46 | SSA capture def(a) | Fields.cs:86:31:86:31 | access to local variable a | -| Fields.cs:87:9:87:22 | SSA def(this.xs) | Fields.cs:89:9:89:15 | access to field xs | -| Fields.cs:88:9:88:25 | SSA def(f.xs) | Fields.cs:90:19:90:22 | access to field xs | -| Fields.cs:89:24:89:46 | SSA capture def(b) | Fields.cs:89:31:89:31 | access to local variable b | -| Fields.cs:95:19:95:19 | SSA param(f) | Fields.cs:97:9:97:9 | access to parameter f | -| Fields.cs:97:9:97:30 | SSA def(f.Field) | Fields.cs:98:20:98:26 | access to field Field | -| Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field) | Fields.cs:98:20:98:32 | access to field Field | -| Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field) | Fields.cs:99:16:99:34 | access to field Field | -| Fields.cs:97:9:97:30 | SSA qualifier def(f.Field.Field.Field.Field) | Fields.cs:100:16:100:40 | access to field Field | -| Fields.cs:102:9:102:28 | SSA def(this.Field) | Fields.cs:104:16:104:25 | access to field Field | -| Fields.cs:107:33:107:33 | SSA param(f) | Fields.cs:107:38:107:38 | access to parameter f | -| Fields.cs:109:10:109:10 | SSA entry def(this.Field) | Fields.cs:115:20:115:29 | access to field Field | -| Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field) | Fields.cs:115:20:115:35 | access to field Field | -| Fields.cs:109:10:109:10 | SSA entry def(this.Field.Field.xs) | Fields.cs:116:21:116:39 | access to field xs | -| Fields.cs:114:9:114:22 | SSA call def(this.Field) | Fields.cs:115:20:115:29 | access to field Field | -| Fields.cs:114:9:114:22 | SSA call def(this.Field.Field) | Fields.cs:115:20:115:35 | access to field Field | -| Fields.cs:114:9:114:22 | SSA qualifier def(this.Field.Field.xs) | Fields.cs:116:21:116:39 | access to field xs | -| OutRef.cs:7:10:7:10 | SSA entry def(this.Field) | OutRef.cs:13:28:13:32 | access to field Field | -| OutRef.cs:9:13:9:17 | SSA def(j) | OutRef.cs:10:32:10:32 | access to local variable j | -| OutRef.cs:10:25:10:25 | SSA def(i) | OutRef.cs:11:13:11:13 | access to local variable i | -| OutRef.cs:10:32:10:32 | SSA def(j) | OutRef.cs:12:13:12:13 | access to local variable j | -| OutRef.cs:13:21:13:21 | SSA def(i) | OutRef.cs:14:13:14:13 | access to local variable i | -| OutRef.cs:13:28:13:32 | SSA def(this.Field) | OutRef.cs:15:13:15:17 | access to field Field | -| OutRef.cs:16:21:16:25 | SSA def(this.Field) | OutRef.cs:17:13:17:17 | access to field Field | -| OutRef.cs:18:13:18:28 | SSA def(t) | OutRef.cs:19:32:19:32 | access to local variable t | -| OutRef.cs:18:13:18:28 | SSA qualifier def(t.Field) | OutRef.cs:19:32:19:38 | access to field Field | -| OutRef.cs:19:21:19:25 | SSA def(this.Field) | OutRef.cs:20:13:20:17 | access to field Field | -| OutRef.cs:19:32:19:38 | SSA def(t.Field) | OutRef.cs:21:13:21:19 | access to field Field | -| OutRef.cs:22:22:22:22 | SSA def(j) | OutRef.cs:23:13:23:13 | access to local variable j | -| OutRef.cs:24:29:24:29 | SSA def(j) | OutRef.cs:25:13:25:13 | access to local variable j | -| OutRef.cs:28:37:28:37 | SSA param(j) | OutRef.cs:30:13:30:13 | access to parameter j | -| OutRef.cs:34:38:34:38 | SSA param(j) | OutRef.cs:36:13:36:13 | access to parameter j | -| OutRef.cs:39:24:39:24 | SSA param(b) | OutRef.cs:41:13:41:13 | access to parameter b | -| Patterns.cs:7:16:7:23 | SSA def(o) | Patterns.cs:8:13:8:13 | access to local variable o | -| Patterns.cs:8:18:8:23 | SSA def(i1) | Patterns.cs:10:38:10:39 | access to local variable i1 | -| Patterns.cs:12:23:12:31 | SSA def(s1) | Patterns.cs:14:41:14:42 | access to local variable s1 | -| Patterns.cs:24:18:24:23 | SSA def(i2) | Patterns.cs:24:30:24:31 | access to local variable i2 | -| Patterns.cs:27:18:27:23 | SSA def(i3) | Patterns.cs:28:42:28:43 | access to local variable i3 | -| Patterns.cs:30:18:30:26 | SSA def(s2) | Patterns.cs:31:45:31:46 | access to local variable s2 | -| Properties.cs:16:17:16:17 | SSA entry def(this.xs) | Properties.cs:18:19:18:20 | access to property xs | -| Properties.cs:19:9:19:13 | SSA call def(this.xs) | Properties.cs:20:13:20:14 | access to property xs | -| Properties.cs:20:9:20:14 | SSA def(x) | Properties.cs:21:13:21:13 | access to local variable x | -| Properties.cs:22:13:22:17 | SSA call def(this.xs) | Properties.cs:23:13:23:19 | access to property xs | -| Properties.cs:23:9:23:20 | SSA phi(this.xs) | Properties.cs:23:13:23:19 | access to property xs | -| Properties.cs:24:9:24:23 | SSA def(this.xs) | Properties.cs:25:13:25:14 | access to property xs | -| Properties.cs:28:17:28:17 | SSA entry def(Properties.stat) | Properties.cs:33:19:33:22 | access to property stat | -| Properties.cs:28:17:28:17 | SSA entry def(this.xs) | Properties.cs:32:19:32:20 | access to property xs | -| Properties.cs:30:13:30:32 | SSA def(f) | Properties.cs:31:19:31:19 | access to local variable f | -| Properties.cs:30:13:30:32 | SSA qualifier def(f.xs) | Properties.cs:31:19:31:22 | access to property xs | -| Properties.cs:30:17:30:32 | SSA call def(Properties.stat) | Properties.cs:33:19:33:22 | access to property stat | -| Properties.cs:34:9:34:16 | SSA call def(Properties.stat) | Properties.cs:37:13:37:16 | access to property stat | -| Properties.cs:34:9:34:16 | SSA call def(f.xs) | Properties.cs:35:13:35:16 | access to property xs | -| Properties.cs:34:9:34:16 | SSA call def(this.xs) | Properties.cs:36:13:36:14 | access to property xs | -| Properties.cs:38:9:38:13 | SSA call def(Properties.stat) | Properties.cs:41:13:41:16 | access to property stat | -| Properties.cs:38:9:38:13 | SSA call def(f.xs) | Properties.cs:39:13:39:16 | access to property xs | -| Properties.cs:38:9:38:13 | SSA call def(this.xs) | Properties.cs:40:13:40:14 | access to property xs | -| Properties.cs:42:9:42:23 | SSA def(this.xs) | Properties.cs:44:13:44:14 | access to property xs | -| Properties.cs:45:9:45:25 | SSA def(f.xs) | Properties.cs:46:13:46:16 | access to property xs | -| Properties.cs:47:9:47:14 | SSA def(z) | Properties.cs:48:13:48:13 | access to local variable z | -| Properties.cs:49:13:49:32 | SSA def(f) | Properties.cs:50:13:50:13 | access to local variable f | -| Properties.cs:49:13:49:32 | SSA qualifier def(f.xs) | Properties.cs:50:13:50:16 | access to property xs | -| Properties.cs:49:17:49:32 | SSA call def(Properties.stat) | Properties.cs:54:13:54:16 | access to property stat | -| Properties.cs:50:9:50:17 | SSA phi(Properties.stat) | Properties.cs:54:13:54:16 | access to property stat | -| Properties.cs:50:9:50:17 | SSA phi(f) | Properties.cs:50:13:50:13 | access to local variable f | -| Properties.cs:50:9:50:17 | SSA phi(f.xs) | Properties.cs:50:13:50:16 | access to property xs | -| Properties.cs:51:9:51:24 | SSA call def(Properties.stat) | Properties.cs:54:13:54:16 | access to property stat | -| Properties.cs:61:17:61:17 | SSA entry def(this.LoopProp) | Properties.cs:65:24:65:31 | access to property LoopProp | -| Properties.cs:61:23:61:23 | SSA param(i) | Properties.cs:63:16:63:16 | access to parameter i | -| Properties.cs:63:16:63:16 | SSA phi(i) | Properties.cs:63:16:63:16 | access to parameter i | -| Properties.cs:63:16:63:18 | SSA def(i) | Properties.cs:63:16:63:16 | access to parameter i | -| Properties.cs:67:21:67:38 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:67:21:67:38 | access to property SingleAccessedProp | -| Properties.cs:72:20:72:37 | SSA untracked def(this.SingleAccessedProp) | Properties.cs:72:20:72:37 | access to property SingleAccessedProp | -| Properties.cs:73:13:73:32 | SSA def(f) | Properties.cs:76:9:76:9 | access to local variable f | -| Properties.cs:74:23:74:54 | SSA def(a) | Properties.cs:77:9:77:9 | access to local variable a | -| Properties.cs:74:27:74:54 | SSA capture def(f) | Properties.cs:74:35:74:35 | access to local variable f | -| Properties.cs:75:23:75:35 | SSA def(b) | Properties.cs:80:9:80:9 | access to local variable b | -| Properties.cs:76:9:76:25 | SSA def(f.xs) | Properties.cs:78:19:78:22 | access to property xs | -| Properties.cs:77:9:77:11 | SSA call def(f.xs) | Properties.cs:78:19:78:22 | access to property xs | -| Properties.cs:79:9:79:25 | SSA def(f.xs) | Properties.cs:81:19:81:22 | access to property xs | -| Properties.cs:81:9:81:22 | SSA def(this.xs) | Properties.cs:82:9:82:15 | access to property xs | -| Properties.cs:82:9:82:47 | SSA call def(f.xs) | Properties.cs:83:19:83:22 | access to property xs | -| Properties.cs:82:24:82:46 | SSA capture def(a) | Properties.cs:82:31:82:31 | access to local variable a | -| Properties.cs:83:9:83:22 | SSA def(this.xs) | Properties.cs:85:9:85:15 | access to property xs | -| Properties.cs:84:9:84:25 | SSA def(f.xs) | Properties.cs:86:19:86:22 | access to property xs | -| Properties.cs:85:24:85:46 | SSA capture def(b) | Properties.cs:85:31:85:31 | access to local variable b | -| Properties.cs:95:20:95:38 | SSA untracked def(this.NonTrivialProp) | Properties.cs:95:20:95:38 | access to property NonTrivialProp | -| Properties.cs:98:16:98:31 | SSA untracked def(this.VirtualProp) | Properties.cs:98:16:98:31 | access to property VirtualProp | -| Properties.cs:100:9:100:26 | SSA untracked def(this.VolatileField) | Properties.cs:100:9:100:26 | access to field VolatileField | -| Properties.cs:101:21:101:38 | SSA untracked def(this.VolatileField) | Properties.cs:101:21:101:38 | access to field VolatileField | -| Properties.cs:101:21:101:41 | SSA untracked def(this.VolatileField.xs) | Properties.cs:101:21:101:41 | access to property xs | -| Properties.cs:106:37:106:37 | SSA param(p) | Properties.cs:106:42:106:42 | access to parameter p | -| Properties.cs:108:10:108:10 | SSA entry def(this.Props) | Properties.cs:114:20:114:29 | access to field Props | -| Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props) | Properties.cs:114:20:114:35 | access to field Props | -| Properties.cs:108:10:108:10 | SSA entry def(this.Props.Props.xs) | Properties.cs:115:21:115:39 | access to property xs | -| Properties.cs:113:9:113:22 | SSA call def(this.Props) | Properties.cs:114:20:114:29 | access to field Props | -| Properties.cs:113:9:113:22 | SSA call def(this.Props.Props) | Properties.cs:114:20:114:35 | access to field Props | -| Properties.cs:113:9:113:22 | SSA qualifier def(this.Props.Props.xs) | Properties.cs:115:21:115:39 | access to property xs | -| Test.cs:5:15:5:20 | SSA param(param1) | Test.cs:11:13:11:18 | access to parameter param1 | -| Test.cs:5:67:5:72 | SSA param(param2) | Test.cs:39:27:39:32 | access to parameter param2 | -| Test.cs:7:9:7:17 | SSA def(this.field) | Test.cs:33:13:33:17 | access to field field | -| Test.cs:8:13:8:17 | SSA def(x) | Test.cs:13:13:13:13 | access to local variable x | -| Test.cs:8:13:8:17 | SSA def(x) | Test.cs:25:16:25:16 | access to local variable x | -| Test.cs:13:13:13:15 | SSA def(x) | Test.cs:14:19:14:19 | access to local variable x | -| Test.cs:14:13:14:19 | SSA def(y) | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:14:17:14:19 | SSA def(x) | Test.cs:25:16:25:16 | access to local variable x | -| Test.cs:15:13:15:17 | SSA def(z) | Test.cs:24:13:24:13 | access to local variable z | -| Test.cs:19:13:19:17 | SSA def(y) | Test.cs:20:13:20:13 | access to local variable y | -| Test.cs:20:13:20:18 | SSA def(y) | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:21:13:21:22 | SSA def(this.field) | Test.cs:33:13:33:17 | access to field field | -| Test.cs:22:13:22:17 | SSA def(z) | Test.cs:24:13:24:13 | access to local variable z | -| Test.cs:24:9:24:15 | SSA phi(this.field) | Test.cs:33:13:33:17 | access to field field | -| Test.cs:24:9:24:15 | SSA phi(x) | Test.cs:25:16:25:16 | access to local variable x | -| Test.cs:24:9:24:15 | SSA phi(y) | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:24:9:24:15 | SSA phi(z) | Test.cs:24:13:24:13 | access to local variable z | -| Test.cs:25:16:25:16 | SSA phi(param1) | Test.cs:27:17:27:22 | access to parameter param1 | -| Test.cs:25:16:25:16 | SSA phi(param1) | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:25:16:25:16 | SSA phi(y) | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:27:17:27:24 | SSA def(param1) | Test.cs:27:17:27:22 | access to parameter param1 | -| Test.cs:27:17:27:24 | SSA def(param1) | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:31:13:31:18 | SSA def(y) | Test.cs:25:20:25:20 | access to local variable y | -| Test.cs:33:9:33:19 | SSA phi(param1) | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:34:18:34:22 | SSA def(i) | Test.cs:34:25:34:25 | access to local variable i | -| Test.cs:34:25:34:25 | SSA phi(i) | Test.cs:34:25:34:25 | access to local variable i | -| Test.cs:34:25:34:25 | SSA phi(x) | Test.cs:36:13:36:13 | access to local variable x | -| Test.cs:34:25:34:25 | SSA phi(x) | Test.cs:43:16:43:16 | access to local variable x | -| Test.cs:34:33:34:35 | SSA def(i) | Test.cs:34:25:34:25 | access to local variable i | -| Test.cs:36:13:36:18 | SSA def(x) | Test.cs:36:13:36:13 | access to local variable x | -| Test.cs:36:13:36:18 | SSA def(x) | Test.cs:43:16:43:16 | access to local variable x | -| Test.cs:39:9:42:9 | SSA phi(param1) | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:39:22:39:22 | SSA def(w) | Test.cs:41:23:41:23 | access to local variable w | -| Test.cs:41:13:41:23 | SSA def(param1) | Test.cs:41:13:41:18 | access to parameter param1 | -| Test.cs:46:10:46:10 | SSA entry def(this.field) | Test.cs:56:13:56:17 | access to field field | -| Test.cs:46:16:46:18 | SSA param(in) | Test.cs:48:13:48:15 | access to parameter in | -| Test.cs:57:9:57:17 | SSA def(this.field) | Test.cs:58:13:58:17 | access to field field | -| Test.cs:68:45:68:45 | [exception: DivideByZeroException] SSA def(e) | Test.cs:70:17:70:17 | access to local variable e | -| Tuples.cs:10:9:10:54 | SSA def(b) | Tuples.cs:12:13:12:13 | access to local variable b | -| Tuples.cs:10:9:10:54 | SSA def(s) | Tuples.cs:13:13:13:13 | access to local variable s | -| Tuples.cs:10:9:10:54 | SSA def(x) | Tuples.cs:11:13:11:13 | access to local variable x | -| Tuples.cs:14:9:14:32 | SSA def(b) | Tuples.cs:16:13:16:13 | access to local variable b | -| Tuples.cs:14:9:14:32 | SSA def(s) | Tuples.cs:17:13:17:13 | access to local variable s | -| Tuples.cs:14:9:14:32 | SSA def(x) | Tuples.cs:15:13:15:13 | access to local variable x | -| Tuples.cs:18:40:18:57 | SSA def(tuple) | Tuples.cs:19:13:19:17 | access to local variable tuple | -| Tuples.cs:20:9:20:34 | SSA def(this.Field) | Tuples.cs:22:13:22:17 | access to field Field | -| Tuples.cs:20:9:20:34 | SSA def(this.Property) | Tuples.cs:21:13:21:20 | access to property Property | -| Tuples.cs:23:9:23:37 | SSA def(x) | Tuples.cs:24:13:24:13 | access to local variable x | -| Tuples.cs:25:13:25:28 | SSA def(t) | Tuples.cs:26:17:26:17 | access to local variable t | -| Tuples.cs:26:9:26:33 | SSA def(t.Field) | Tuples.cs:28:13:28:19 | access to field Field | -| Tuples.cs:26:9:26:33 | SSA def(this.Field) | Tuples.cs:27:13:27:17 | access to field Field | diff --git a/csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.ql b/csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.ql deleted file mode 100644 index ebbd1561b1d0..000000000000 --- a/csharp/ql/test/library-tests/dataflow/ssa/SsaAdjacentUncertainRead.ql +++ /dev/null @@ -1,5 +0,0 @@ -import csharp - -from Ssa::Definition def, AssignableRead read -where read = def.getAFirstUncertainRead() -select def, read From c17eca90a164f29f619ec6c24364a4a741aab0cc Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 18 Dec 2018 12:29:31 +0000 Subject: [PATCH 35/69] JS: add test case for $(location) --- .../Security/CWE-079/StoredXss.expected | 18 +++++++++++++ .../query-tests/Security/CWE-079/Xss.expected | 27 +++++++++++++++++++ .../test/query-tests/Security/CWE-079/tst.js | 12 +++++++++ 3 files changed, 57 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected index c4813758503c..6832a9b88b98 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -214,6 +214,18 @@ nodes | tst.js:256:7:256:17 | window.name | | tst.js:257:7:257:10 | name | | tst.js:261:11:261:21 | window.name | +| tst.js:267:7:267:14 | location | +| tst.js:268:7:268:21 | window.location | +| tst.js:269:7:269:23 | document.location | +| tst.js:270:9:270:23 | loc1 | +| tst.js:270:16:270:23 | location | +| tst.js:271:9:271:30 | loc2 | +| tst.js:271:16:271:30 | window.location | +| tst.js:272:9:272:32 | loc3 | +| tst.js:272:16:272:32 | document.location | +| tst.js:273:7:273:10 | loc1 | +| tst.js:274:7:274:10 | loc2 | +| tst.js:275:7:275:10 | loc3 | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | | winjs.js:2:17:2:40 | documen ... .search | @@ -396,6 +408,12 @@ edges | tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted | | tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted | +| tst.js:270:9:270:23 | loc1 | tst.js:273:7:273:10 | loc1 | +| tst.js:270:16:270:23 | location | tst.js:270:9:270:23 | loc1 | +| tst.js:271:9:271:30 | loc2 | tst.js:274:7:274:10 | loc2 | +| tst.js:271:16:271:30 | window.location | tst.js:271:9:271:30 | loc2 | +| tst.js:272:9:272:32 | loc3 | tst.js:275:7:275:10 | loc3 | +| tst.js:272:16:272:32 | document.location | tst.js:272:9:272:32 | loc3 | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | | winjs.js:2:17:2:33 | document.location | winjs.js:2:17:2:40 | documen ... .search | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected index 36771ee86ac2..01293c7daf0a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected @@ -171,6 +171,18 @@ nodes | tst.js:256:7:256:17 | window.name | | tst.js:257:7:257:10 | name | | tst.js:261:11:261:21 | window.name | +| tst.js:267:7:267:14 | location | +| tst.js:268:7:268:21 | window.location | +| tst.js:269:7:269:23 | document.location | +| tst.js:270:9:270:23 | loc1 | +| tst.js:270:16:270:23 | location | +| tst.js:271:9:271:30 | loc2 | +| tst.js:271:16:271:30 | window.location | +| tst.js:272:9:272:32 | loc3 | +| tst.js:272:16:272:32 | document.location | +| tst.js:273:7:273:10 | loc1 | +| tst.js:274:7:274:10 | loc2 | +| tst.js:275:7:275:10 | loc3 | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | | winjs.js:2:17:2:40 | documen ... .search | @@ -307,6 +319,12 @@ edges | tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted | | tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted | +| tst.js:270:9:270:23 | loc1 | tst.js:273:7:273:10 | loc1 | +| tst.js:270:16:270:23 | location | tst.js:270:9:270:23 | loc1 | +| tst.js:271:9:271:30 | loc2 | tst.js:274:7:274:10 | loc2 | +| tst.js:271:16:271:30 | window.location | tst.js:271:9:271:30 | loc2 | +| tst.js:272:9:272:32 | loc3 | tst.js:275:7:275:10 | loc3 | +| tst.js:272:16:272:32 | document.location | tst.js:272:9:272:32 | loc3 | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | | winjs.js:2:7:2:53 | tainted | winjs.js:4:43:4:49 | tainted | | winjs.js:2:17:2:33 | document.location | winjs.js:2:17:2:40 | documen ... .search | @@ -378,5 +396,14 @@ edges | tst.js:256:7:256:17 | window.name | tst.js:256:7:256:17 | window.name | tst.js:256:7:256:17 | window.name | Cross-site scripting vulnerability due to $@. | tst.js:256:7:256:17 | window.name | user-provided value | | tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | Cross-site scripting vulnerability due to $@. | tst.js:257:7:257:10 | name | user-provided value | | tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | Cross-site scripting vulnerability due to $@. | tst.js:261:11:261:21 | window.name | user-provided value | +| tst.js:267:7:267:14 | location | tst.js:267:7:267:14 | location | tst.js:267:7:267:14 | location | Cross-site scripting vulnerability due to $@. | tst.js:267:7:267:14 | location | user-provided value | +| tst.js:268:7:268:21 | window.location | tst.js:268:7:268:21 | window.location | tst.js:268:7:268:21 | window.location | Cross-site scripting vulnerability due to $@. | tst.js:268:7:268:21 | window.location | user-provided value | +| tst.js:269:7:269:23 | document.location | tst.js:269:7:269:23 | document.location | tst.js:269:7:269:23 | document.location | Cross-site scripting vulnerability due to $@. | tst.js:269:7:269:23 | document.location | user-provided value | +| tst.js:273:7:273:10 | loc1 | tst.js:270:16:270:23 | location | tst.js:273:7:273:10 | loc1 | Cross-site scripting vulnerability due to $@. | tst.js:270:16:270:23 | location | user-provided value | +| tst.js:273:7:273:10 | loc1 | tst.js:273:7:273:10 | loc1 | tst.js:273:7:273:10 | loc1 | Cross-site scripting vulnerability due to $@. | tst.js:273:7:273:10 | loc1 | user-provided value | +| tst.js:274:7:274:10 | loc2 | tst.js:271:16:271:30 | window.location | tst.js:274:7:274:10 | loc2 | Cross-site scripting vulnerability due to $@. | tst.js:271:16:271:30 | window.location | user-provided value | +| tst.js:274:7:274:10 | loc2 | tst.js:274:7:274:10 | loc2 | tst.js:274:7:274:10 | loc2 | Cross-site scripting vulnerability due to $@. | tst.js:274:7:274:10 | loc2 | user-provided value | +| tst.js:275:7:275:10 | loc3 | tst.js:272:16:272:32 | document.location | tst.js:275:7:275:10 | loc3 | Cross-site scripting vulnerability due to $@. | tst.js:272:16:272:32 | document.location | user-provided value | +| tst.js:275:7:275:10 | loc3 | tst.js:275:7:275:10 | loc3 | tst.js:275:7:275:10 | loc3 | Cross-site scripting vulnerability due to $@. | tst.js:275:7:275:10 | loc3 | user-provided value | | winjs.js:3:43:3:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:3:43:3:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value | | winjs.js:4:43:4:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:4:43:4:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/tst.js index cab08a0d925e..e91fcb278e5d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/tst.js @@ -262,3 +262,15 @@ function windowNameAssigned() { $(name); // OK } } + +function jqueryLocation() { + $(location); // OK + $(window.location); // OK + $(document.location); // OK + var loc1 = location; + var loc2 = window.location; + var loc3 = document.location; + $(loc1); // OK + $(loc2); // OK + $(loc3); // OK +} From 02978c97f1784958bba5518fe3cfaeabe3bc60d3 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 18 Dec 2018 13:01:22 +0000 Subject: [PATCH 36/69] JS: whitelist $(location) in simple cases --- .../security/dataflow/DomBasedXss.qll | 3 ++- .../Security/CWE-079/StoredXss.expected | 13 ------------ .../query-tests/Security/CWE-079/Xss.expected | 21 ------------------- .../test/query-tests/Security/CWE-079/tst.js | 2 +- 4 files changed, 3 insertions(+), 36 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/DomBasedXss.qll b/javascript/ql/src/semmle/javascript/security/dataflow/DomBasedXss.qll index 7a935196ce0b..6e7635821ccd 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/DomBasedXss.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/DomBasedXss.qll @@ -91,7 +91,8 @@ module DomBasedXss { isPrefixOfJQueryHtmlString(astNode, prefix) and strval = prefix.asExpr().getStringValue() and not strval.regexpMatch("\\s*<.*") - ) + ) and + not isDocumentURL(astNode) ) or // call to an Angular method that interprets its argument as HTML diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected index 6832a9b88b98..ed5dfaa34a86 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -214,17 +214,8 @@ nodes | tst.js:256:7:256:17 | window.name | | tst.js:257:7:257:10 | name | | tst.js:261:11:261:21 | window.name | -| tst.js:267:7:267:14 | location | -| tst.js:268:7:268:21 | window.location | -| tst.js:269:7:269:23 | document.location | -| tst.js:270:9:270:23 | loc1 | -| tst.js:270:16:270:23 | location | -| tst.js:271:9:271:30 | loc2 | -| tst.js:271:16:271:30 | window.location | | tst.js:272:9:272:32 | loc3 | | tst.js:272:16:272:32 | document.location | -| tst.js:273:7:273:10 | loc1 | -| tst.js:274:7:274:10 | loc2 | | tst.js:275:7:275:10 | loc3 | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | @@ -408,10 +399,6 @@ edges | tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted | | tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted | -| tst.js:270:9:270:23 | loc1 | tst.js:273:7:273:10 | loc1 | -| tst.js:270:16:270:23 | location | tst.js:270:9:270:23 | loc1 | -| tst.js:271:9:271:30 | loc2 | tst.js:274:7:274:10 | loc2 | -| tst.js:271:16:271:30 | window.location | tst.js:271:9:271:30 | loc2 | | tst.js:272:9:272:32 | loc3 | tst.js:275:7:275:10 | loc3 | | tst.js:272:16:272:32 | document.location | tst.js:272:9:272:32 | loc3 | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected index 01293c7daf0a..37800a8962a0 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected @@ -171,17 +171,8 @@ nodes | tst.js:256:7:256:17 | window.name | | tst.js:257:7:257:10 | name | | tst.js:261:11:261:21 | window.name | -| tst.js:267:7:267:14 | location | -| tst.js:268:7:268:21 | window.location | -| tst.js:269:7:269:23 | document.location | -| tst.js:270:9:270:23 | loc1 | -| tst.js:270:16:270:23 | location | -| tst.js:271:9:271:30 | loc2 | -| tst.js:271:16:271:30 | window.location | | tst.js:272:9:272:32 | loc3 | | tst.js:272:16:272:32 | document.location | -| tst.js:273:7:273:10 | loc1 | -| tst.js:274:7:274:10 | loc2 | | tst.js:275:7:275:10 | loc3 | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | @@ -319,10 +310,6 @@ edges | tst.js:238:23:238:29 | tainted | tst.js:228:32:228:49 | prevProps.tainted4 | | tst.js:244:39:244:55 | props.propTainted | tst.js:248:60:248:82 | this.st ... Tainted | | tst.js:252:23:252:29 | tainted | tst.js:244:39:244:55 | props.propTainted | -| tst.js:270:9:270:23 | loc1 | tst.js:273:7:273:10 | loc1 | -| tst.js:270:16:270:23 | location | tst.js:270:9:270:23 | loc1 | -| tst.js:271:9:271:30 | loc2 | tst.js:274:7:274:10 | loc2 | -| tst.js:271:16:271:30 | window.location | tst.js:271:9:271:30 | loc2 | | tst.js:272:9:272:32 | loc3 | tst.js:275:7:275:10 | loc3 | | tst.js:272:16:272:32 | document.location | tst.js:272:9:272:32 | loc3 | | winjs.js:2:7:2:53 | tainted | winjs.js:3:43:3:49 | tainted | @@ -396,14 +383,6 @@ edges | tst.js:256:7:256:17 | window.name | tst.js:256:7:256:17 | window.name | tst.js:256:7:256:17 | window.name | Cross-site scripting vulnerability due to $@. | tst.js:256:7:256:17 | window.name | user-provided value | | tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | Cross-site scripting vulnerability due to $@. | tst.js:257:7:257:10 | name | user-provided value | | tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | Cross-site scripting vulnerability due to $@. | tst.js:261:11:261:21 | window.name | user-provided value | -| tst.js:267:7:267:14 | location | tst.js:267:7:267:14 | location | tst.js:267:7:267:14 | location | Cross-site scripting vulnerability due to $@. | tst.js:267:7:267:14 | location | user-provided value | -| tst.js:268:7:268:21 | window.location | tst.js:268:7:268:21 | window.location | tst.js:268:7:268:21 | window.location | Cross-site scripting vulnerability due to $@. | tst.js:268:7:268:21 | window.location | user-provided value | -| tst.js:269:7:269:23 | document.location | tst.js:269:7:269:23 | document.location | tst.js:269:7:269:23 | document.location | Cross-site scripting vulnerability due to $@. | tst.js:269:7:269:23 | document.location | user-provided value | -| tst.js:273:7:273:10 | loc1 | tst.js:270:16:270:23 | location | tst.js:273:7:273:10 | loc1 | Cross-site scripting vulnerability due to $@. | tst.js:270:16:270:23 | location | user-provided value | -| tst.js:273:7:273:10 | loc1 | tst.js:273:7:273:10 | loc1 | tst.js:273:7:273:10 | loc1 | Cross-site scripting vulnerability due to $@. | tst.js:273:7:273:10 | loc1 | user-provided value | -| tst.js:274:7:274:10 | loc2 | tst.js:271:16:271:30 | window.location | tst.js:274:7:274:10 | loc2 | Cross-site scripting vulnerability due to $@. | tst.js:271:16:271:30 | window.location | user-provided value | -| tst.js:274:7:274:10 | loc2 | tst.js:274:7:274:10 | loc2 | tst.js:274:7:274:10 | loc2 | Cross-site scripting vulnerability due to $@. | tst.js:274:7:274:10 | loc2 | user-provided value | | tst.js:275:7:275:10 | loc3 | tst.js:272:16:272:32 | document.location | tst.js:275:7:275:10 | loc3 | Cross-site scripting vulnerability due to $@. | tst.js:272:16:272:32 | document.location | user-provided value | -| tst.js:275:7:275:10 | loc3 | tst.js:275:7:275:10 | loc3 | tst.js:275:7:275:10 | loc3 | Cross-site scripting vulnerability due to $@. | tst.js:275:7:275:10 | loc3 | user-provided value | | winjs.js:3:43:3:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:3:43:3:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value | | winjs.js:4:43:4:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:4:43:4:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/tst.js index e91fcb278e5d..6a945d6ab20d 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/tst.js @@ -272,5 +272,5 @@ function jqueryLocation() { var loc3 = document.location; $(loc1); // OK $(loc2); // OK - $(loc3); // OK + $(loc3); // OK - but still flagged } From 7f538e82c09d54dc2f3a35c70a34c6c31752ad7f Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 18 Dec 2018 13:55:05 +0000 Subject: [PATCH 37/69] JS: add test case for non-whitelisted use of location --- .../ql/test/query-tests/Security/CWE-079/StoredXss.expected | 1 + javascript/ql/test/query-tests/Security/CWE-079/Xss.expected | 2 ++ javascript/ql/test/query-tests/Security/CWE-079/tst.js | 2 ++ 3 files changed, 5 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected index ed5dfaa34a86..50fcbbca5efd 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/StoredXss.expected @@ -217,6 +217,7 @@ nodes | tst.js:272:9:272:32 | loc3 | | tst.js:272:16:272:32 | document.location | | tst.js:275:7:275:10 | loc3 | +| tst.js:277:22:277:29 | location | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | | winjs.js:2:17:2:40 | documen ... .search | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected index 37800a8962a0..34ab0b8a16dc 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected +++ b/javascript/ql/test/query-tests/Security/CWE-079/Xss.expected @@ -174,6 +174,7 @@ nodes | tst.js:272:9:272:32 | loc3 | | tst.js:272:16:272:32 | document.location | | tst.js:275:7:275:10 | loc3 | +| tst.js:277:22:277:29 | location | | winjs.js:2:7:2:53 | tainted | | winjs.js:2:17:2:33 | document.location | | winjs.js:2:17:2:40 | documen ... .search | @@ -384,5 +385,6 @@ edges | tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | tst.js:257:7:257:10 | name | Cross-site scripting vulnerability due to $@. | tst.js:257:7:257:10 | name | user-provided value | | tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | tst.js:261:11:261:21 | window.name | Cross-site scripting vulnerability due to $@. | tst.js:261:11:261:21 | window.name | user-provided value | | tst.js:275:7:275:10 | loc3 | tst.js:272:16:272:32 | document.location | tst.js:275:7:275:10 | loc3 | Cross-site scripting vulnerability due to $@. | tst.js:272:16:272:32 | document.location | user-provided value | +| tst.js:277:22:277:29 | location | tst.js:277:22:277:29 | location | tst.js:277:22:277:29 | location | Cross-site scripting vulnerability due to $@. | tst.js:277:22:277:29 | location | user-provided value | | winjs.js:3:43:3:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:3:43:3:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value | | winjs.js:4:43:4:49 | tainted | winjs.js:2:17:2:33 | document.location | winjs.js:4:43:4:49 | tainted | Cross-site scripting vulnerability due to $@. | winjs.js:2:17:2:33 | document.location | user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-079/tst.js b/javascript/ql/test/query-tests/Security/CWE-079/tst.js index 6a945d6ab20d..b10da36c190b 100644 --- a/javascript/ql/test/query-tests/Security/CWE-079/tst.js +++ b/javascript/ql/test/query-tests/Security/CWE-079/tst.js @@ -273,4 +273,6 @@ function jqueryLocation() { $(loc1); // OK $(loc2); // OK $(loc3); // OK - but still flagged + + $("body").append(location); // NOT OK } From 1246de466a9f1058a57ef05afea4050ea0c62ee0 Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 18 Dec 2018 13:58:03 +0000 Subject: [PATCH 38/69] JS: add change note --- change-notes/1.20/analysis-javascript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/change-notes/1.20/analysis-javascript.md b/change-notes/1.20/analysis-javascript.md index af8bb984ae8a..10cef9b56734 100644 --- a/change-notes/1.20/analysis-javascript.md +++ b/change-notes/1.20/analysis-javascript.md @@ -24,7 +24,7 @@ | **Query** | **Expected impact** | **Change** | |--------------------------------------------|------------------------------|------------------------------------------------------------------------------| -| Client-side cross-site scripting | More results | This rule now recognizes WinJS functions that are vulnerable to HTML injection. | +| Client-side cross-site scripting | More true-positive results, fewer false-positive results. | This rule now recognizes WinJS functions that are vulnerable to HTML injection, and no longer flags certain safe uses of jQuery. | | Insecure randomness | More results | This rule now flags insecure uses of `crypto.pseudoRandomBytes`. | | Unused parameter | Fewer false-positive results | This rule no longer flags parameters with leading underscore. | | Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that are implictly used by JSX elements, and no longer flags variables with leading underscore. | From f57454951bc491d3335f7f6b426cadf583dd6ccc Mon Sep 17 00:00:00 2001 From: Asger F Date: Tue, 18 Dec 2018 14:15:12 +0000 Subject: [PATCH 39/69] JS: move
      outside of

      element --- .../MissingIndexAdjustmentAfterConcurrentModification.qhelp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp index 20bf93105d3e..3340b919ce2d 100644 --- a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp +++ b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp @@ -15,6 +15,8 @@

      Determine what the loop is supposed to do: +

      +
      • If the intention is to remove every occurence of a certain value, decrement the loop counter after removing an element, to counterbalance @@ -28,7 +30,6 @@ Determine what the loop is supposed to do: so it is clear that the loop is not a trivial array iteration loop.
      -

      From f9d7f8ba11be7cd9fac14eefa67c4831a5408c0d Mon Sep 17 00:00:00 2001 From: Asger F Date: Wed, 19 Dec 2018 10:10:56 +0000 Subject: [PATCH 40/69] JS: fix links in qhelp --- .../MissingIndexAdjustmentAfterConcurrentModification.qhelp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp index 3340b919ce2d..b682eab0688e 100644 --- a/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp +++ b/javascript/ql/src/Statements/MissingIndexAdjustmentAfterConcurrentModification.qhelp @@ -38,7 +38,7 @@ Determine what the loop is supposed to do: In this example, a function is intended to remove ".." parts from a path:

      - +

      However, whenever the input contain two ".." parts right after one another, only the first will be removed. @@ -51,13 +51,13 @@ index 0 and will therefore be skipped. One way to avoid this is to decrement the loop counter after removing an element from the array:

      - +

      Alternatively, use the filter method:

      - +
      From f84301e4769682df9264fa26258b33edd2328269 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 14 Dec 2018 10:59:55 +0000 Subject: [PATCH 41/69] JS: add tests with res.sendFile root option --- .../query-tests/Security/CWE-022/TaintedPath.expected | 6 ++++++ .../test/query-tests/Security/CWE-022/tainted-sendFile.js | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index 7a73a250542c..f3da2d2d8f9a 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -84,6 +84,9 @@ nodes | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | +| tainted-sendFile.js:12:16:12:33 | req.param("gimme") | +| tainted-sendFile.js:14:16:14:33 | req.param("gimme") | +| tainted-sendFile.js:17:16:17:32 | req.param("file") | | views.js:1:43:1:55 | req.params[0] | edges | TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | @@ -188,4 +191,7 @@ edges | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | a user-provided value | | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | a user-provided value | +| tainted-sendFile.js:12:16:12:33 | req.param("gimme") | tainted-sendFile.js:12:16:12:33 | req.param("gimme") | tainted-sendFile.js:12:16:12:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:12:16:12:33 | req.param("gimme") | a user-provided value | +| tainted-sendFile.js:14:16:14:33 | req.param("gimme") | tainted-sendFile.js:14:16:14:33 | req.param("gimme") | tainted-sendFile.js:14:16:14:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:14:16:14:33 | req.param("gimme") | a user-provided value | +| tainted-sendFile.js:17:16:17:32 | req.param("file") | tainted-sendFile.js:17:16:17:32 | req.param("file") | tainted-sendFile.js:17:16:17:32 | req.param("file") | This path depends on $@. | tainted-sendFile.js:17:16:17:32 | req.param("file") | a user-provided value | | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | diff --git a/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js b/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js index e925f6c566b3..21f385f44ada 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js +++ b/javascript/ql/test/query-tests/Security/CWE-022/tainted-sendFile.js @@ -7,4 +7,12 @@ app.get('/some/path', function(req, res) { res.sendFile(req.param("gimme")); // BAD: same as above res.sendfile(req.param("gimme")); + + // GOOD: ensures files cannot be accessed outside of root folder + res.sendFile(req.param("gimme"), { root: process.cwd() }); + // GOOD: ensures files cannot be accessed outside of root folder + res.sendfile(req.param("gimme"), { root: process.cwd() }); + + // BAD: doesn't help if user controls root + res.sendFile(req.param("file"), { root: req.param("dir") }); }); From 0e40717358dfb11387a467425e4d37d492ae638c Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 14 Dec 2018 11:12:16 +0000 Subject: [PATCH 42/69] JS: recognize res.sendfile root option --- javascript/ql/src/semmle/javascript/Concepts.qll | 10 +++++++++- .../ql/src/semmle/javascript/frameworks/Express.qll | 4 ++++ .../javascript/security/dataflow/TaintedPath.qll | 6 +++++- .../query-tests/Security/CWE-022/TaintedPath.expected | 8 ++------ 4 files changed, 20 insertions(+), 8 deletions(-) diff --git a/javascript/ql/src/semmle/javascript/Concepts.qll b/javascript/ql/src/semmle/javascript/Concepts.qll index 53220a149789..0aff9a5904ed 100644 --- a/javascript/ql/src/semmle/javascript/Concepts.qll +++ b/javascript/ql/src/semmle/javascript/Concepts.qll @@ -28,7 +28,15 @@ abstract class FileSystemAccess extends DataFlow::Node { /** Gets an argument to this file system access that is interpreted as a path. */ abstract DataFlow::Node getAPathArgument(); - + + /** + * Gets an argument to this file system access that is interpreted as a root folder + * in which the path arguments are constrained. + * + * In other words, if a root argument is provided, the underlying file access does its own + * sanitization to prevent the path arguments from traversing outside the root folder. + */ + DataFlow::Node getRootPathArgument() { none() } } /** diff --git a/javascript/ql/src/semmle/javascript/frameworks/Express.qll b/javascript/ql/src/semmle/javascript/frameworks/Express.qll index 09ac3cdce2ef..0185849d3996 100644 --- a/javascript/ql/src/semmle/javascript/frameworks/Express.qll +++ b/javascript/ql/src/semmle/javascript/frameworks/Express.qll @@ -866,6 +866,10 @@ module Express { override DataFlow::Node getAPathArgument() { result = DataFlow::valueNode(astNode.getArgument(0)) } + + override DataFlow::Node getRootPathArgument() { + result = this.(DataFlow::CallNode).getOptionArgument(1, "root") + } } /** diff --git a/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPath.qll b/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPath.qll index a7d842281818..55e3455fdd5a 100644 --- a/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPath.qll +++ b/javascript/ql/src/semmle/javascript/security/dataflow/TaintedPath.qll @@ -71,7 +71,11 @@ module TaintedPath { */ class FsPathSink extends Sink, DataFlow::ValueNode { FsPathSink() { - this = any(FileSystemAccess fs).getAPathArgument() + exists (FileSystemAccess fs | + this = fs.getAPathArgument() and + not exists(fs.getRootPathArgument()) + or + this = fs.getRootPathArgument()) } } diff --git a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected index f3da2d2d8f9a..e7ea1b87af77 100644 --- a/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected +++ b/javascript/ql/test/query-tests/Security/CWE-022/TaintedPath.expected @@ -84,9 +84,7 @@ nodes | tainted-require.js:7:19:7:37 | req.param("module") | | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | -| tainted-sendFile.js:12:16:12:33 | req.param("gimme") | -| tainted-sendFile.js:14:16:14:33 | req.param("gimme") | -| tainted-sendFile.js:17:16:17:32 | req.param("file") | +| tainted-sendFile.js:17:43:17:58 | req.param("dir") | | views.js:1:43:1:55 | req.params[0] | edges | TaintedPath-es6.js:7:7:7:44 | path | TaintedPath-es6.js:10:41:10:44 | path | @@ -191,7 +189,5 @@ edges | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | tainted-require.js:7:19:7:37 | req.param("module") | This path depends on $@. | tainted-require.js:7:19:7:37 | req.param("module") | a user-provided value | | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:7:16:7:33 | req.param("gimme") | a user-provided value | | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:9:16:9:33 | req.param("gimme") | a user-provided value | -| tainted-sendFile.js:12:16:12:33 | req.param("gimme") | tainted-sendFile.js:12:16:12:33 | req.param("gimme") | tainted-sendFile.js:12:16:12:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:12:16:12:33 | req.param("gimme") | a user-provided value | -| tainted-sendFile.js:14:16:14:33 | req.param("gimme") | tainted-sendFile.js:14:16:14:33 | req.param("gimme") | tainted-sendFile.js:14:16:14:33 | req.param("gimme") | This path depends on $@. | tainted-sendFile.js:14:16:14:33 | req.param("gimme") | a user-provided value | -| tainted-sendFile.js:17:16:17:32 | req.param("file") | tainted-sendFile.js:17:16:17:32 | req.param("file") | tainted-sendFile.js:17:16:17:32 | req.param("file") | This path depends on $@. | tainted-sendFile.js:17:16:17:32 | req.param("file") | a user-provided value | +| tainted-sendFile.js:17:43:17:58 | req.param("dir") | tainted-sendFile.js:17:43:17:58 | req.param("dir") | tainted-sendFile.js:17:43:17:58 | req.param("dir") | This path depends on $@. | tainted-sendFile.js:17:43:17:58 | req.param("dir") | a user-provided value | | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | views.js:1:43:1:55 | req.params[0] | This path depends on $@. | views.js:1:43:1:55 | req.params[0] | a user-provided value | From f9da1dc03e8f12619fddb5425424bbd9515d2d21 Mon Sep 17 00:00:00 2001 From: Asger F Date: Fri, 14 Dec 2018 11:38:38 +0000 Subject: [PATCH 43/69] JS: add change note --- change-notes/1.20/analysis-javascript.md | 1 + 1 file changed, 1 insertion(+) diff --git a/change-notes/1.20/analysis-javascript.md b/change-notes/1.20/analysis-javascript.md index af8bb984ae8a..99601bae9fba 100644 --- a/change-notes/1.20/analysis-javascript.md +++ b/change-notes/1.20/analysis-javascript.md @@ -28,5 +28,6 @@ | Insecure randomness | More results | This rule now flags insecure uses of `crypto.pseudoRandomBytes`. | | Unused parameter | Fewer false-positive results | This rule no longer flags parameters with leading underscore. | | Unused variable, import, function or class | Fewer false-positive results | This rule now flags fewer variables that are implictly used by JSX elements, and no longer flags variables with leading underscore. | +| Uncontrolled data used in path expression | Fewer false-positive results | This rule now recognizes the Express `root` option, which prevents path traversal. | ## Changes to QL libraries From e5cbac5c13ed0c4bbbe7b6d02bd9208c70d3a869 Mon Sep 17 00:00:00 2001 From: Tom Hvitved Date: Wed, 19 Dec 2018 11:37:22 +0100 Subject: [PATCH 44/69] C#: Replace a use of `boundedFastTC` with `fastTC` --- .../semmle/code/csharp/dispatch/Dispatch.qll | 47 ++++++------------- 1 file changed, 15 insertions(+), 32 deletions(-) diff --git a/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll b/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll index b043cdb56304..80c03685e353 100644 --- a/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll +++ b/csharp/ql/src/semmle/code/csharp/dispatch/Dispatch.qll @@ -269,13 +269,6 @@ private module Internal { * types for a given expression. */ private module SimpleTypeDataFlow { - // A temporary workaround to get the right join-order in `Sink::getASource()` - private newtype ExprWrapper = TExprWrapper(Expr e) - - private Expr unwrap(ExprWrapper ew) { ew = TExprWrapper(result) } - - private ExprWrapper wrap(Expr e) { result = TExprWrapper(e) } - /** * Holds if type `t` may be imprecise, that is, an expression of type `t` may * in fact have a more precise type. @@ -321,34 +314,27 @@ private module Internal { typeMayBeImprecise(succ.getType()) } - private predicate step(ExprWrapper succ, ExprWrapper pred) { - stepExpr(unwrap(succ), unwrap(pred)) - } - - private predicate isSink(ExprWrapper ew) { - exists(Expr e | - e = unwrap(ew) | - e = any(DynamicMemberAccess dma | isSink(wrap(dma))).getQualifier() or - e = any(AccessorCall ac).getAnArgument() or - e = any(DispatchReflectionOrDynamicCall c).getArgument(_) or - e = any(MethodCall mc | mc.getTarget() = any(SystemObjectClass c).getGetTypeMethod()).getQualifier() or - e = any(DispatchCallImpl c).getQualifier() - ) - } - - private predicate stepTC(ExprWrapper succ, ExprWrapper pred) = - boundedFastTC(step/2, isSink/1)(succ, pred) + private predicate stepTC(Expr succ, Expr pred) = + fastTC(stepExpr/2)(succ, pred) private class Source extends Expr { Source() { not stepExpr(this, _) } } private class Sink extends Expr { - Sink() { isSink(wrap(this)) } - - Source getASource() { - stepTC(wrap(this), wrap(result)) + Sink() { + this = any(DynamicMemberAccess dma | dma instanceof Sink).getQualifier() + or + this = any(AccessorCall ac).getAnArgument() + or + this = any(DispatchReflectionOrDynamicCall c).getArgument(_) + or + this = any(MethodCall mc | mc.getTarget() = any(SystemObjectClass c).getGetTypeMethod()).getQualifier() + or + this = any(DispatchCallImpl c).getQualifier() } + + Source getASource() { stepTC(this, result) } } /** Holds if the expression `e` has an exact type. */ @@ -357,10 +343,7 @@ private module Internal { e instanceof BaseAccess } - /** - * Gets a source type for expression `e`, using simple data flow. The - * expression must be a member of the predicate `isSink()` above. - */ + /** Gets a source type for expression `e`, using simple data flow. */ Type getASourceType(Sink e, boolean isExact) { exists(Source s | s = e.getASource() or From a7cdf528dd616f8311c404467f74f5048216a59d Mon Sep 17 00:00:00 2001 From: calum Date: Tue, 4 Dec 2018 14:51:10 +0000 Subject: [PATCH 45/69] C#: Improve performance by mapping directly from entities to labels. --- csharp/extractor/Semmle.Extraction/Context.cs | 48 ++++++++----------- 1 file changed, 19 insertions(+), 29 deletions(-) diff --git a/csharp/extractor/Semmle.Extraction/Context.cs b/csharp/extractor/Semmle.Extraction/Context.cs index b2b3c42765f8..51593bb1a1f9 100644 --- a/csharp/extractor/Semmle.Extraction/Context.cs +++ b/csharp/extractor/Semmle.Extraction/Context.cs @@ -50,20 +50,30 @@ public SemanticModel Model(SyntaxNode node) /// true iff the label already existed. public bool GetOrAddCachedLabel(ICachedEntity entity) { - var id = GetId(entity); + // Look up the label in the entityLabelCache + if (entityLabelCache.TryGetValue(entity, out Label label)) + { + entity.Label = label; + return true; + } + + var id = entity.Id; + if (id == null) throw new InternalError("Attempt to create a null entity for {0}", entity.GetType()); - Label existingLabel; - if (labelCache.TryGetValue(id, out existingLabel)) + // Look up the Id in the idLabelCache + if (idLabelCache.TryGetValue(id, out label)) { - entity.Label = existingLabel; + entity.Label = label; + entityLabelCache[entity] = label; return true; } - entity.Label = new Label(NewId()); - DefineLabel(entity.Label, id); - labelCache[id] = entity.Label; + entity.Label = label = new Label(NewId()); + DefineLabel(label, id); + entityLabelCache[entity] = label; + idLabelCache[id] = label; return false; } @@ -90,25 +100,6 @@ public bool ExtractGenerics(ICachedEntity entity) } } - /// - /// Gets the ID belonging to cached entity . - /// - /// The ID itself is also cached, but unlike the label cache (which is used - /// to prevent reextraction/infinite loops), this is a pure performance - /// optimization. Moreover, the label cache is injective, which the ID cache - /// need not be. - /// - IId GetId(ICachedEntity entity) - { - IId id; - if (!idCache.TryGetValue(entity, out id)) - { - id = entity.Id; - idCache[entity] = id; - } - return id; - } - /// /// Creates a fresh label with ID "*", and set it on the /// supplied object. @@ -120,7 +111,8 @@ public void AddFreshLabel(IEntity entity) entity.Label = label; } - readonly Dictionary labelCache = new Dictionary(); + readonly Dictionary idLabelCache = new Dictionary(); + readonly Dictionary entityLabelCache = new Dictionary(); readonly HashSet