Небезопасное преобразование между указателем и целым числом

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

Описание

Небезопасное преобразование между указателем и целым числом проверяет на указатель на целое число и целое число к преобразованиям указателей. Если вы преобразовываете между указателем, 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);
}

Информация о результате

Группа: Программирование
Язык: C | C++
Значение по умолчанию: 'off'
Синтаксис командной строки: BAD_INT_PTR_CAST
Влияние: носитель
ID CWE: 465, 466, 587, 758

Введенный в R2017b