CERT C: Rule EXP36-C

Не бросайте указатели в более строго выровненные типы указателей

Описание

Управляйте определением

Не бросайте указатели в более строго выровненный указатель types.[1]

Реализация Polyspace

Это средство проверки проверяет на:

  • Преобразование void* указатель в указатель на объект

  • Исходный буфер неправильно выравнивается с целевым буфером

Примеры

развернуть все

Проблема

Преобразование void* указатель в указатель на объект происходит когда void* указатель преобразован в указатель на другой тип данных. Средство проверки не отмечает броски или неявные преобразования из NULL или (void*)0.

Риск

Можно косвенно преобразовать указатель на один тип данных в указатель на различный и неправильно выровненный тип данных через промежуточный void* указатель. Это средство проверки отмечает преобразования из void* указатели в указатели на другие типы и предотвращают эти косвенные преобразования.

Фиксация

Избегайте преобразований из void* указатель в указатель на другой тип данных.

Пример - преобразование из void* к int*
int *lookup (void *loc)
{
  /* ... */
  return loc; //Noncompliant   
}

void search (char *pos)
{
  int *found = lookup (pos);
}

В этом примере, lookup функция имеет void* параметр, но преобразует параметр в int* указатель при возврате. Это преобразование позволяет косвенное преобразование char* указатель передал в качестве аргумента lookup в int* указатель.

Проблема

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

  • Точки к буферу, который меньшего размера, чем, на что указывает целевой указатель.

  • Точки к буферу, который является более крупным, чем, на что указывает целевой указатель, но buffer size не является точным кратным целевой buffer size.

Выравнивание исходного указателя изменяется в этих преобразованиях.

Риск

Если выравнивание указателя изменяется в преобразовании от указателя к указателю, разыменовывание результата преобразования может вызвать аварийное завершение программы.

Фиксация

Постарайтесь не изменять выравнивание указателя в преобразовании от указателя к указателю.

Пример - изменяется в выравнивании указателя во время преобразования
#include <string.h>
struct record {
  int len;
  /* ... */
};

int copyBuffer (char *data, int offset)
{
  struct record *tmp;
  struct record dest;
  tmp = (struct record *) (data + offset);   //Noncompliant
  memcpy (&dest, tmp, sizeof (dest));
  /* ... */

  return dest.len;
}

В этом примере, char* указатель преобразован в struct record* указатель, сопровождаемый memcpy операция. memcpy операция может принять struct record* выравнивание tmp и вывод к неопределенному поведению. Средство проверки отмечает предшествующее преобразование, чтобы предотвратить это неопределенное поведение.

Чтобы избежать проблемы, используйте data + offset в качестве исходного аргумента memcpy вместо того, чтобы использовать промежуточный struct record* указатель.

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

Группа: правило 03. Выражения (EXP)
Введенный в R2019a

[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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