CERT C++: OOP57-CPP

Предпочитайте специальные функции представителей и перегруженные операторы функциям библиотеки C Standard Library

Описание

Определение правила

Предпочитайте специальные функции представителей и перегруженные операторы функциям библиотеки C Standard Library.[1]

Реализация Polyspace

Эта проверка проверяет операции Bytewise для нетривиального объекта класса.

Примеры

расширить все

Проблема

Байтвизовые операции с нетривиальным объектом класса происходят, когда вы используете функции библиотеки C Standard для выполнения байтвизовой операции с нетривиальными или нестандартными объектами типа класса размещения. Определения тривиальных и стандартных классов размещения см. в Стандартах C++, [класс], абзацы 6 и 7 соответственно.

Проверка поднимает дефект, который вы инициализируете или копируете нетривиальные объекты типа класса, используя эти функции:

  • std::memset

  • std::memcpy

  • std::strcpy

  • std::memmove

Или при сравнении объектов типа нестандартного класса размещения с помощью этих функций:

  • std::memcmp

  • std::strcmp

Байтовые операции с нетривиальным объектом класса не поднимают никакого дефекта, если байтовая операция выполняется через псевдоним. Для примера ни один дефект не возникает при байтовом сравнении и копировании операций в этом коде. В байтовых операциях используются dptr и sptrпсевдонимы нетривиальных или нестандартных объектов класса размещения d и s.

void func(NonTrivialNonStdLayout *d, const NonTrivialNonStdLayout *s)
{
   void* dptr = (void*)d; 
   const void* sptr = (void*)s;
   // ...
   // ...
   // ...
   if (!std::memcmp(dptr, sptr, sizeof(NonTrivialNonStdLayout))) {  
     (void)std::memcpy(dptr, sptr, sizeof(NonTrivialNonStdLayout)); 
      // ...
   }
}

Риск

Выполнение операций сравнения по байту при помощи функций библиотеки C Standard на нетривиальном или нестандартном объекте типа класса размещения может привести к неожиданным значениям из-за деталей реализации. Представление объекта зависит от деталей реализации, таких как порядок частных и публичных представителей или использование таблиц указателей на виртуальные функции для представления объекта.

Выполнение операций байтовидной настройки при помощи функций библиотеки C Standard на нетривиальном или нестандартном объекте типа класса размещения может изменить детали реализации. Операция может привести к ненормальному поведению программы или уязвимости выполнения кода. Для образца, если адрес представителя функции перезаписан, вызов этой функции вызывает неожиданную функцию.

Зафиксировать

Чтобы выполнить байтовые операции, нетривиальный или нестандартный объект типа класса размещения, используйте эти специальные функции представителя C++ вместо функций библиотеки C Standard.

Функции стандартной библиотеки CПредставители C++

std::memset

Конструктор классов

std::memcpy

std::strcpy

std::memmove

Конструктор копирования классов

Конструктор перемещения классов

Оператор копирования назначения

Оператор переноса назначения

std::memcmp

std::strcmp

operator<()

operator>()

operator==()

operator!=()

Пример - Использование memset с нетривиальным объектом класса
#include <cstring>
#include <iostream>
#include <utility>

class nonTrivialClass
{
    int scalingFactor;
    int otherData;
public:
    nonTrivialClass() : scalingFactor(1) {}
    void set_other_data(int i);
    int f(int i)
    {
        return i / scalingFactor;
    }
    // ...
};

void func()
{
    nonTrivialClass c;
    // ... Code that mutates c ...
    std::memset(&c, 0, sizeof(nonTrivialClass));
    std::cout << c.f(100) << std::endl;
}

В этом примере func() использует std::memset для повторной инициализации объекта нетривиального класса c после того, как он будет впервые инициализирован его конструктором по умолчанию. Эта байтовая операция может неправильно инициализировать представление значений c.

Коррекция - задайте шаблон функции, который использует std::swap

Одной из возможных коррекций является определение шаблона функции clear() который использует std::swap для выполнения операции замены. Вызов clear()правильно инициализирует объект c путем замены содержимого c и инициализированный объект по умолчанию empty.

 #include <cstring>
#include <iostream>
#include <utility>

class nonTrivialClass
{
    int scalingFactor;
    int otherData;
public:
    nonTrivialClass() : scalingFactor(1) {}
    void set_other_data(int i);
    int f(int i)
    {
        return i / scalingFactor;
    }
    // ...
};

template <typename T>
T& clear(T& o)
{
    using std::swap;
    T empty;
    swap(o, empty);
    return o;
}

void func()
{
    nonTrivialClass c;
    // ... Code that mutates c ...

    clear(c);
    std::cout << c.f(100) << std::endl;
}

Проверяйте информацию

Группа: Правило 09. Объектно-ориентированное программирование (OOP)
Введенный в R2019b

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.