mirror of
https://github.com/github/codeql.git
synced 2025-12-17 17:23:36 +01:00
113 lines
3.3 KiB
C#
113 lines
3.3 KiB
C#
// semmle-extractor-options: --cil
|
|
|
|
using System;
|
|
|
|
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);
|
|
var f3 = Math.Max(2, 3);
|
|
var f4 = Math.Round(0.5);
|
|
var f5 = System.IO.Path.GetFullPath("tainted");
|
|
|
|
// Tainted dataflow (there is no untainted dataflow path)
|
|
int remainder;
|
|
var t1 = System.Math.DivRem(1, 2, out remainder);
|
|
|
|
// Tainted indirect call to method (there is no untainted dataflow path)
|
|
var t2 = System.Math.IEEERemainder(1.0, 2.0);
|
|
|
|
// Miscellaneous examples
|
|
var m1 = System.Math.DivRem(Math.Abs(-1), Math.Max(1, 2), out remainder);
|
|
var m2 = "tainted".ToString().Contains("t");
|
|
}
|
|
|
|
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");
|
|
|
|
// 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()
|
|
{
|
|
System.Reflection.Assembly.LoadFrom("", null, System.Configuration.Assemblies.AssemblyHashAlgorithm.SHA1); // Throws NotSupportedException
|
|
DeadCode();
|
|
}
|
|
|
|
void Throw() => throw new InvalidCastException();
|
|
|
|
void CsAlwaysThrows()
|
|
{
|
|
Throw();
|
|
DeadCode();
|
|
}
|
|
|
|
void Nullness()
|
|
{
|
|
var @null = default(object);
|
|
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 notNull1 = cond ? NullFunction() : this;
|
|
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;
|
|
|
|
bool cond;
|
|
|
|
object NullFunction()
|
|
{
|
|
object x = IndirectNull();
|
|
if (cond) x = null;
|
|
return x;
|
|
}
|
|
}
|