exponenta event banner

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

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

Описание

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

Риск

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

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

  • Усеченные или находящиеся вне диапазона целочисленные значения.

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

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

  • Несогласованные указатели или несогласованные объекты.

  • Недопустимые адреса указателей.

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

По возможности избегайте преобразования указателя в целое число или целого числа в указатель. Если требуется преобразовать 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++
По умолчанию: Откл.
Синтаксис командной строки: BAD_INT_PTR_CAST
Воздействие: среднее
CWE ID: 465, 466, 587, 758
Представлен в R2016b