﻿# Простая ошибка при кодировании \- не значит нестрашная ошибка

Популяризируя статический анализатор кода PVS\-Studio, мы обычно пишем статьи для программистов\. Однако, на некоторые вещи программисты смотрят одностороннее\. Именно поэтому и существуют менеджеры программных проектов, которые могут управлять процессом развития проекта направлять его в нужное русло\. Я решил написать несколько статей, целевой аудиторией которых являются менеджеры программных проектов\. Эти статьи помогут им лучше ориентироваться в вопросах использования методологии статического анализа кода\. Сейчас мы рассмотрим ложный постулат: "ошибки кодирования несущественны"\.

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

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

_Причина простая: основные баги — в алгоритмах\. В работе аналитиков, математиков, постановщиков, алгоритмистов\. А багов при кодировании — не так много\._

В общем, ничего нового\. Опять мы встречаемся с мифом, [что профессиональные разработчики не допускают простых ошибок](https://pvs-studio.ru/ru/blog/posts/0116/)\. А если и допускают, то это не страшно: такие ошибки легко найти и, как правило, они не критичные\.

Обсуждать утверждение, что профессионалы не допускают ляпов, я смысла не вижу\. Эта тема уже много раз была разобрана мною в статьях\. В конце концов, если всё так просто, почему все эти профессионалы наделали так много ошибок в известных проектах\. На данный момент, нами найдено уже более [11000 ошибок](https://pvs-studio.ru/ru/blog/examples/) в открытых проектах, хотя мы никогда не стремились выявить как можно больше ошибок\. Это просто побочный продукт написания [статей](https://pvs-studio.ru/ru/blog/inspections/)\.

Сейчас мне интереснее обсудить вот какую тему: многие программисты считают, что по\-настоящему серьезные ошибки можно допустить только при реализации алгоритмов\. Вот здесь я хочу предостеречь менеджеров \- это не так\. Любая ошибка может быть критичной\. Я не отрицаю, что ошибки в алгоритмах крайне важны, однако, не следует недооценивать важность опечаток и обыкновенных ляпов\.

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

Чтобы не быть голословным, предлагаю вам 3 примера\.

Для начала можно вспомнить критическую уязвимость в iOS, появившуюся из\-за двойного _goto_\.

```cpp
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
  goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
  goto fail;
  goto fail;
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
  goto fail;
```

Подробности изложены в статье [Apple's SSL/TLS bug](https://www.imperialviolet.org/2014/02/22/applebug.html)\. Не важно появилась эта ошибка из\-за опечатки или неудачного merge\. Явно, это "механическая" ошибка, не имеющая отношения к математике или алгоритмам\. При этом, подобная ошибка обнаруживается анализатором PVS\-Studio\.

Теперь вспомним уязвимость в MySQL: 

```cpp
char foo(...) {
  return memcmp(...);
}
```

Ошибка возникает из\-за неявного приведения типа \(_int \-\> char_\), при котором отбрасываются значения старших битов\. Это вновь ошибка, которая не имеет отношения к сложным алгоритмам и прекрасно выявляется анализатором PVS\-Studio\. Не смотря на свою простоту, ошибка приводит к тому, что на некоторых платформах в 1 случае из 256 процедура сравнения хэша с ожидаемым значением всегда возвращает значение 'true', независимо от хэша\.

Третий пример\. Я участвовал в разработке пакета численного моделирования газодинамических процессов\. Масса математики, алгоритмов и т\.д\. И, конечно, были связанные с этой математикой ошибки и проблемы\. Однако, мне намного больше запомнились проблемы, возникающие из\-за переноса кода на 64\-битные системы\. Кстати, именно тогда и зародилась идея создать анализатор Viva64, который потом развился в PVS\-Studio \(история: [как 10 лет назад начинался проект PVS\-Studio](https://pvs-studio.ru/ru/blog/posts/0465/)\)\.

Одна из ошибок была связана с неправильным позиционированием в файле с помощью функции [\_fseeki64](https://msdn.microsoft.com/en-us/library/75yw9bf3.aspx)\. Пакет моделирования, став 64\-битным, смог обрабатывать больший объем данных и, как результат, записывать данные большего объема на диск\. Вот только потом, не мог их правильно прочитать\. Причем, нельзя сказать, что код был написан как\-то уж очень плохо\. Приблизительно там было так:

```cpp
unsigned long W, H, D, DensityPos;
....
unsigned long offset = W * H * D * DensityPos;
res = _fseeki64(f, offset * sizeof(float), SEEK_SET);
```

Возникает переполнение при перемножении переменных\. В защиту программиста можно сказать, что, когда он писал этот код, сложно предположить, что в Win64 \([ILP32LL](https://pvs-studio.ru/ru/blog/terms/0019/)\) размер типа _long_ останется 32\-битным\. Эту ошибку искали очень долго\. Когда приводится вот такой псевдокод, кажется всё простым и понятным\. На практике же, очень сложно было понять, почему при превышении определенного порога объёма обрабатываемых данных, начинаются странные ошибки\. Неделю отладки легко можно было бы заменить проверкой кода с помощью PVS\-Studio, который в два счёта нашел бы описанный баг\. Алгоритмы и математика при переходе на 64\-битную систему как раз не повлекли за собой никаких сложностей\.

Как видите, простые ошибки могут приводить к серьезным последствиям\. Лучше находить их как можно больше с помощью статического анализатора, а не проводя часы и дни в отладчиках\. И уж тем более, лучше найти ошибку самим\. Худший вариант: выясняется, что ваше приложение содержит уязвимость, но оно уже инсталлировано на десятках тысяч компьютеров\.

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

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

**Дополнительные ссылки:**

1. Страница [PVS\-Studio](https://pvs-studio.ru/ru/pvs-studio/)\.
1. Мифы о статическом анализе\. [Миф первый – статический анализатор это продукт разового применения](https://pvs-studio.ru/ru/blog/posts/0115/)\.
1. Мифы о статическом анализе\. [Миф второй – профессиональные разработчики не допускают глупых ошибок](https://pvs-studio.ru/ru/blog/posts/0116/)\.
1. Мифы о статическом анализе\. [Миф третий – динамический анализ лучше чем статический](https://pvs-studio.ru/ru/blog/posts/0117/)\.
1. Мифы о статическом анализе\. [Миф четвёртый – программисты хотят добавлять свои правила в статический анализатор](https://pvs-studio.ru/ru/blog/posts/0118/)\.
1. Мифы о статическом анализе\. [Миф пятый – можно составить маленькую программу, чтобы оценить инструмент](https://pvs-studio.ru/ru/blog/posts/0119/)\.
1. В дополнении к пятому мифу: [Почему я не люблю синтетические тесты](https://pvs-studio.ru/ru/blog/posts/cpp/0471/)\.