Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
>
>
>
C# программист, испытай себя -найди оши…

C# программист, испытай себя -найди ошибку

01 Фев 2021

Анализатор PVS-Studio регулярно пополняется новыми диагностическими правилами. Что интересно, часто диагностики обнаруживают подозрительные фрагменты кода еще до окончания всех работ. Например, в процессе тестирования на open-source проектах. Одной из подобных интересных 'находок' и хотелось бы поделиться сегодня с вами.

0792_StringBuilder_BounceCastle_ru/image1.png

Как говорилось выше, один из этапов тестирования диагностического правила - проверка его работы на реальной кодовой базе. Для этого используется набор отобранных open-source проектов, для которых проводится анализ. Очевидное преимущество такого подхода - возможность посмотреть, как ведёт себя диагностическое правило в "реальных условиях". Менее очевидное - иногда находится что-то настолько интересное, что про это и заметку не грех написать. :)

Итак, предлагаю посмотреть на код из проекта Bouncy Castle C# и найти в нём ошибку:

public static string ToString(object[] a)
{
  StringBuilder sb = new StringBuilder('[');
  if (a.Length > 0)
  {
    sb.Append(a[0]);
    for (int index = 1; index < a.Length; ++index)
    {
      sb.Append(", ").Append(a[index]);
    }
  }
  sb.Append(']');
  return sb.ToString();
}

Для тех, кто любит подглядывать, я добавил картинку, чтобы сохранить интригу.

0792_StringBuilder_BounceCastle_ru/image2.png

Уверен, многие не смогли найти ошибку без открытия IDE или документации к классу StringBuilder. Ошибка допущена при вызове конструктора:

StringBuilder sb = new StringBuilder('[');

Собственно, об этом и предупреждает статический анализатор PVS-Studio: V3165 Character literal '[' is passed as an argument of the 'Int32' type whereas similar overload with the string parameter exists. Perhaps, a string literal should be used instead. Arrays.cs 193.

Программист хотел создать экземпляр типа StringBuilder, строка в котором будет начинаться с символа '['. Однако из-за опечатки будет получен объект ёмкостью под 91 элемент, не содержащий символов.

Это произошло из-за того, что вместо двойных кавычек использовались одинарные, что привело к вызову не той перегрузки конструктора:

....
public StringBuilder(int capacity);
public StringBuilder(string? value);
....

При вызове конструктора символьный литерал '[' будет неявно приведен к соответствующему значению типа int (91 в Unicode). Это приведет к вызову конструктора с параметром типа int, задающим начальную вместимость. Программист же хотел вызвать конструктор, задающий начало строки.

Для исправления ошибки следует заменить символьный литерал на строковый (т.е. использовать "[", а не '['), что позволит вызвать правильную перегрузку конструктора.

Мы решили не ограничиваться этим паттерном и расширили случаи, которые рассматривает диагностика. В результате, кроме символьных литералов, сейчас рассматриваются и другие выражения типа char, а также, аналогично конструкторам, проверяются методы.

Диагностика, срабатывание которой было описано выше, была добавлена в релизе PVS-Studio 7.11. Вы сами можете загрузить последнюю версию анализатора и посмотреть на что способна не только диагностика V3165, но и другие диагностики для языков C, C++, C# и Java.

Кстати, идеи диагностик нам часто предлагают сами пользователи. Так получилось и в этот раз - спасибо пользователю Krypt с ресурса Habr. Если у вас также есть идеи диагностических правил - не стесняйтесь предлагать их!

P.S. В текущей кодовой базе проекта данная ошибка уже исправлена. Однако это не отменяет того факта, что какое-то время она существовала в коде, и что статический анализ позволяет выявлять подобные проблемы и исправлять их на самых ранних этапах.

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам