﻿# Как PVS\-Studio защищает от поспешных правок кода, пример N5

В статическом анализаторе кода PVS\-Studio реализован механизм символьного выполнения\. И сейчас предоставилась хорошая возможность на практике продемонстрировать, как этот механизм помогает выявлять ошибки\.

![0936_Blender_prevents_rash_code_changes_N5_ru/image1.png](https://import.viva64.com/docx/blog/0936_Blender_prevents_rash_code_changes_N5_ru/image1.png)

Каждый день [система](https://pvs-studio.ru/ru/blog/posts/cpp/0799/) для регулярного мониторинга проекта Blender присылает мне отчёт о потенциальных ошибках в новом или изменённом коде\. Описывать каждый новый баг и писать 100500 заметок про это неинтересно, но сегодня особый случай\.

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

Суть технологии символьного выполнения в том, чтобы вычислять выражения, не зная значений переменных\. Звучит таинственно, но сейчас мы разберём это на практическом примере, и всё сразу станет понятно\. Рассмотрим вот этот [коммит](https://github.com/blender/blender/commit/48014fbf1432de2ad74ef76280673062d9870af7) в проекте Blender\.

PVS\-Studio выдаёт предупреждение на 868\-ую строчку кода:

```cpp
memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
```

Анализатор считает подозрительным, что функция _memset_ на самом деле не заполняет память:

\[CWE\-628\] [V575](https://pvs-studio.ru/ru/docs/warnings/v575/): The 'memset' function processes '0' elements\. Inspect the third argument\.

Давайте разберёмся, как он пришёл к такому выводу\.

Анализатор не знает, какие числовые значения могут храниться в переменной _path\-\>len_\. Он знает про эту переменную кое\-что другое, но про это позже\.

Про переменную _i_ известно чуть больше\.

```cpp
for (int i = 0; i < path->len; i++) {
  ....
  if (i != 0) {
    ....
    memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
```

Из этого кода анализатор может извлечь следующую информацию:

1. Переменная _i_ меньше _path\-\>len_\. Это известно из анализа цикла\.
1. Переменная _i_ больше 0\. Это следует из инициализации этой переменной в цикле и последующей проверки на неравенство нулю\.

Итого, значения переменной _i_ лежат в диапазоне от 1 до _path\-\>len_\.

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

Анализатор видит, что перед вызовом функции _memset_ значение _path\-\>len_ меняется следующим образом:

```cpp
path->len = i;
if (i != 0) {
  memset(&path->ptr[i], 0, sizeof(path->ptr[i]) * (path->len - i));
```

Переменная _path\-\>len_ равна значению _i_\. Поэтому, даже не зная диапазоны возможных значений переменных, можно вычислить выражение\. Для этого анализатор делает подстановку:

```cpp
sizeof(path->ptr[i]) * (i - i)
```

И получает 0 в качестве третьего аргумента функции:

```cpp
sizeof(path->ptr[i]) * 0
```

Это явная аномалия, о чём PVS\-Studio и сообщает программистам\. Перед нами какая\-то ошибка, возникшая в процессе редактирования кода\. Прикольно, что её можно сразу выявить и исправить, если использовать инструмент статического анализа\.

**Примечание\.** Поскольку в статье приводится только маленькая часть кода, то присваивание _path\-\>len \= i_ может показаться вообще очень странным\. Ведь это означает, что цикл всегда завершается после первой итерации\. На самом деле, рассмотренный в статье фрагмент находится под условиями, и такой код имеет смысл\. Вы можете сами [изучить](https://github.com/blender/blender/commit/48014fbf1432de2ad74ef76280673062d9870af7) тело цикла целиком\.

**Предыдущие публикации:**

1. [Как PVS\-Studio защищает от поспешных правок кода, пример N4](https://pvs-studio.ru/ru/blog/posts/cpp/0924/)\.
1. [Как PVS\-Studio защищает от поспешных правок кода, пример N3](https://pvs-studio.ru/ru/blog/posts/cpp/0922/)\.
1. [Как PVS\-Studio защищает от поспешных правок кода, пример N2](https://pvs-studio.ru/ru/blog/posts/cpp/0910/)\.
1. [Как PVS\-Studio защищает от поспешных правок кода](https://pvs-studio.ru/ru/blog/posts/cpp/0817/)\.
1. [PVS\-Studio, Blender: цикл заметок о пользе регулярного использования статического анализа](https://pvs-studio.ru/ru/blog/posts/cpp/0807/)\.