Unicorn with delicious cookie
Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
V3171. Potentially negative value is...
menu mobile close menu
Проверка проектов
Дополнительная информация
toggle menu Оглавление

V3171. Potentially negative value is used as the size of an array.

21 Апр 2021

Анализатор обнаружил, что при создании массива в качестве значения для задания его длины может использоваться переменная или выражение, имеющие отрицательное значение.

Рассмотрим пример:

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;
}

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3171.