Это ложный позитив от Klocwork

Фон

Рассмотрим следующий код:

    template <typename T>
void WriteData(const size_t &offset, const T &data)
{
if(sizeof(data) <= 8) //if size is 64bits or less, memcpy is not as efficient as a direct write
*reinterpret_cast<T*>(reinterpret_cast<char*>(_memView) + offset) = data;
else
{
errno_t result = memcpy_s(reinterpret_cast<char*>(_memView) + offset, SHARED_BUFFER_SIZE - offset, &data, sizeof(data));
if(result != 0)
throw exception("Error writing data");
}
}

Предположим, что _memView объявлен как пустой указатель.
memcpy_s нигде не был переопределен.

Функция создается только со следующими типами: char, int, HANDLE, unsigned int, long и unsigned long. Не увязайте в других проблемах с этим фрагментом, речь идет о klocwork.

Этот шаблонный код является частью класса, и поэтому он находится в заголовочном файле.

Если мне не хватает другой подходящей информации, просто спросите.

Проблема

После анализа с помощью Klocwork я получаю предупреждение SV.BANNED.COPY: «Не используйте небезопасные функции буферного копирования — рассмотрите возможность использования безопасного варианта, такого как strcpy_s»

Итак, я делаю что-то мертвое здесь с тем, как я называю memcpy_s, memcpy_s считается небезопасным для Klocwork? Смущает ли Klocwork приведение к char * и думает, что я манипулирую строкой в ​​стиле C?

Я хотел бы понять, что Klocwork пытается сказать мне, даже если он просто говорит мне, что это ложный позитив.

1

Решение

Эта функция не работает, согласно стандарту C ++.

  • if ветки выполняют запись без выравнивания и нарушают строгое псевдонимы.

Обе ветви с радостью запишут конец вашего буфера.

  • if ветка вообще не проверяет размер.
  • else ветвь подчиняется беззнаковому переносу в расчете аргумента размера буфера.

memcpy_s не панацея С помощью memcpy и некоторые размышления о проверке параметров будут бить вслепую memcpy_s каждый раз.

Исправленная версия:

template <typename T>
void WriteData(const size_t &offset, const T &data)
{
if (sizeof data > SHARED_BUFFER_SIZE)
throw exception("Type cannot fit in shared buffer");
if (offset > SHARED_BUFFER_SIZE - sizeof data)
throw exception("Copy would overrun end of shared buffer");
memcpy(reinterpret_cast<char*>(_memView) + offset, &data, sizeof data);
}

Чтобы эффективно обрабатывать небольшие копии, убедитесь, что ваш компилятор обрабатывает memcpy как встроенный включен.

2

Другие решения


По вопросам рекламы [email protected]