Skip to content

Commit

Permalink
C#: Add some lambda flow tests for demo
Browse files Browse the repository at this point in the history
  • Loading branch information
hvitved committed Nov 15, 2024
1 parent 1347076 commit 205a41a
Show file tree
Hide file tree
Showing 3 changed files with 256 additions and 0 deletions.
158 changes: 158 additions & 0 deletions csharp/ql/test/library-tests/dataflow/lambda/LambdaFlow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using System;

public class LambdaFlow
{
/// <summary>
/// Flow into a normal method
/// </summary>
class Ex1
{
void M1(string s)
{
Sink(s); // $ hasValueFlow=1
}

public void M2()
{
var source = Source(1);
M1(source);
}
}







/// <summary>
/// Flow into a lambda
/// </summary>
class Ex2
{
void M1(Action<string> lambda)
{
var source = Source(2);
lambda(source);
}

void M2()
{
Action<string> lambda = x => Sink(x); // $ hasValueFlow=2
M1(lambda);
}
}







/// <summary>
/// Flow out of a lambda
/// </summary>
class Ex3
{
Func<string> M1()
{
return () => Source(3);
}

void M2()
{
var lambda = M1();
Sink(lambda()); // $ hasValueFlow=3
}
}







/// <summary>
/// Flow through a lambda
/// </summary>
class Ex4
{
string M1(Func<string, string> lambda, string input)
{
return lambda(input);
}

void M2()
{
Func<string, string> id = x => x;
var source = Source(4);
var output = M1(id, source);
Sink(output); // $ hasValueFlow=4
}
}







/// <summary>
/// No flow into lambda (call context sensitivity)
/// </summary>
class Ex5
{
void M1(Action<string> lambda, string input)
{
lambda(input);
}

void M2(Action<string> lambda, string input)
{
M1(lambda, input);
}

void M3()
{
Action<string> lambda1 = arg => Sink(arg);
Action<string> lambda2 = arg => { };

var source = Source(5);
var nonSource = "non-source";

M1(lambda1, nonSource);
M1(lambda2, source);

M2(lambda1, nonSource);
M2(lambda2, source);
}
}







/// <summary>
/// Flow into a returned lambda
/// </summary>
class Ex6
{
Action<string> M1()
{
return x => Sink(x); // $ hasValueFlow=6
}

void M2()
{
var source = Source(6);
var lambda = M1();
lambda(source);
}
}

static string Source(int source) => source.ToString();

static void Sink(string value) { }
}
86 changes: 86 additions & 0 deletions csharp/ql/test/library-tests/dataflow/lambda/LambdaFlow.expected
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
models
edges
| LambdaFlow.cs:10:24:10:24 | s : String | LambdaFlow.cs:12:18:12:18 | access to parameter s | provenance | |
| LambdaFlow.cs:17:17:17:22 | access to local variable source : String | LambdaFlow.cs:18:16:18:21 | access to local variable source : String | provenance | |
| LambdaFlow.cs:17:26:17:34 | call to method Source : String | LambdaFlow.cs:17:17:17:22 | access to local variable source : String | provenance | |
| LambdaFlow.cs:18:16:18:21 | access to local variable source : String | LambdaFlow.cs:10:24:10:24 | s : String | provenance | |
| LambdaFlow.cs:33:32:33:37 | lambda [Return] : Action<String> [delegate argument at position 0] : String | LambdaFlow.cs:42:16:42:21 | [post] access to local variable lambda : Action<String> [delegate argument at position 0] : String | provenance | |
| LambdaFlow.cs:35:17:35:22 | access to local variable source : String | LambdaFlow.cs:36:20:36:25 | access to local variable source : String | provenance | |
| LambdaFlow.cs:35:26:35:34 | call to method Source : String | LambdaFlow.cs:35:17:35:22 | access to local variable source : String | provenance | |
| LambdaFlow.cs:36:13:36:18 | [post] access to parameter lambda : Action<String> [delegate argument at position 0] : String | LambdaFlow.cs:33:32:33:37 | lambda [Return] : Action<String> [delegate argument at position 0] : String | provenance | |
| LambdaFlow.cs:36:20:36:25 | access to local variable source : String | LambdaFlow.cs:36:13:36:18 | [post] access to parameter lambda : Action<String> [delegate argument at position 0] : String | provenance | |
| LambdaFlow.cs:41:37:41:37 | x : String | LambdaFlow.cs:41:47:41:47 | access to parameter x | provenance | |
| LambdaFlow.cs:42:16:42:21 | [post] access to local variable lambda : Action<String> [delegate argument at position 0] : String | LambdaFlow.cs:41:37:41:37 | x : String | provenance | |
| LambdaFlow.cs:59:20:59:34 | (...) => ... : (...) => ... [delegate return] : String | LambdaFlow.cs:64:26:64:29 | call to method M1 : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:59:26:59:34 | call to method Source : String | LambdaFlow.cs:59:20:59:34 | (...) => ... : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:64:17:64:22 | access to local variable lambda : (...) => ... [delegate return] : String | LambdaFlow.cs:65:18:65:23 | access to local variable lambda : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:64:26:64:29 | call to method M1 : (...) => ... [delegate return] : String | LambdaFlow.cs:64:17:64:22 | access to local variable lambda : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:65:18:65:23 | access to local variable lambda : (...) => ... [delegate return] : String | LambdaFlow.cs:65:18:65:25 | delegate call | provenance | |
| LambdaFlow.cs:80:40:80:45 | lambda : (...) => ... [delegate return] : String | LambdaFlow.cs:82:20:82:25 | access to parameter lambda : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:80:55:80:59 | input : String | LambdaFlow.cs:82:27:82:31 | access to parameter input : String | provenance | |
| LambdaFlow.cs:82:20:82:25 | [post] access to parameter lambda : Func<String,String> [delegate argument at position 0] : String | LambdaFlow.cs:80:40:80:45 | lambda [Return] : Func<String,String> [delegate argument at position 0] : String | provenance | |
| LambdaFlow.cs:82:20:82:25 | access to parameter lambda : (...) => ... [delegate return] : String | LambdaFlow.cs:82:20:82:32 | delegate call : String | provenance | |
| LambdaFlow.cs:82:27:82:31 | access to parameter input : String | LambdaFlow.cs:82:20:82:25 | [post] access to parameter lambda : Func<String,String> [delegate argument at position 0] : String | provenance | |
| LambdaFlow.cs:87:34:87:35 | access to local variable id : (...) => ... [delegate return] : String | LambdaFlow.cs:89:29:89:30 | access to local variable id : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:87:39:87:39 | x : String | LambdaFlow.cs:87:44:87:44 | access to parameter x : String | provenance | |
| LambdaFlow.cs:87:39:87:44 | (...) => ... : (...) => ... [delegate return] : String | LambdaFlow.cs:87:34:87:35 | access to local variable id : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:88:17:88:22 | access to local variable source : String | LambdaFlow.cs:89:33:89:38 | access to local variable source : String | provenance | |
| LambdaFlow.cs:88:26:88:34 | call to method Source : String | LambdaFlow.cs:88:17:88:22 | access to local variable source : String | provenance | |
| LambdaFlow.cs:89:17:89:22 | access to local variable output : String | LambdaFlow.cs:90:18:90:23 | access to local variable output | provenance | |
| LambdaFlow.cs:89:26:89:39 | call to method M1 : String | LambdaFlow.cs:89:17:89:22 | access to local variable output : String | provenance | |
| LambdaFlow.cs:89:29:89:30 | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String | LambdaFlow.cs:87:39:87:39 | x : String | provenance | |
| LambdaFlow.cs:89:29:89:30 | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String | LambdaFlow.cs:87:39:87:44 | (...) => ... : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:89:29:89:30 | access to local variable id : (...) => ... [delegate return] : String | LambdaFlow.cs:80:40:80:45 | lambda : (...) => ... [delegate return] : String | provenance | |
| LambdaFlow.cs:89:29:89:30 | access to local variable id : (...) => ... [delegate return] : String | LambdaFlow.cs:89:26:89:39 | call to method M1 : String | provenance | |
| LambdaFlow.cs:89:33:89:38 | access to local variable source : String | LambdaFlow.cs:80:55:80:59 | input : String | provenance | |
| LambdaFlow.cs:89:33:89:38 | access to local variable source : String | LambdaFlow.cs:89:29:89:30 | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String | provenance | |
nodes
| LambdaFlow.cs:10:24:10:24 | s : String | semmle.label | s : String |
| LambdaFlow.cs:12:18:12:18 | access to parameter s | semmle.label | access to parameter s |
| LambdaFlow.cs:17:17:17:22 | access to local variable source : String | semmle.label | access to local variable source : String |
| LambdaFlow.cs:17:26:17:34 | call to method Source : String | semmle.label | call to method Source : String |
| LambdaFlow.cs:18:16:18:21 | access to local variable source : String | semmle.label | access to local variable source : String |
| LambdaFlow.cs:33:32:33:37 | lambda [Return] : Action<String> [delegate argument at position 0] : String | semmle.label | lambda [Return] : Action<String> [delegate argument at position 0] : String |
| LambdaFlow.cs:35:17:35:22 | access to local variable source : String | semmle.label | access to local variable source : String |
| LambdaFlow.cs:35:26:35:34 | call to method Source : String | semmle.label | call to method Source : String |
| LambdaFlow.cs:36:13:36:18 | [post] access to parameter lambda : Action<String> [delegate argument at position 0] : String | semmle.label | [post] access to parameter lambda : Action<String> [delegate argument at position 0] : String |
| LambdaFlow.cs:36:20:36:25 | access to local variable source : String | semmle.label | access to local variable source : String |
| LambdaFlow.cs:41:37:41:37 | x : String | semmle.label | x : String |
| LambdaFlow.cs:41:47:41:47 | access to parameter x | semmle.label | access to parameter x |
| LambdaFlow.cs:42:16:42:21 | [post] access to local variable lambda : Action<String> [delegate argument at position 0] : String | semmle.label | [post] access to local variable lambda : Action<String> [delegate argument at position 0] : String |
| LambdaFlow.cs:59:20:59:34 | (...) => ... : (...) => ... [delegate return] : String | semmle.label | (...) => ... : (...) => ... [delegate return] : String |
| LambdaFlow.cs:59:26:59:34 | call to method Source : String | semmle.label | call to method Source : String |
| LambdaFlow.cs:64:17:64:22 | access to local variable lambda : (...) => ... [delegate return] : String | semmle.label | access to local variable lambda : (...) => ... [delegate return] : String |
| LambdaFlow.cs:64:26:64:29 | call to method M1 : (...) => ... [delegate return] : String | semmle.label | call to method M1 : (...) => ... [delegate return] : String |
| LambdaFlow.cs:65:18:65:23 | access to local variable lambda : (...) => ... [delegate return] : String | semmle.label | access to local variable lambda : (...) => ... [delegate return] : String |
| LambdaFlow.cs:65:18:65:25 | delegate call | semmle.label | delegate call |
| LambdaFlow.cs:80:40:80:45 | lambda : (...) => ... [delegate return] : String | semmle.label | lambda : (...) => ... [delegate return] : String |
| LambdaFlow.cs:80:40:80:45 | lambda [Return] : Func<String,String> [delegate argument at position 0] : String | semmle.label | lambda [Return] : Func<String,String> [delegate argument at position 0] : String |
| LambdaFlow.cs:80:55:80:59 | input : String | semmle.label | input : String |
| LambdaFlow.cs:82:20:82:25 | [post] access to parameter lambda : Func<String,String> [delegate argument at position 0] : String | semmle.label | [post] access to parameter lambda : Func<String,String> [delegate argument at position 0] : String |
| LambdaFlow.cs:82:20:82:25 | access to parameter lambda : (...) => ... [delegate return] : String | semmle.label | access to parameter lambda : (...) => ... [delegate return] : String |
| LambdaFlow.cs:82:20:82:32 | delegate call : String | semmle.label | delegate call : String |
| LambdaFlow.cs:82:27:82:31 | access to parameter input : String | semmle.label | access to parameter input : String |
| LambdaFlow.cs:87:34:87:35 | access to local variable id : (...) => ... [delegate return] : String | semmle.label | access to local variable id : (...) => ... [delegate return] : String |
| LambdaFlow.cs:87:39:87:39 | x : String | semmle.label | x : String |
| LambdaFlow.cs:87:39:87:44 | (...) => ... : (...) => ... [delegate return] : String | semmle.label | (...) => ... : (...) => ... [delegate return] : String |
| LambdaFlow.cs:87:44:87:44 | access to parameter x : String | semmle.label | access to parameter x : String |
| LambdaFlow.cs:88:17:88:22 | access to local variable source : String | semmle.label | access to local variable source : String |
| LambdaFlow.cs:88:26:88:34 | call to method Source : String | semmle.label | call to method Source : String |
| LambdaFlow.cs:89:17:89:22 | access to local variable output : String | semmle.label | access to local variable output : String |
| LambdaFlow.cs:89:26:89:39 | call to method M1 : String | semmle.label | call to method M1 : String |
| LambdaFlow.cs:89:29:89:30 | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String | semmle.label | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String |
| LambdaFlow.cs:89:29:89:30 | access to local variable id : (...) => ... [delegate return] : String | semmle.label | access to local variable id : (...) => ... [delegate return] : String |
| LambdaFlow.cs:89:33:89:38 | access to local variable source : String | semmle.label | access to local variable source : String |
| LambdaFlow.cs:90:18:90:23 | access to local variable output | semmle.label | access to local variable output |
subpaths
| LambdaFlow.cs:89:29:89:30 | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String | LambdaFlow.cs:87:39:87:39 | x : String | LambdaFlow.cs:87:44:87:44 | access to parameter x : String | LambdaFlow.cs:87:39:87:44 | (...) => ... : (...) => ... [delegate return] : String |
| LambdaFlow.cs:89:29:89:30 | access to local variable id : (...) => ... [delegate return] : String | LambdaFlow.cs:80:40:80:45 | lambda : (...) => ... [delegate return] : String | LambdaFlow.cs:82:20:82:32 | delegate call : String | LambdaFlow.cs:89:26:89:39 | call to method M1 : String |
| LambdaFlow.cs:89:33:89:38 | access to local variable source : String | LambdaFlow.cs:80:55:80:59 | input : String | LambdaFlow.cs:80:40:80:45 | lambda [Return] : Func<String,String> [delegate argument at position 0] : String | LambdaFlow.cs:89:29:89:30 | [post] access to local variable id : Func<String,String> [delegate argument at position 0] : String |
testFailures
| LambdaFlow.cs:144:34:144:52 | // ... | Missing result: hasValueFlow=6 |
#select
| LambdaFlow.cs:12:18:12:18 | access to parameter s | LambdaFlow.cs:17:26:17:34 | call to method Source : String | LambdaFlow.cs:12:18:12:18 | access to parameter s | $@ | LambdaFlow.cs:17:26:17:34 | call to method Source : String | call to method Source : String |
| LambdaFlow.cs:41:47:41:47 | access to parameter x | LambdaFlow.cs:35:26:35:34 | call to method Source : String | LambdaFlow.cs:41:47:41:47 | access to parameter x | $@ | LambdaFlow.cs:35:26:35:34 | call to method Source : String | call to method Source : String |
| LambdaFlow.cs:65:18:65:25 | delegate call | LambdaFlow.cs:59:26:59:34 | call to method Source : String | LambdaFlow.cs:65:18:65:25 | delegate call | $@ | LambdaFlow.cs:59:26:59:34 | call to method Source : String | call to method Source : String |
| LambdaFlow.cs:90:18:90:23 | access to local variable output | LambdaFlow.cs:88:26:88:34 | call to method Source : String | LambdaFlow.cs:90:18:90:23 | access to local variable output | $@ | LambdaFlow.cs:88:26:88:34 | call to method Source : String | call to method Source : String |
12 changes: 12 additions & 0 deletions csharp/ql/test/library-tests/dataflow/lambda/LambdaFlow.ql
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* @kind path-problem
*/

import csharp
import TestUtilities.InlineFlowTest
import ValueFlowTest<DefaultFlowConfig>
import PathGraph

from PathNode source, PathNode sink
where flowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()

0 comments on commit 205a41a

Please sign in to comment.