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

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

CWE-839

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