CERT C++: ARR39-C

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

Описание

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

Не добавляйте или вычитайте масштабированное целое число к указателю.[1]

Реализация Polyspace

Это средство проверки проверяет на Неправильное масштабирование указателя.

Примеры

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

Проблема

Неправильное масштабирование указателя происходит, когда вы игнорируете неявное масштабирование в адресной арифметике с указателями.

Например, дефект может произойти в этих ситуациях.

СитуацияРискВозможная фиксация
Вы используете sizeof оператор в арифметических операциях на указателе.

sizeof оператор возвращает размер типа данных в количестве байтов.

Когда вы выполняете арифметические операции на указателе, аргумент неявно масштабируется размером типа данных резкой переменной. Использование sizeof в адресной арифметике с указателями приводит к непреднамеренным результатам.

Не используйте sizeof оператор в адресной арифметике с указателями.
Вы выполняете арифметические операции на указателе, и затем применяете бросок.Неявное масштабирование в адресной арифметике с указателями зависит от типа объекта. Выполнение их масштабировало арифметику, и затем изменение типа указателя кастингом может привести к непреднамеренным результатам.Выполните адресную арифметику с указателями после операции кастинга.

Исправление

Фиксация зависит от первопричины дефекта. Часто, панель Result Details показывает последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если панель Result Details не показывает историю события, исследует первопричину дефекта путем проверки предыдущих связанных событий. См. также Интерпретируют Результаты Bug Finder в Пользовательском интерфейсе Рабочего стола Polyspace.

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

Пример — использование sizeof Оператор
#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>



enum { INTBUFSIZE = 80 };
extern int getdata (void);
int buf[INTBUFSIZE];
void foo (void)
{
  int *buf_ptr = buf;

  while (buf_ptr < (buf + sizeof (buf))) {  
    *buf_ptr++ = getdata ();
  }
}

В этом примере, операции sizeof(buf) используется для получения указателя в конец массива buf. Выход sizeof(buf) масштабируется int. Поскольку адресная арифметика с указателями неявно масштабируется, выход sizeof(buf) снова масштабируется int когда это добавляется к buf, получившийся в неожиданном поведении. Polyspace® отмечает использование sizeof оператор.

Коррекция — удаляет sizeof Оператор

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

#include <string.h>
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
#include <stdio.h>



enum { INTBUFSIZE = 80 };
extern int getdata (void);
int buf[INTBUFSIZE];
void foo (void)
{
  int *buf_ptr = buf;

  while (buf_ptr < (buf + INTBUFSIZE)) {  
    *buf_ptr++ = getdata ();
  }
}
Пример — бросок после адресной арифметики с указателями
int func(void) {
    int x = 0;
    char r = *(char *)(&x + 1);
    return r;
}

В этом примере, операции &x + 1 смещения &x sizeof(int). После операции получившийся указатель указывает вне позволенного буфера. Когда вы разыменовываете указатель, ошибка Pointer access out of bounds появляется на * операция.

Коррекция — применяет бросок перед адресной арифметикой с указателями

Если вы хотите получить доступ к второму байту x, сначала бросьте &x к char* указатель, и затем выполняет адресную арифметику с указателями. Получившийся указатель возмещен sizeof(char) байты и неподвижные точки в позволенном буфере, размером которого является sizeof(int) байты.

int func(void) {
    int x = 0;
    char r = *((char *)(&x )+ 1);
    return r;
}
Пример — использование sizeof в аргументах функции
#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
enum { WCHAR_BUF = 128 };
FILE* pFile;
//...
void func2_ko (void)
{
	wchar_t error_msg[WCHAR_BUF];
	wcscpy (error_msg, L"Error: ");
	fgetws (error_msg + wcslen (error_msg) 
	       * sizeof (wchar_t), WCHAR_BUF - 7, pFile);  //Noncompliant
}

В этом примере сообщение об ошибке читается из указателя файла pFile поток и скопированный в error_msg после смещения. Намеченным смещением здесь является wcslen(error_msg), который уже неявно масштабируется, когда это добавляется к wchar указатель error_msg. Поскольку смещение затем явным образом масштабируется снова при помощи sizeof, Polyspace отмечает неправильное масштабирование.

Коррекция — удаляет sizeof Оператор

Одна возможная коррекция должна удалить sizeof оператор.

#include <stddef.h>
#include <stdlib.h>
#include <wchar.h>
enum { WCHAR_BUF = 128 };
const wchar_t ERROR_PREFIX[8] = L"Error: ";
FILE* pFile;
//...

void func2_ok (void)
{
  const size_t prefix_len = wcslen (ERROR_PREFIX);
  wchar_t error_msg[WCHAR_BUF];
  wcscpy (error_msg, ERROR_PREFIX);
  fgetws (error_msg + prefix_len, WCHAR_BUF - prefix_len, pFile);  //Compliant
  /* ... */
}

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

Группа: 04. Контейнеры (CTR)
Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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