ПроблемаНеправильное масштабирование указателя происходит, когда вы игнорируете неявное масштабирование в адресной арифметике с указателями.
Например, дефект может произойти в этих ситуациях.
Ситуация | Риск | Возможная фиксация |
---|
Вы используете 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
/* ... */
}