mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
C#: Fix bug in dataflow library.
This commit is contained in:
@@ -44,7 +44,8 @@ private class ThrowingCall extends NonReturningCall {
|
||||
exists(CIL::Method m, CIL::Type ex |
|
||||
this.getTarget().matchesHandle(m) and
|
||||
alwaysThrowsException(m, ex) and
|
||||
c.getExceptionClass().matchesHandle(ex)
|
||||
c.getExceptionClass().matchesHandle(ex) and
|
||||
not m.isVirtual()
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -646,7 +646,7 @@ module DataFlow {
|
||||
sourceDecl.matchesHandle(result.(Callable))
|
||||
or
|
||||
// CIL callable without C# implementation in the database
|
||||
not sourceDecl.matchesHandle(any(Callable k)) and
|
||||
not sourceDecl.matchesHandle(any(Callable k | k.hasBody())) and
|
||||
result = sourceDecl
|
||||
else
|
||||
// C# callable without C# implementation in the database
|
||||
@@ -1188,7 +1188,7 @@ module DataFlow {
|
||||
* nodes that may potentially be reached in flow from some source to some
|
||||
* sink.
|
||||
*/
|
||||
private module Pruning {
|
||||
module Pruning {
|
||||
/**
|
||||
* Holds if `node` is reachable from a source in the configuration `config`,
|
||||
* ignoring call contexts.
|
||||
|
||||
@@ -7,35 +7,53 @@ private import cil
|
||||
private import semmle.code.csharp.dataflow.Nullness
|
||||
private import semmle.code.cil.CallableReturns as CR
|
||||
|
||||
private predicate finalCallable(Callable c) {
|
||||
not c.(Virtualizable).isVirtual() and
|
||||
not exists(DeclarationWithGetSetAccessors p | c = p.getAnAccessor() and p.isVirtual())
|
||||
}
|
||||
|
||||
/** Holds if callable `c` always returns null. */
|
||||
predicate alwaysNullCallable(Callable c) {
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
|
||||
finalCallable(c) and
|
||||
(
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof AlwaysNullExpr)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if callable `c` always returns a non-null value. */
|
||||
predicate alwaysNotNullCallable(Callable c) {
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNotNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
|
||||
finalCallable(c) and
|
||||
(
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysNotNullMethod(m))
|
||||
or
|
||||
forex(Expr e | c.canReturn(e) | e instanceof NonNullExpr)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if callable 'c' always throws an exception. */
|
||||
predicate alwaysThrowsCallable(Callable c) {
|
||||
forex(ControlFlow::Node pre | pre = c.getExitPoint().getAPredecessor() |
|
||||
pre.getElement() instanceof ThrowElement
|
||||
finalCallable(c) and
|
||||
(
|
||||
forex(ControlFlow::Node pre | pre = c.getExitPoint().getAPredecessor() |
|
||||
pre.getElement() instanceof ThrowElement
|
||||
)
|
||||
or
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysThrowsMethod(m))
|
||||
)
|
||||
or
|
||||
exists(CIL::Method m | m.matchesHandle(c) | CR::alwaysThrowsMethod(m))
|
||||
}
|
||||
|
||||
/** Holds if callable `c` always throws exception `ex`. */
|
||||
predicate alwaysThrowsException(Callable c, Class ex) {
|
||||
forex(ControlFlow::Node pre | pre = c.getExitPoint().getAPredecessor() |
|
||||
pre.getElement().(ThrowElement).getThrownExceptionType() = ex
|
||||
finalCallable(c) and
|
||||
(
|
||||
forex(ControlFlow::Node pre | pre = c.getExitPoint().getAPredecessor() |
|
||||
pre.getElement().(ThrowElement).getThrownExceptionType() = ex
|
||||
)
|
||||
or
|
||||
exists(CIL::Method m, CIL::Type t | m.matchesHandle(c) |
|
||||
CR::alwaysThrowsException(m, t) and t.matchesHandle(ex)
|
||||
)
|
||||
)
|
||||
or
|
||||
exists(CIL::Method m, CIL::Type t | m.matchesHandle(c) | CR::alwaysThrowsException(m, t) and t.matchesHandle(ex))
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,11 @@
|
||||
stubs
|
||||
alwaysNull
|
||||
| System.Object Dataflow.NullMethods.ReturnsNull2() | 0: ldarg.0, 1: call Dataflow.NullMethods.ReturnsNull, 2: ret |
|
||||
| System.Object Dataflow.NullMethods.ReturnsNull() | 0: ldnull, 1: ret |
|
||||
| System.Object Dataflow.NullMethods.ReturnsNullIndirect() | 0: ldarg.0, 1: call Dataflow.NullMethods.ReturnsNull, 2: ret |
|
||||
| System.Object Dataflow.NullMethods.VirtualReturnsNull() | 0: ldnull, 1: ret |
|
||||
| System.Object Dataflow.NullMethods.get_NullProperty() | 0: ldnull, 1: ret |
|
||||
| System.Object Dataflow.NullMethods.get_VirtualNullProperty() | 0: ldnull, 1: ret |
|
||||
| System.Object System.Collections.EmptyReadOnlyDictionaryInternal.get_Item(System.Object) | 0: ldarg.1, 1: brtrue.s 6:, 2: ldstr "key", 3: call System.SR.get_ArgumentNull_Key, 4: newobj System.ArgumentNullException..ctor, 5: throw, 6: ldnull, 7: ret |
|
||||
alwaysNonNull
|
||||
| System.ArgumentException System.ThrowHelper.GetAddingDuplicateWithKeyArgumentException(System.Object) |
|
||||
@@ -11,6 +18,12 @@ alwaysNonNull
|
||||
| System.ArgumentOutOfRangeException System.ThrowHelper.GetArgumentOutOfRangeException(System.ExceptionArgument,System.Int32,System.ExceptionResource) |
|
||||
| System.Exception System.ThrowHelper.GetArraySegmentCtorValidationFailedException(System.Array,System.Int32,System.Int32) |
|
||||
| System.InvalidOperationException System.ThrowHelper.GetInvalidOperationException(System.ExceptionResource) |
|
||||
| System.Object Dataflow.NonNullMethods.ReturnsNonNull2() |
|
||||
| System.Object Dataflow.NonNullMethods.ReturnsNonNull() |
|
||||
| System.Object Dataflow.NonNullMethods.ReturnsNonNullIndirect() |
|
||||
| System.Object Dataflow.NonNullMethods.get_VirtualNonNull() |
|
||||
| System.Object Dataflow.NonNullMethods.get_VirtualNonNullProperty() |
|
||||
| System.String Dataflow.NonNullMethods.get_NonNullProperty2() |
|
||||
| System.Text.Encoder System.Text.ASCIIEncoding.GetEncoder() |
|
||||
| System.Text.Encoder System.Text.Encoding.GetEncoder() |
|
||||
| System.Text.Encoder System.Text.EncodingNLS.GetEncoder() |
|
||||
@@ -20,6 +33,10 @@ alwaysNonNull
|
||||
| System.Text.Encoder System.Text.UTF32Encoding.GetEncoder() |
|
||||
| System.Text.Encoder System.Text.UnicodeEncoding.GetEncoder() |
|
||||
alwaysThrows
|
||||
| System.Object Dataflow.ThrowingMethods.AlwaysThrows() | System.InvalidOperationException | 0: newobj System.InvalidOperationException..ctor, 1: throw |
|
||||
| System.Object Dataflow.ThrowingMethods.VirtualThrows() | System.Exception | 0: newobj System.Exception..ctor, 1: throw |
|
||||
| System.Object Dataflow.ThrowingMethods.get_ThrowProperty() | System.Exception | 0: newobj System.Exception..ctor, 1: throw |
|
||||
| System.Object Dataflow.ThrowingMethods.get_VirtualThrowProperty() | System.Exception | 0: newobj System.Exception..ctor, 1: throw |
|
||||
| System.Object System.ValueTuple.get_Item(System.Int32) | System.IndexOutOfRangeException | 0: newobj System.IndexOutOfRangeException..ctor, 1: throw |
|
||||
| System.Void System.ThrowHelper.ThrowAddingDuplicateWithKeyArgumentException(System.Object) | System.ArgumentException | 0: ldarg.0, 1: call System.ThrowHelper.GetAddingDuplicateWithKeyArgumentException, 2: throw |
|
||||
| System.Void System.ThrowHelper.ThrowAggregateException(System.Collections.Generic.List<System.Exception>) | System.AggregateException | 0: ldarg.0, 1: newobj System.AggregateException..ctor, 2: throw |
|
||||
|
||||
@@ -7,6 +7,13 @@ predicate relevantMethod(CIL::Method m) {
|
||||
m.getName() = "get_Item"
|
||||
or
|
||||
m.getDeclaringType().getName() = "ThrowHelper"
|
||||
or
|
||||
m.getLocation().(CIL::Assembly).getName() = "DataFlow"
|
||||
}
|
||||
|
||||
// Check that the assembly hasn't been marked as a stub.
|
||||
query predicate stubs(string str) {
|
||||
exists(CIL::Assembly asm | CIL::assemblyIsStub(asm) | str = asm.toString())
|
||||
}
|
||||
|
||||
query predicate alwaysNull(string s, string d) {
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| dataflow.cs:41:9:41:18 | call to method DeadCode |
|
||||
| dataflow.cs:49:9:49:18 | call to method DeadCode |
|
||||
| dataflow.cs:57:9:57:18 | call to method DeadCode |
|
||||
| dataflow.cs:65:9:65:18 | call to method DeadCode |
|
||||
|
||||
176
csharp/ql/test/library-tests/cil/dataflow/DataFlow.cs_
Normal file
176
csharp/ql/test/library-tests/cil/dataflow/DataFlow.cs_
Normal file
@@ -0,0 +1,176 @@
|
||||
using System;
|
||||
|
||||
namespace Dataflow
|
||||
{
|
||||
public class NullMethods
|
||||
{
|
||||
public object ReturnsNull() => null;
|
||||
|
||||
public object ReturnsNull2()
|
||||
{
|
||||
var x = ReturnsNull();
|
||||
return x;
|
||||
}
|
||||
|
||||
// Does not necessarily return null because of virtual method call.
|
||||
public object NotReturnsNull() => VirtualReturnsNull();
|
||||
|
||||
public object ReturnsNullIndirect() => ReturnsNull();
|
||||
|
||||
public virtual object VirtualReturnsNull() => null;
|
||||
|
||||
public object NullProperty { get => null; }
|
||||
|
||||
public virtual object VirtualNullProperty { get => null; }
|
||||
}
|
||||
|
||||
public class NonNullMethods
|
||||
{
|
||||
public object ReturnsNonNull() => new object();
|
||||
|
||||
public object ReturnsNonNull2()
|
||||
{
|
||||
var x = ReturnsNonNull();
|
||||
return x;
|
||||
}
|
||||
|
||||
public object ReturnsNonNullIndirect() => ReturnsNonNull();
|
||||
|
||||
public object NonNullProperty { get => 1; }
|
||||
|
||||
public string NonNullProperty2 { get => "not null"; }
|
||||
|
||||
public virtual object VirtualNonNull { get => "not null"; }
|
||||
|
||||
public bool cond = false;
|
||||
|
||||
public string MaybeNull()
|
||||
{
|
||||
if (cond)
|
||||
return null;
|
||||
else
|
||||
return "not null";
|
||||
}
|
||||
|
||||
public string MaybeNull2()
|
||||
{
|
||||
return cond ? null : "not null";
|
||||
}
|
||||
|
||||
public virtual object VirtualNonNullProperty { get => "non null"; }
|
||||
}
|
||||
|
||||
public class ThrowingMethods
|
||||
{
|
||||
public static object AlwaysThrows() => throw new InvalidOperationException();
|
||||
|
||||
public object AlwaysThrowsIndirect() => AlwaysThrows();
|
||||
|
||||
public virtual object VirtualThrows() => throw new Exception();
|
||||
|
||||
public object ThrowProperty { get => throw new Exception(); }
|
||||
public virtual object VirtualThrowProperty { get => throw new Exception(); }
|
||||
|
||||
}
|
||||
|
||||
public class DataFlow
|
||||
{
|
||||
public object Taint1(object x) => x;
|
||||
|
||||
public object Taint2(object x) => Taint5(x);
|
||||
|
||||
public string Taint3(string s)
|
||||
{
|
||||
var x = s;
|
||||
Console.WriteLine(s);
|
||||
return x;
|
||||
}
|
||||
|
||||
public object Taint5(object x) => Taint6(x);
|
||||
|
||||
private object Taint6(object x) => x;
|
||||
}
|
||||
|
||||
public class TaintFlow
|
||||
{
|
||||
public string Taint1(string a, string b) => a + b;
|
||||
|
||||
public int Taint2(int a, int b) => a + b;
|
||||
|
||||
public int Taint3(int a) => -a;
|
||||
|
||||
public string TaintIndirect(string a, string b) => Taint1(a, b);
|
||||
}
|
||||
|
||||
public class Properties
|
||||
{
|
||||
public int TrivialProperty1 { get; set; }
|
||||
|
||||
int field;
|
||||
|
||||
public int TrivialProperty2
|
||||
{
|
||||
get => field;
|
||||
set { field = value; }
|
||||
}
|
||||
}
|
||||
|
||||
public class ThisAssemblyIsNotAStub
|
||||
{
|
||||
public void F()
|
||||
{
|
||||
// Ensure that the assembly isn't tagged as a stub
|
||||
// Need to bump the average instruction count.
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
Console.WriteLine("This is not a stub assembly");
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
csharp/ql/test/library-tests/cil/dataflow/DataFlow.dll
Normal file
BIN
csharp/ql/test/library-tests/cil/dataflow/DataFlow.dll
Normal file
Binary file not shown.
@@ -1,10 +1,17 @@
|
||||
| dataflow.cs:16:18:16:26 | "tainted" | dataflow.cs:16:18:16:37 | call to method ToString |
|
||||
| dataflow.cs:17:27:17:28 | 12 | dataflow.cs:17:18:17:29 | call to method Abs |
|
||||
| dataflow.cs:18:27:18:27 | 2 | dataflow.cs:18:18:18:31 | call to method Max |
|
||||
| dataflow.cs:18:30:18:30 | 3 | dataflow.cs:18:18:18:31 | call to method Max |
|
||||
| dataflow.cs:20:45:20:53 | "tainted" | dataflow.cs:20:18:20:54 | call to method GetFullPath |
|
||||
| dataflow.cs:27:44:27:46 | 1 | dataflow.cs:27:18:27:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:27:49:27:51 | 2 | dataflow.cs:27:18:27:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:64:30:64:33 | null | dataflow.cs:61:23:61:50 | ... ? ... : ... |
|
||||
| dataflow.cs:64:30:64:33 | null | dataflow.cs:70:20:70:33 | call to method IndirectNull |
|
||||
| dataflow.cs:71:23:71:26 | null | dataflow.cs:61:23:61:50 | ... ? ... : ... |
|
||||
| dataflow.cs:18:18:18:26 | "tainted" | dataflow.cs:18:18:18:37 | call to method ToString |
|
||||
| dataflow.cs:19:27:19:28 | 12 | dataflow.cs:19:18:19:29 | call to method Abs |
|
||||
| dataflow.cs:20:27:20:27 | 2 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:20:30:20:30 | 3 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:22:45:22:53 | "tainted" | dataflow.cs:22:18:22:54 | call to method GetFullPath |
|
||||
| dataflow.cs:29:44:29:46 | 1 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:29:49:29:51 | 2 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:40:34:40:37 | "d1" | dataflow.cs:40:18:40:38 | call to method Taint1 |
|
||||
| dataflow.cs:41:34:41:37 | "d2" | dataflow.cs:41:18:41:38 | call to method Taint2 |
|
||||
| dataflow.cs:42:34:42:37 | "d3" | dataflow.cs:42:18:42:38 | call to method Taint3 |
|
||||
| dataflow.cs:46:28:46:32 | "t1a" | dataflow.cs:46:18:46:40 | call to method Taint1 |
|
||||
| dataflow.cs:46:35:46:39 | "t1b" | dataflow.cs:46:18:46:40 | call to method Taint1 |
|
||||
| dataflow.cs:49:35:49:38 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
|
||||
| dataflow.cs:49:41:49:44 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
|
||||
| dataflow.cs:95:30:95:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
|
||||
| dataflow.cs:95:30:95:33 | null | dataflow.cs:101:20:101:33 | call to method IndirectNull |
|
||||
| dataflow.cs:102:23:102:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import csharp
|
||||
import semmle.code.csharp.dataflow.DataFlow::DataFlow
|
||||
|
||||
// import DataFlow::PathGraph
|
||||
|
||||
class FlowConfig extends Configuration {
|
||||
FlowConfig() { this = "FlowConfig" }
|
||||
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
alwaysNull
|
||||
| dataflow.cs:54:21:54:35 | default(...) |
|
||||
| dataflow.cs:56:27:56:56 | access to property DeclaringMethod |
|
||||
| dataflow.cs:58:39:58:52 | call to method IndirectNull |
|
||||
| dataflow.cs:70:21:70:35 | default(...) |
|
||||
| dataflow.cs:74:39:74:52 | call to method IndirectNull |
|
||||
| dataflow.cs:78:21:78:45 | call to method ReturnsNull |
|
||||
| dataflow.cs:79:21:79:46 | call to method ReturnsNull2 |
|
||||
| dataflow.cs:80:21:80:44 | access to property NullProperty |
|
||||
alwaysNotNull
|
||||
| dataflow.cs:55:23:55:34 | default(...) |
|
||||
| dataflow.cs:56:27:56:30 | this access |
|
||||
| dataflow.cs:56:27:56:40 | call to method GetType |
|
||||
| dataflow.cs:57:30:57:33 | true |
|
||||
| dataflow.cs:57:30:57:44 | call to method ToString |
|
||||
| dataflow.cs:58:21:58:34 | this access |
|
||||
| dataflow.cs:58:39:58:52 | this access |
|
||||
| dataflow.cs:61:23:61:26 | this access |
|
||||
| dataflow.cs:61:30:61:43 | this access |
|
||||
| dataflow.cs:61:47:61:50 | this access |
|
||||
| dataflow.cs:71:24:71:35 | default(...) |
|
||||
| dataflow.cs:72:27:72:30 | this access |
|
||||
| dataflow.cs:72:27:72:40 | call to method GetType |
|
||||
| dataflow.cs:73:30:73:33 | true |
|
||||
| dataflow.cs:73:30:73:44 | call to method ToString |
|
||||
| dataflow.cs:74:21:74:34 | this access |
|
||||
| dataflow.cs:74:39:74:52 | this access |
|
||||
| dataflow.cs:77:27:77:52 | object creation of type NullMethods |
|
||||
| dataflow.cs:78:21:78:31 | access to local variable nullMethods |
|
||||
| dataflow.cs:79:21:79:31 | access to local variable nullMethods |
|
||||
| dataflow.cs:80:21:80:31 | access to local variable nullMethods |
|
||||
| dataflow.cs:83:23:83:51 | object creation of type NonNullMethods |
|
||||
| dataflow.cs:84:24:84:30 | access to local variable nonNull |
|
||||
| dataflow.cs:84:24:84:47 | call to method ReturnsNonNull |
|
||||
| dataflow.cs:85:24:85:30 | access to local variable nonNull |
|
||||
| dataflow.cs:85:24:85:55 | call to method ReturnsNonNullIndirect |
|
||||
| dataflow.cs:86:24:86:30 | access to local variable nonNull |
|
||||
| dataflow.cs:89:24:89:27 | this access |
|
||||
| dataflow.cs:89:31:89:44 | this access |
|
||||
| dataflow.cs:89:48:89:51 | this access |
|
||||
| dataflow.cs:90:24:90:34 | access to local variable nullMethods |
|
||||
| dataflow.cs:91:24:91:34 | access to local variable nullMethods |
|
||||
| dataflow.cs:92:26:92:32 | access to local variable nonNull |
|
||||
|
||||
@@ -1,18 +1,28 @@
|
||||
| dataflow.cs:12:18:12:22 | "123" | dataflow.cs:12:18:12:37 | call to method CompareTo |
|
||||
| dataflow.cs:12:34:12:36 | "b" | dataflow.cs:12:18:12:37 | call to method CompareTo |
|
||||
| dataflow.cs:16:18:16:26 | "tainted" | dataflow.cs:16:18:16:37 | call to method ToString |
|
||||
| dataflow.cs:17:27:17:28 | 12 | dataflow.cs:17:18:17:29 | call to method Abs |
|
||||
| dataflow.cs:18:27:18:27 | 2 | dataflow.cs:18:18:18:31 | call to method Max |
|
||||
| dataflow.cs:18:30:18:30 | 3 | dataflow.cs:18:18:18:31 | call to method Max |
|
||||
| dataflow.cs:20:45:20:53 | "tainted" | dataflow.cs:20:18:20:54 | call to method GetFullPath |
|
||||
| dataflow.cs:24:37:24:37 | 1 | dataflow.cs:24:18:24:56 | call to method DivRem |
|
||||
| dataflow.cs:24:40:24:40 | 2 | dataflow.cs:24:18:24:56 | call to method DivRem |
|
||||
| dataflow.cs:27:44:27:46 | 1 | dataflow.cs:27:18:27:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:27:49:27:51 | 2 | dataflow.cs:27:18:27:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:30:60:30:60 | 1 | dataflow.cs:30:18:30:80 | call to method DivRem |
|
||||
| dataflow.cs:30:63:30:63 | 2 | dataflow.cs:30:18:30:80 | call to method DivRem |
|
||||
| dataflow.cs:64:30:64:33 | null | dataflow.cs:58:21:58:52 | ... ?? ... |
|
||||
| dataflow.cs:64:30:64:33 | null | dataflow.cs:61:23:61:50 | ... ? ... : ... |
|
||||
| dataflow.cs:64:30:64:33 | null | dataflow.cs:70:20:70:33 | call to method IndirectNull |
|
||||
| dataflow.cs:71:23:71:26 | null | dataflow.cs:58:21:58:52 | ... ?? ... |
|
||||
| dataflow.cs:71:23:71:26 | null | dataflow.cs:61:23:61:50 | ... ? ... : ... |
|
||||
| dataflow.cs:11:18:11:22 | "123" | dataflow.cs:11:18:11:37 | call to method CompareTo |
|
||||
| dataflow.cs:11:34:11:36 | "b" | dataflow.cs:11:18:11:37 | call to method CompareTo |
|
||||
| dataflow.cs:18:18:18:26 | "tainted" | dataflow.cs:18:18:18:37 | call to method ToString |
|
||||
| dataflow.cs:19:27:19:28 | 12 | dataflow.cs:19:18:19:29 | call to method Abs |
|
||||
| dataflow.cs:20:27:20:27 | 2 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:20:30:20:30 | 3 | dataflow.cs:20:18:20:31 | call to method Max |
|
||||
| dataflow.cs:22:45:22:53 | "tainted" | dataflow.cs:22:18:22:54 | call to method GetFullPath |
|
||||
| dataflow.cs:26:37:26:37 | 1 | dataflow.cs:26:18:26:56 | call to method DivRem |
|
||||
| dataflow.cs:26:40:26:40 | 2 | dataflow.cs:26:18:26:56 | call to method DivRem |
|
||||
| dataflow.cs:29:44:29:46 | 1 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:29:49:29:51 | 2 | dataflow.cs:29:18:29:52 | call to method IEEERemainder |
|
||||
| dataflow.cs:32:60:32:60 | 1 | dataflow.cs:32:18:32:80 | call to method DivRem |
|
||||
| dataflow.cs:32:63:32:63 | 2 | dataflow.cs:32:18:32:80 | call to method DivRem |
|
||||
| dataflow.cs:40:34:40:37 | "d1" | dataflow.cs:40:18:40:38 | call to method Taint1 |
|
||||
| dataflow.cs:41:34:41:37 | "d2" | dataflow.cs:41:18:41:38 | call to method Taint2 |
|
||||
| dataflow.cs:42:34:42:37 | "d3" | dataflow.cs:42:18:42:38 | call to method Taint3 |
|
||||
| dataflow.cs:46:28:46:32 | "t1a" | dataflow.cs:46:18:46:40 | call to method Taint1 |
|
||||
| dataflow.cs:46:35:46:39 | "t1b" | dataflow.cs:46:18:46:40 | call to method Taint1 |
|
||||
| dataflow.cs:47:28:47:28 | 2 | dataflow.cs:47:18:47:32 | call to method Taint2 |
|
||||
| dataflow.cs:47:31:47:31 | 3 | dataflow.cs:47:18:47:32 | call to method Taint2 |
|
||||
| dataflow.cs:48:28:48:28 | 1 | dataflow.cs:48:18:48:29 | call to method Taint3 |
|
||||
| dataflow.cs:49:35:49:38 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
|
||||
| dataflow.cs:49:41:49:44 | "t6" | dataflow.cs:49:18:49:45 | call to method TaintIndirect |
|
||||
| dataflow.cs:95:30:95:33 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
|
||||
| dataflow.cs:95:30:95:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
|
||||
| dataflow.cs:95:30:95:33 | null | dataflow.cs:101:20:101:33 | call to method IndirectNull |
|
||||
| dataflow.cs:102:23:102:26 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
|
||||
| dataflow.cs:102:23:102:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
| Dataflow.Properties.TrivialProperty1 |
|
||||
| Dataflow.Properties.TrivialProperty2 |
|
||||
| System.Collections.DictionaryEntry.Key |
|
||||
| System.Collections.DictionaryEntry.Value |
|
||||
| System.Reflection.AssemblyName.CodeBase |
|
||||
|
||||
@@ -5,4 +5,6 @@ where
|
||||
prop.getDeclaringType().hasQualifiedName("System.Reflection.AssemblyName")
|
||||
or
|
||||
prop.getDeclaringType().hasQualifiedName("System.Collections.DictionaryEntry")
|
||||
or
|
||||
prop.getDeclaringType().hasQualifiedName("Dataflow.Properties")
|
||||
select prop.getQualifiedName()
|
||||
|
||||
@@ -6,12 +6,14 @@ class Test
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
|
||||
// Indirect call to method
|
||||
var c1 = "abc".Contains("a"); // Calls string.IndexOf()
|
||||
var c2 = "123".CompareTo("b"); // Calls string.Compare()
|
||||
var c3 = Tuple.Create("c", "d", "e"); // Calls Tuple constructor
|
||||
|
||||
}
|
||||
|
||||
void DataFlowThroughFramework()
|
||||
{
|
||||
// Dataflow through call
|
||||
var f1 = "tainted".ToString();
|
||||
var f2 = Math.Abs(12);
|
||||
@@ -31,13 +33,27 @@ class Test
|
||||
var m2 = "tainted".ToString().Contains("t");
|
||||
}
|
||||
|
||||
void DeadCode() { }
|
||||
void DataFlowThroughAssembly()
|
||||
{
|
||||
// Dataflow through test assembly
|
||||
var dataflow = new Dataflow.DataFlow();
|
||||
var d1 = dataflow.Taint1("d1");
|
||||
var d2 = dataflow.Taint2("d2");
|
||||
var d3 = dataflow.Taint3("d3");
|
||||
|
||||
System.Reflection.Assembly assembly;
|
||||
// Taint tracking
|
||||
var tt = new Dataflow.TaintFlow();
|
||||
var t1 = tt.Taint1("t1a", "t1b");
|
||||
var t2 = tt.Taint2(2, 3);
|
||||
var t3 = tt.Taint3(1);
|
||||
var t4 = tt.TaintIndirect("t6", "t6");
|
||||
}
|
||||
|
||||
void DeadCode() { }
|
||||
|
||||
void CilAlwaysThrows()
|
||||
{
|
||||
assembly.GetModules(true); // Throws NotImplementedException
|
||||
System.Reflection.Assembly.LoadFrom("", null, System.Configuration.Assemblies.AssemblyHashAlgorithm.SHA1); // Throws NotSupportedException
|
||||
DeadCode();
|
||||
}
|
||||
|
||||
@@ -52,13 +68,28 @@ class Test
|
||||
void Nullness()
|
||||
{
|
||||
var @null = default(object);
|
||||
var nonNull = default(int);
|
||||
var nonNull1 = default(int);
|
||||
var nullFromCil = this.GetType().DeclaringMethod;
|
||||
var nonNullFromCil = true.ToString();
|
||||
var null2 = NullFunction() ?? IndirectNull();
|
||||
|
||||
// Null from dataflow assembly
|
||||
var nullMethods = new Dataflow.NullMethods();
|
||||
var null3 = nullMethods.ReturnsNull(); // Null
|
||||
var null4 = nullMethods.ReturnsNull2();
|
||||
var null5 = nullMethods.NullProperty;
|
||||
|
||||
// NotNull
|
||||
var nonNull = new Dataflow.NonNullMethods();
|
||||
var nonNull2 = nonNull.ReturnsNonNull();
|
||||
var nonNull3 = nonNull.ReturnsNonNullIndirect();
|
||||
var nonNull4 = nonNull.NonNullProperty;
|
||||
|
||||
// The following are not always null:
|
||||
var notNull = cond ? NullFunction() : this;
|
||||
var notNull1 = cond ? NullFunction() : this;
|
||||
var notNull2 = nullMethods.VirtualReturnsNull();
|
||||
var notNull3 = nullMethods.VirtualNullProperty;
|
||||
var notNonNull = nonNull.VirtualNonNull;
|
||||
}
|
||||
|
||||
object IndirectNull() => null;
|
||||
|
||||
Reference in New Issue
Block a user