V727. Return value of 'wcslen' function is not multiplied by 'sizeof(wchar_t)'


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

Когда стоит задача получения размера строки типа char, стандартным решением является использование конструкции "strlen(str) + 1". Функция strlen() вычисляет длину некой строки, а единица означает резервирование одного байта для терминального нуля. Но если речь идет о строке типа wchar_t, char16_t или char32_t, то следует не забывать умножать "длину строки + 1" на размер одного символа, то есть на 'sizeof(T)'.

Рассмотрим несколько синтетических примеров ошибок.

Пример N1:

wchar_t *str = L"Test";
size_t size = wcslen(str) + 1 * sizeof(wchar_t);

Из-за пропущенных скобок происходит умножение 'sizeof' на единицу, а затем сложение с функцией, вычисляющей длину строки. Корректный код:


size_t size = (wcslen(str) + 1) * sizeof(wchar_t);

Пример N2:

Выражение может быть записано и в другой последовательности, при которой сначала будет происходить умножение результата функции на 'sizeof', а затем сложение с единицей.


.... = malloc(sizeof(wchar_t) * wcslen(str) + 1);

Порой может случиться такая ситуация, когда программист в процессе написания вспомнил, что длину строки следует умножать на "sizeof(wchar_t)", но по привычке добавил 1. В результате памяти будет выделено на 1 байт меньше, чем необходимо.

Корректные варианты кода:


.... = malloc(wcslen(str) * sizeof(wchar_t) + 1 * sizeof(wchar_t));

.... = malloc((wcslen(str) + 1) * sizeof(wchar_t));

Согласно Common Weakness Enumeration, потенциальные ошибки, найденные с помощью этой диагностики, классифицируются как CWE-783.


Найденные ошибки

Проверено проектов
346
Собрано ошибок
13 188

А ты совершаешь ошибки в коде?

Проверь с помощью
PVS-Studio

Статический анализ
кода для C, C++, C#
и Java

goto PVS-Studio;