﻿# PVS\-Studio 2018: CWE, Java, RPG, macOS, Keil, IAR, MISRA

Приближается 2018 год и пора подумать о новых направлениях развития нашего статического анализатора PVS\-Studio\. Сейчас наибольший интерес для нас представляет поддержка языка Java\. Дополнительно мы рассматриваем возможность поддержки языка IBM RPG\. Не менее интересно развить анализ C, C\+\+ C\# кода в направлении выявления потенциальных уязвимостей\. Ещё нам хочется поддержать анализ C и C\+\+ кода на платформе macOS, и, наконец, доделать поддержку компиляторов от компаний Keil и IAR\. Никуда мы не денемся и от поддержки стандарта MISRA\. Перечислено много, и на всё одного 2018 года нам не хватит\. Поэтому давайте вместе с нами пообсуждаем наши планы и выберем самые приоритетные направления\.

![0547_PVS-Studio_todo_2018_ru/image1.png](https://import.viva64.com/docx/blog/0547_PVS-Studio_todo_2018_ru/image1.png)

Для начала напомню уже реализованные возможности статического анализатора кода [PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/):

* Выявление широкого спектра ошибок и потенциальных уязвимостей в коде программ на языке C, C\+\+, C\+\+/CLI, C\+\+/CX и C\#\.
* Удобная и простая интеграция с Visual Studio 2010\-2017\. Возможен автоматический анализ отдельных файлов после их перекомпиляции\.
* Запуск из командной строки для проверки всего решения: позволяет интегрировать PVS\-Studio в ночные сборки, чтобы утром у всех был свежий лог\. Как вариант, используя утилиту BlameNotifier, можно рассылать письма разработчикам об ошибках, которые PVS\-Studio нашел во время ночного прогона\.
* Отличная масштабируемость\. Поддержка многоядерных и многопроцессорных систем с настройкой количества используемых ядер\. Поддержка Incredibuild\.
* Интерактивная фильтрация результатов анализа \(лога\) в окне PVS\-Studio: по коду диагностики, по имени файла, по включению слова в текст диагностики\.
* Большое количество вариантов интеграции в проекты, разрабатываемые под Linux\.
* Mark as False Alarm – разметка в коде, чтобы не ругаться конкретной диагностикой в конкретном фрагменте файла\. Также можно использовать комментарии специального вида для подавления предупреждений, относящихся к макросам\.
* Mass Suppression – позволяет подавить все старые сообщения, чтобы анализатор выдавал 0 срабатываний\. К подавленным сообщениям всегда можно вернуться позже\. Возможность безболезненно внедрить PVS\-Studio в существующий процесс разработки и сфокусироваться на ошибках только в новом коде\.
* Автоматическая проверка на наличие новых версий PVS\-Studio \(как при работе в IDE, так и при ночных сборках\)\.
* Использование относительных путей в файлах отчета для возможности переноса отчета на другую машину\.
* CLMonitoring – проверка проектов, у которых нет файлов Visual Studio \(\.sln/\.vcxproj\); если вдруг вам не хватит функциональности CLMonitoring, то вы можете интегрировать PVS\-Studio в любую Makefile\-based систему сборки вручную\. Аналогичная утилита под Linux носит название pvs\-studio\-analyzer\.
* Возможность исключить из анализа файлы по имени, папке или маске; возможность проверять файлы, модифицированные за последние N дней\.
* Интеграция с SonarQube\. Это открытая платформа для обеспечения непрерывного контроля качества исходного кода\.
* HTML отчет в коротком и полном варианте\. Полный вариант включает в себя исходный код файлов и позволяет осуществлять по ним навигацию\.

Поддерживаемые языки и компиляторы:

* Windows\. Visual Studio 2017 C, C\+\+, C\+\+/CLI, C\+\+/CX \(WinRT\), C\#
* Windows\. Visual Studio 2015 C, C\+\+, C\+\+/CLI, C\+\+/CX \(WinRT\), C\#
* Windows\. Visual Studio 2013 C, C\+\+, C\+\+/CLI, C\+\+/CX \(WinRT\), C\#
* Windows\. Visual Studio 2012 C, C\+\+, C\+\+/CLI, C\+\+/CX \(WinRT\), C\#
* Windows\. Visual Studio 2010 C, C\+\+, C\+\+/CLI, C\#
* Windows\. MinGW C, C\+\+
* Windows/Linux\. Clang C, C\+\+
* Linux\. GCC C, C\+\+

Мы кратко перечислили то, что уже есть\. Подробности можно найти в [документации](https://pvs-studio.ru/ru/docs/)\. Теперь давайте посмотрим, что может появиться в новых версиях\.

## Потенциальные уязвимости \(weaknesses\), CWE

Анализатор PVS\-Studio уже умеет выявлять большое количество потенциальных уязвимостей \(weaknesses\)\. Скоро появится версия PVS\-Studio, где большинству предупреждений будет соответствовать тот или иной идентификатор согласно классификации [CWE](https://cwe.mitre.org/)\.

![0547_PVS-Studio_todo_2018_ru/image3.png](https://import.viva64.com/docx/blog/0547_PVS-Studio_todo_2018_ru/image3.png)

Рисунок N1\. Включен столбец CWE \(нажмите на рисунок для увеличения\)\.

Однако это только первый этап, который мы сделаем в уходящем 2017 году\. В следующем году нас ждёт более интересная работа, связанная с реализацией поиска потенциальных уязвимостей\. Мы планируем сделать несколько специализированных диагностик для C, C\+\+ и C\# в этом направлении\. Для примера, приведём описание одной из запланированных диагностик\.

Приведу описание из issues\-трекера\. 

Для начала нам надо ввести понятие "ненадёжные данные"\. Это данные, которые приходят извне\. Примеры ненадёжных данных:

* данные в буфере, прочитанные с помощью функции _fread_
* данные в буфере, полученные с помощью функции _recv_
* данные в буфере \(строке\), прочитанные с помощью _scanf\("%s", \.\.\.\)_
* целочисленная переменная, прочитанная с помощью _fscanf\("%i", \.\.\.\)_
* целочисленная переменная, прочитанная с помощью _fread\(&integer, sizeof\(int\), 1, file\)_
* целочисленная переменная, прочитанная из потока: _wcin \>\> n;_
* целочисленная переменная, полученная извне другими способами: _n \= GetFileSize\(h, x\);_
* для получения информации используются функции _GetServerVariable_, _ReadClient_ \(считывается какое\-то поле из структуры _EXTENSION\_CONTROL\_BLOCK_\)
* и так далее

Переменная/буфер считается ненадёжным источником, пока для него не выполняется какая\-то проверка значений\. Примеры проверок, делающих данные достоверными \(данные проверены и корректны\):

* _if \(n \=\= 2\)_
* _if \(strcmp\(s1, s2\) \> 0\)_
* _if \(strchr\(s1, 'c'\) \=\= 0\)_
* _if \(n \> 1 && n < 100\)_

Примечание 1\. При этом проверка на NULL для указателей не считается за проверку корректности данных:

```cpp
char s[100];
scanf("%s", s);
if (s) // Здесь мы ничего не проверили.
       // Это вообще лишний код. 's' по-прежнему недостоверный буфер.
```

Примечание 2\. Потребуется особый механизм Data Flow для массивов и структур, которого пока нет в PVS\-Studio\. Дело в том, что проверка отдельных элементов не делает достоверным весь буфер/структуру\. Пояснение:

```cpp
unsigned char B[2];
if (B[0] < 3) // Проверяем первый элемент, но не второй.
              // Второму элементу мы не можем доверять.
              // Требуется реализовать для массивов "множество
              // непроверенных/проверенных значений".
if (B[0] < 3 && B[1] < 3) // Проверили весь массив.
                          // Теперь весь массив считается достоверным.
```

Самое сложное \- подумать над вот такими проверками всего массива:

```cpp
int A[100];
...
for (i = 0; i < 100; ++i)
  if (A[i] < 10)          // проверяем весь массив
    return;
```

Когда PVS\-Studio начнёт знать о недостоверных данных, сделать диагностику, обнаруживающую их использование\. Это позволит выявлять уязвимости\. Много реальных уязвимостей связано с тем, что принятый байт/байты используются без предварительной проверки\. Под использованием понимаются, например, такие действия:

* _if \(pinter\[unsafe\_int\] \=\= 1\)_
* _malloc\(unsafe\_int \* sizeof\(float\)\)_
* _ptr \+\= unsafe\_int;_
* _if \(A\[unsafe\_buffer\[1\]\] \=\= 1\)_
* _memcpy\(a, b, unsafe\_buffer\[i\]\)_
* _buffer\_size \= 1 \+ unsafe\_int;_
* _printf\(unsafe\_buffer, 1, 2\);_
* _sprintf\(normal\_bug, unsafe\_buffer, 1, 2\);_
* и т\.д\.

Примечание 3\. Такие функции, как _strncpy_ или _\_tcsncpy\_s_ \(имеется в виду вариант функции с 3 аргументами\), могут образовывать строку без терминального нуля в конце\. Такие строки небезопасны с точки зрения применения к ним в дальнейшем функций, которые ждут на вход null\-терминальную строку\. Например, их нельзя передавать в функцию _strlen_\.

## Java

Уже пару месяцев тихо и спокойно ведётся разработка Java анализатора\. К сожалению, пока это происходит в фоновом режиме, так как на всё не хватает сил\. Рассказывать про это начинание пока рано\. Отмечу только, что для Data Flow анализа планируется использовать наработки, реализованные в ядре С\+\+ анализатора\.

Java\-анализатор взаимодействует с C\+\+ ядром при помощи Java Native Interface \(JNI\)\. Для генерации обёрток над функциями используется SWIG \(Simplified Wrapper and Interface Generator\)\. Это позволяет переиспользовать функционал C\+\+ анализатора, а также повысить производительность\.

Чтобы подогреть интерес, приведу пару ошибок, которые уже умеет выявлять PVS\-Studio в Java\-коде\.

Проект [JMonkeyEngine](https://github.com/jMonkeyEngine/jmonkeyengine)\. Предупреждение PVS\-Studio: V6004 The 'then' statement is equivalent to the 'else' statement\. VRMouseManager\.java:139, 147

```cpp
if( environment.isInVR() == false ){
  Texture tex = environment.getApplication().
                  getAssetManager().loadTexture(texture);
 mouseImage.setTexture(
   environment.getApplication().getAssetManager(),
   (Texture2D)tex, true);
 ySize = tex.getImage().getHeight();
  mouseImage.setHeight(ySize);
  mouseImage.setWidth(tex.getImage().getWidth());
  mouseImage.getMaterial().getAdditionalRenderState().
  setBlendMode(BlendMode.Alpha);
    mouseImage.getMaterial().getAdditionalRenderState().
  setDepthWrite(false);
} else {
  Texture tex = environment.getApplication().
                  getAssetManager().loadTexture(texture);
 mouseImage.setTexture(
   environment.getApplication().getAssetManager(),
   (Texture2D)tex, true);
 ySize = tex.getImage().getHeight();
  mouseImage.setHeight(ySize);
  mouseImage.setWidth(tex.getImage().getWidth());
  mouseImage.getMaterial().getAdditionalRenderState().
  setBlendMode(BlendMode.Alpha);
    mouseImage.getMaterial().getAdditionalRenderState().
  setDepthWrite(false);
}
```

В приведённом коде блоки _then_ и _else_ одинаковы\. Стоит проверить код на наличие ошибки, либо убрать дублирование\.

Проект [RxJava](https://github.com/ReactiveX/RxJava)\. Предупреждение PVS\-Studio: V6022 Expression 'idx3 \> 0' is always true\. JavadocWording\.java:865

```cpp
if (idx1 > 0 && idx2 > 0 &&
    (idx3 < 0 || (idx2 < idx3 && idx3 > 0))) {
    ....
}
```

Возможно настоящей ошибки здесь нет, но проверка _idx3 \> 0_ является избыточной\. Раз _idx2 \> 0_, и _idx2 < idx3_, то _idx3_ всегда будет больше нуля\.

## IBM RPG

Далеко не все знают, что это за язык, поэтому начнём с его краткого описания\.

IBM RPG \(Report Program Generator\) \- язык программирования, синтаксис которого был изначально сходен с командным языком механических табуляторов компании IBM\. Был разработан для облегчения перехода инженеров, обслуживавших эти табуляторы, на новую технику и переноса данных\. Первоначально был реализован для IBM 1401\. Широко использовался в 1960\-х и 1970\-х\.

![0547_PVS-Studio_todo_2018_ru/image4.jpg](https://import.viva64.com/docx/blog/0547_PVS-Studio_todo_2018_ru/image4.jpg)

Рисунок 2\. IBM 1401 \(нажмите на рисунок для увеличения\)\. См\. также [Ken Ross and Paul Laughton demo the IBM 1401](https://youtu.be/VQueCt114Gk)\.

Компания IBM продолжает поддержку языка и в настоящее время, так как на нём написан громадный объём кода, который невыгодно переводить на другие языки программирования\.

В версии RPG IV, выпущенной в 2001 году, введены элементы объектного программирования\.

Компилятор Visual RPG, разработанный сторонним производителем, обеспечивает работу под Windows и поддержку GUI\. Существуют также реализации для OpenVMS и других, более экзотических платформ\.

Подробнее о языке можно прочитать в Wikipedia: [IBM RPG](https://en.wikipedia.org/wiki/IBM_RPG)\. Плюс, мы скоро планируем написать обзорную статью про этот язык\.

Теперь надо рассказать, почему мы обратили внимание на этот язык\.

С нами связалась компания, потенциально заинтересованная в статическом анализе кода на языке RPG\. Поэтому мы решили посмотреть на этот язык, и он нас заинтересовал\. Как мы понимаем, на этом языке написано много кода, который нужно поддерживать и дописывать новые фрагменты\. При этом специалистов, знакомых с этим языком, крайне мало, что заставляет думать о дополнительных способах контроля его качества и корректности\. Именно из этого и возникает интерес к возможности статического анализа кода\.

Мы подумали, что раз в мире продолжают появляться и развиваться анализаторы для таких языков, как Cobol и Ada, то почему\-бы нам не сделать анализатор для RPG\. Тем более, что этот язык пока обделён в плане анализаторов кода\. Например, существует анализатор [SonarRPG](https://www.sonarsource.com/rpg/), но в нём реализовано только 8 диагностик для выявления ошибок\. Этого явно недостаточно\. Я уверен: мы бы смогли предложить пользователям гораздо больше интересных диагностик для выявления настоящих ошибок и опечаток\.

Мы не спешим браться за создание анализатора для IBM RPG, но решили озвучить эту тему, чтобы поискать потенциальных клиентов\. Если в вашей организации имеют дело с IBM RPG, то мы будем рады пообщаться с вами и узнать ваше мнение о перспективах разработки RPG\-анализатора\.

Если мы увидим, что к языку RPG действительно есть интерес, то в 2018 мы начнём работу в этом направлении\.

Примечание\. Анализатор IBM RPG, если такой появится, будет поставляться отдельно и иметь специальную цену \(винтаж ведь дороже стоит :\)\.

![0547_PVS-Studio_todo_2018_ru/image6.jpg](https://import.viva64.com/docx/blog/0547_PVS-Studio_todo_2018_ru/image6.jpg)

Рисунок N3\. Книги по языку RPG куплены \(нажмите на рисунок для увеличения\)\. Осталось найти героя их прочитать\.

## macOS

Предлагаем делать предзаказы и приобретать лицензии на macOS версию анализатора\.

На данный момент macOS версия не готова, но в её создании нет ничего сложного\. Нужно просто взять и сделать её\. Думаю, если этот вопрос станет актуальным, мы адаптируем PVS\-Studio для macOS в течение нескольких месяцев\. Другое дело, что пока мы не торопимся это делать\. Мы не уверены, что это более приоритетное направление, по сравнению с другими\.

Поэтому мы были бы рады продать несколько лицензий, чтобы убедиться в практическом интересе со стороны программистского сообщества\.

Нам важен именно практический интерес, а абстрактный интерес мы "уже проходили" и сделали [неудачный продукт CppCat](https://pvs-studio.ru/ru/blog/posts/0320/) :\)\. Хочется не повторять таких ошибок\.

Преимущества, которые получат клиенты, приобретя ещё неготовую PVS\-Studio:

* За цену годовой лицензии Вы сможете использовать PVS\-Studio 2 года\.
* Вы получите интеграцию именно под свою сборочную систему и окружение\.

## Keil, IAR

Компании Keil и IAR разрабатывают компиляторы для встраиваемых систем\. Время от времени нам пишут с предложением реализовать их поддержку\. Никаких препятствий нет и часть работы уже проделана\. К сожалению, не хватает ресурсов довести это до ума и протестировать\. Надеюсь, мы сможем найти время для Keil и IAR в 2018 году\.

## MISRA

До недавнего времени мы крайне узко [смотрели](https://pvs-studio.ru/ru/blog/posts/0436/) на стандарт MISRA с позиции \- как много ошибок он позволит найти\. Это неправильный подход\. Смысл таких стандартов как MISRA не в том, чтобы найти как можно больше ошибок в проекте\. Их смысл, чтобы дополнительно контролировать качество кода и предостерегать программиста от использования потенциально опасных конструкций языка\.

Например, одно из правил MISRA запрещает использовать оператор _goto_\. Если взять и попробовать применить такое правило к старому, большому, и при этом давно существующему проекту, то результатом, скорее всего, будет разочарование от такой проверки кода\. Почти наверняка, не найдется ошибок, зато придётся переписывать большое количество алгоритмов, чтобы избавиться от _goto_\. Этим можно нанести больше вреда, чем получить пользы, случайно внеся ошибки в процессе рефакторинга кода\.

Стандарт MISRA используют не так\. Приложение сразу должно писаться с учетом приведённых в стандарте правил\. Образно говоря, MISRA не способ борьбы с существующими _goto_, а способ, чтобы эти _goto_ не использовались при написании кода\.

Мы пересмотрели своё отношение к стандарту MISRA и понимаем, что он действительно необходим, хоть и не укладывается в нашу модель "взяли большой проект, запустили PVS\-Studio, нашли ошибки"\. Наши потенциальные клиенты хотят одновременно и использовать MISRA и находить опечатки, которые замечательно выявляет PVS\-Studio\.

Мы идём навстречу нашим клиентам и начали работу по поддержке стандартов MISRA C и MISRA C\+\+ в PVS\-Studio\. По умолчанию MISRA\-предупреждения будут отключены\. Мы не хотим забивать окно отчета такими сообщениями, как "нельзя использовать комментарии /\* \*/, следует использовать //"\. Однако, в любой момент набор MISRA\-диагностик можно будет включить и начать регулярно использовать\.

## Заключение

Как видите, на 2018 год у нас очень много планов\. Эта статья написана как повод начать дискуссию с нашими новыми потенциальными пользователями и узнать, что больше их интересует\. Просим проявлять активность и [писать](https://pvs-studio.ru/ru/about-feedback/) нам свои мнения по озвученным направлениям\. Особенно веским словом будут предзаказы лицензий :\)\.

![0547_PVS-Studio_todo_2018_ru/image7.png](https://import.viva64.com/docx/blog/0547_PVS-Studio_todo_2018_ru/image7.png)

Всем спасибо за внимание и заранее поздравляем с наступающим Новым 2018 годом\!