Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions csharp/ql/src/semmle/code/cil/CallableReturns.qll
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,25 @@ private module Cached {
}
import Cached

pragma[noinline]
private predicate alwaysNullVariableUpdate(VariableUpdate vu) {
forex(Expr src | src = vu.getSource() | alwaysNullExpr(src))
}

/** Holds if expression `expr` always evaluates to `null`. */
private predicate alwaysNullExpr(Expr expr) {
expr instanceof NullLiteral
or
alwaysNullMethod(expr.(StaticCall).getTarget())
or
forex(VariableUpdate vu | DefUse::variableUpdateUse(_, vu, expr) | alwaysNullExpr(vu.getSource()))
forex(VariableUpdate vu | DefUse::variableUpdateUse(_, vu, expr) |
alwaysNullVariableUpdate(vu)
)
}

pragma[noinline]
private predicate alwaysNotNullVariableUpdate(VariableUpdate vu) {
forex(Expr src | src = vu.getSource() | alwaysNotNullExpr(src))
}

/** Holds if expression `expr` always evaluates to non-null. */
Expand All @@ -48,6 +60,6 @@ private predicate alwaysNotNullExpr(Expr expr) {
alwaysNotNullMethod(expr.(StaticCall).getTarget())
or
forex(VariableUpdate vu | DefUse::variableUpdateUse(_, vu, expr) |
alwaysNotNullExpr(vu.getSource())
alwaysNotNullVariableUpdate(vu)
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ predicate relevantMethod(CIL::Method m) {
or
m.getDeclaringType().getName() = "ThrowHelper"
or
m.getLocation().(CIL::Assembly).getName() = "DataFlow"
m.getLocation().(CIL::Assembly).getName().matches("DataFlow%")
}

// Check that the assembly hasn't been marked as a stub.
Expand Down
2 changes: 2 additions & 0 deletions csharp/ql/test/library-tests/cil/dataflow/DataFlow.cs_
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// Generate DataFlow.dll: `csc /o /target:library DataFlow.cs_ /out:DataFlow.dll`

using System;

namespace Dataflow
Expand Down
Binary file modified csharp/ql/test/library-tests/cil/dataflow/DataFlow.dll
100644 → 100755
Binary file not shown.
6 changes: 3 additions & 3 deletions csharp/ql/test/library-tests/cil/dataflow/DataFlow.expected
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
| 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 | ... ? ... : ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:108:20:108:33 | call to method IndirectNull |
| dataflow.cs:109:23:109:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
24 changes: 24 additions & 0 deletions csharp/ql/test/library-tests/cil/dataflow/DataFlowUnoptimized.cs_
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Generate DataFlowUnoptimized.dll: `csc /target:library DataFlowUnoptimized.cs_ /out:DataFlowUnoptimized.dll`

using System;

namespace DataflowUnoptimized
{
public class MaybeNullMethods
{
public bool cond = false;

public string MaybeNull()
{
if (cond)
return null;
else
return "not null";
}

public string MaybeNull2()
{
return cond ? null : "not null";
}
}
}
Binary file not shown.
5 changes: 5 additions & 0 deletions csharp/ql/test/library-tests/cil/dataflow/Nullness.expected
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,8 @@ alwaysNotNull
| 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 |
| dataflow.cs:95:25:95:31 | access to local variable nonNull |
| dataflow.cs:96:26:96:32 | access to local variable nonNull |
| dataflow.cs:97:32:97:73 | object creation of type MaybeNullMethods |
| dataflow.cs:98:21:98:36 | access to local variable maybeNullMethods |
| dataflow.cs:99:22:99:37 | access to local variable maybeNullMethods |
10 changes: 5 additions & 5 deletions csharp/ql/test/library-tests/cil/dataflow/TaintTracking.expected
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
| 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 | ... ? ... : ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
| dataflow.cs:102:30:102:33 | null | dataflow.cs:108:20:108:33 | call to method IndirectNull |
| dataflow.cs:109:23:109:26 | null | dataflow.cs:74:21:74:52 | ... ?? ... |
| dataflow.cs:109:23:109:26 | null | dataflow.cs:89:24:89:51 | ... ? ... : ... |
7 changes: 7 additions & 0 deletions csharp/ql/test/library-tests/cil/dataflow/dataflow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ void Nullness()
var notNull2 = nullMethods.VirtualReturnsNull();
var notNull3 = nullMethods.VirtualNullProperty;
var notNonNull = nonNull.VirtualNonNull;

// The following are maybe null
var maybeNull = nonNull.MaybeNull();
var maybeNull2 = nonNull.MaybeNull2();
var maybeNullMethods = new DataflowUnoptimized.MaybeNullMethods();
maybeNull = maybeNullMethods.MaybeNull();
maybeNull2 = maybeNullMethods.MaybeNull2();
}

object IndirectNull() => null;
Expand Down