CERT C: правило INT36-C

Преобразование указателя на целое число или целое число к указателю

Описание

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

Преобразование указателя на целое число или целое число к указателю. [1]

Примеры

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

Описание

Небезопасное преобразование между указателем и целым числом проверяет на указатель на целое число и целое число к преобразованиям указателей. Если вы преобразовываете между указателем, intptr_t, или uintprt_t и целочисленным типом, таким как enum, ptrdiff_t или pid_t, Polyspace повышает дефект.

Риск

Отображение между указателями и целыми числами не всегда сопоставимо со структурой обращения среды.

Преобразование от указателей до целых чисел может создать:

  • Усеченный или из целочисленных значений области значений.

  • Недопустимые целочисленные типы.

Преобразование от целых чисел до указателей может создать:

  • Неправильно выровненные указатели или неправильно выровненные объекты.

  • Адреса недопустимого указателя.

Фиксация

Где возможно, избегайте преобразования целого числа к указателю или указатель на целое число. Если вы хотите преобразовать указатель void на целое число, так, чтобы вы не изменяли значение, используйте типы:

  • C99 — intptr_t или uintptr_t

  • C90 — size_t или ssize_t

Пример - целое число к преобразованиям указателя

unsigned int *badintptrcast(void)
{
    unsigned int *ptr0 = (unsigned int *)0xdeadbeef;
    char *ptr1 = (char *)0xdeadbeef;
    return (unsigned int *)(ptr0 - (unsigned int *)ptr1);
}

В этом примере существует три преобразования, два небезопасных преобразования и одно безопасное преобразование. Первое преобразование 0xdeadbeef к unsigned int* вызывает проблемы выравнивания для указателя. Второе преобразование 0xdeadbeef к char * безопасно, потому что нет никаких проблем выравнивания для char. Третье преобразование в возврате бросает ptrdiff_t к указателю. Этот указатель может или не может указать на недопустимый адрес.

Исправление — использует intptr_t

Одно возможное исправление должно использовать типы intptr_t, чтобы сохранить адрес указателя 0xdeadbeef. Кроме того, можно изменить второй указатель на целочисленное смещение так, чтобы больше не было преобразования от ptrdiff_t до указателя.

#include <stdint.h>

unsigned int *badintptrcast(void)
{
    intptr_t iptr0 = (intptr_t)0xdeadbeef;
    int offset = 0;
    return (unsigned int *)(iptr0 - offset);
}

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

Группа: правило 04. Целые числа (INT)

Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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