V3171. Potentially negative value is used as the size of an array.
Анализатор обнаружил, что при создании массива в качестве значения для задания его длины может использоваться переменная или выражение, имеющие отрицательное значение.
Рассмотрим пример:
void ProcessBytes(byte[] bytes)
{
int length = BitConverter.ToUInt16(bytes, 0);
int[] newArr = new int[length - 2];
....
}
Значение, возвращаемое методом 'ToUInt16' и присваиваемое переменной 'length', может оказаться равным нулю. Это произойдёт в том случае, если первые два байта в массиве 'bytes' равны нулю. Тогда при создании массива 'newArr' в качестве его длины будет выступать отрицательное значение. Это приведёт к выбросу исключения типа 'OverflowException'.
Исправленный вариант метода 'ProcessBytes' с дополнительной проверкой может выглядеть следующим образом:
void ProcessBytes(byte[] bytes)
{
int length = BitConverter.ToUInt16(bytes, 0);
if (length < 2)
return;
int[] newArr = new int[length - 2];
....
}
Приведём ещё один пример кода. В нём при вызове метода 'SubArray' с определённым набором входных аргументов в качестве длины массива может быть использовано отрицательное значение:
public byte[] GetSubArray(byte[] bytes)
{
return bytes.SubArray(4, 2);
}
public static T[] SubArray<T>(this T[] arr, int index, int length)
{
if (length < 0)
throw new Exception($"Incorrect length value: {length}.");
if (index < 0)
throw new Exception($"Incorrect index value: {index}.");
if (arr.Length < index + length)
length = arr.Length - index;
var subArr = new T[length];
Array.Copy(arr, index, subArr, 0, length);
return subArr;
}
Проблема метода 'SubArray' заключается в том, что он не учитывает случаи, когда длина массива 'arr' может оказаться меньше значения, записанного в переменной 'index'. В этом случае переменная 'length' получит отрицательное значение. Предположим, что длина массива 'arr' равна 3, а значение переменной 'index' - 4. Переменная 'length' в ходе выполнения метода получит значение равное -1, и будет произведена попытка создания массива с отрицательным размером.
Исправленный вариант метода 'SubArray' может выглядеть следующим образом:
public static T[] SubArray<T>(this T[] arr, int index, int length)
{
if (length < 0)
throw new Exception($"Incorrect length value: {length}.");
if (index < 0 || arr.Length <= index)
throw new Exception($"Incorrect index value: {index}.");
if (arr.Length < index + length)
length = arr.Length - index;
var subArr = new T[length];
Array.Copy(arr, index, subArr, 0, length);
return subArr;
}
Данная диагностика классифицируется как: