Files
codeql/csharp/ql/test/experimental/ir/offbyone/test.cs
2020-06-10 09:37:30 +02:00

108 lines
2.4 KiB
C#

class ContainerLengthOffByOne
{
public int[] arr;
public string str;
public static void Fun(int elem)
{
}
public void Test1()
{
int len1 = this.arr.Length;
int len2 = len1 + 1;
// OK
for(int i = 0; i < len2 - 1; i++)
{
ContainerLengthOffByOne.Fun(this.arr[i]);
}
}
public void Test2()
{
int len1 = this.arr.Length;
int len2;
if (len1 % 2 == 0)
len2 = len1 + 1;
else
len2 = len1;
// Not OK, PHI node where the upper bound
// exceeds the size of the array.
for(int i = 0; i < len2; i++)
{
ContainerLengthOffByOne.Fun(this.arr[i]);
}
}
public void Test3()
{
int len1 = this.arr.Length;
int len2 = len1 - 1;
int len3;
if (len2 % 2 == 0)
len3 = len2 + 1;
else
len3 = len2;
// OK, PHI node has bounds that ensure
// we don't get an off by one error.
for(int i = 0; i < len3; i++)
{
ContainerLengthOffByOne.Fun(this.arr[i]);
}
}
public void Test4()
{
int len1 = this.arr.Length;
int len2 = len1 + 1;
int len3 = len2 - 1;
int len4 = len3 + 2;
int len5 = len4 - 1;
// Not OK, len5 is off by one.
for(int i = 0; i < len5; i++)
{
ContainerLengthOffByOne.Fun(this.arr[i]);
}
}
public void Test5()
{
int len = this.str.Length;
// Not OK; test for indexers
for (int i = 0; i <= len; i++)
{
char c = str[i];
}
}
public void Test6()
{
int len = this.arr.Length - 2;
int len1 = len + 3;
int len2 = len1 - 1;
// Not OK, off by one
// The test shows that more complex expressions are treated correctly
for (int i = 0; i < len2; i++)
{
ContainerLengthOffByOne.Fun(this.arr[i + 1]);
}
}
public void Test7()
{
int[] arrInit = { 1, 2, 3 };
int len = (arrInit.Length * 2 + 2) / 2 * 2;
int len1 = len / 2 - 3 + 4;
// Not OK, len1 == this.arrInit + 1
// This test shows that array initializer's length
// are used in bounds
for (int i = 0; i < len1; i++)
{
ContainerLengthOffByOne.Fun(arrInit[i]);
}
}
}