ISO/IEC TS 17961 [nullref]

Удаление указателя за пределами домена

Описание

Определение правила

Удаление указателя за пределами домена.[1]

Реализация Polyspace

Эта проверка проверяет на наличие следующих проблем:

  • Небезопасная арифметика указателя.

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

  • Пустой указатель.

  • Арифметическая операция с указателем NULL.

  • Недопустимое использование стандартной стандартной программы строк библиотек.

Примеры

расширить все

Проблема

Проблема возникает, когда указатель, полученный из арифметики на операнде указателя, не обращается к элементу того же массива, что и этот операнд указателя.

Polyspace® помечает это правило во время анализа как:

Bug Finder и Code Prover проверяют это правило по-разному и могут показывать различные результаты для этого правила. В Code Prover также можно увидеть различие в результатах, основанную на вашем выборе для опции Verification level (-to) (Polyspace Code Prover). Смотрите раздел «Проверка на нарушения стандартов кодирования».

Риск

Использование недопустимого индекса массива может привести к ошибочному поведению программы. Производные от выполнения индексы массива особенно проблематичны, потому что их невозможно легко проверить путем ручного обзора или статического анализа.

Стандарт C определяет создание указателя на указатель за пределами массива. Правило разрешает использование стандарта C. Удаление указателя на указатель за пределами конца массива вызывает неопределенное поведение и является несовместимым.

Проблема

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

Риск

Использование функции библиотеки памяти с недопустимыми аргументами может привести к таким проблемам, как переполнение буфера.

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

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

См. примеры исправлений ниже.

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

Пример - Недопустимое использование стандартной памяти библиотеки Стандартной программы Ошибки
#include <string.h>
#include <stdio.h>

char* Copy_First_Six_Letters(void)
 {
  char str1[10],str2[5];

  printf("Enter string:\n");
  scanf("%s",str1);

  memcpy(str2,str1,6); 
  /* Defect: Arguments of memcpy invalid: str2 has size < 6 */

  return str2;
 }

Размер строкового str2 5, но шесть символов строки str1 копируются в str2 использование memcpy функция.

Коррекция - функция вызова с допустимыми аргументами

Одна из возможных коррекций состоит в том, чтобы настроить размер str2 так, чтобы в нем размещались символы, скопированные со memcpy функция.

#include <string.h>
#include <stdio.h>

char* Copy_First_Six_Letters(void)
 {
  /* Fix: Declare str2 with size 6 */
  char str1[10],str2[6]; 

  printf("Enter string:\n");
  scanf("%s",str1);

  memcpy(str2,str1,6);
  return str2;
 }
Проблема

Нулевой указатель возникает, когда вы используете указатель со значением NULL как если бы это указывало на допустимое место памяти.

Риск

Снятие нуля с указателя является неопределенным поведением. В большинстве реализаций dereference может привести к аварийному завершению работы вашей программы.

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

Проверьте указатель на NULL до ссоры.

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

См. примеры исправлений ниже.

Пример - Ошибка указателя NULL
#include <stdlib.h>

int FindMax(int *arr, int Size) 
{
 int* p=NULL;

 *p=arr[0];
 /* Defect: Null pointer dereference */

 for(int i=0;i<Size;i++)
  {
   if(arr[i] > (*p))
     *p=arr[i];    
  }

 return *p;
}

Указатель p инициализируется значением NULL. Однако, когда значение arr[0] записывается в *p, p принято, что указывает на допустимое место памяти.

Коррекция - Присвоение адреса нулевому указателю перед дереференцией

Одной из возможных коррекций является инициализация p с допустимым адресом памяти перед dereference.

#include <stdlib.h>

int FindMax(int *arr, int Size) 
{
 /* Fix: Assign address to null pointer */
 int* p=&arr[0];       

 for(int i=0;i<Size;i++)
  {
   if(arr[i] > (*p))
     *p=arr[i];    
  }

 return *p;
}
Проблема

Арифметическая операция с NULL-указателем происходит, когда арифметическая операция включает указатель, значение которого NULL.

Риск

Выполнение арифметики указателя на пустом указателе и разыменование результирующего указателя является неопределенным поведением. В большинстве реализаций dereference может привести к аварийному завершению работы вашей программы.

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

Проверьте указатель на NULL перед арифметическими операциями над указателем.

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

См. примеры исправлений ниже.

Пример - Арифметическая операция с ошибкой NULL-указателя
#include<stdlib.h>

int Check_Next_Value(int *loc, int val) 
 {
  int *ptr = loc, found = 0; 
  
  if (ptr==NULL)
   { 
      ptr++; 
      /* Defect: NULL pointer shifted */

      if (*ptr==val) found=1;
   } 
   
  return(found);    
 }

Когда ptr является NULL указатель, код вводит if тело оператора. Поэтому a NULL указатель сдвигается в операторе ptr++.

Коррекция - Избегайте арифметики указателя NULL

Одной из возможных коррекций является выполнение арифметической операции при ptr не NULL.

#include<stdlib.h>

int Check_Next_Value(int *loc, int val) 
 {
  int *ptr = loc, found = 0; 
  
  /* Fix: Perform operation when ptr is not NULL */
  if (ptr!=NULL)
   { 
      ptr++;

      if (*ptr==val) found=1;
   }
   
  return(found);    
 }
Проблема

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

Риск

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

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

Исправление зависит от стандартной функции библиотеки, участвующей в дефекте. В некоторых случаях можно ограничить аргументы функции перед вызовом функции. Для образца, если strcpy функция:

char * strcpy(char * destination, const char* source);
пытается скопировать слишком много байтов в целевой аргумент по сравнению с доступным буфером, ограничивает исходный аргумент перед вызовом strcpy. В некоторых случаях можно использовать альтернативную функцию, чтобы избежать ошибки. Для образца вместо strcpy, можно использовать strncpy для управления количеством скопированных байтов.

См. примеры исправлений ниже.

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

Пример - Недопустимое использование стандартной строки библиотеки Стандартной программы Ошибки
 #include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  char gbuffer[5],text[20]="ABCDEFGHIJKL";

  res=strcpy(gbuffer,text); 
  /* Error: Size of text is less than gbuffer */

  return(res);
 }

Строка text больше в размере, чем gbuffer. Поэтому функция strcpy невозможно скопировать text в gbuffer.

Коррекция - используйте допустимые аргументы

Одной из возможных коррекций является объявление строки назначения gbuffer с размером, равным или большим, чем исходная строка text.

#include <string.h>
 #include <stdio.h>
 
 char* Copy_String(void)
 {
  char *res;
  /*Fix: gbuffer has equal or larger size than text */
  char gbuffer[20],text[20]="ABCDEFGHIJKL";

  res=strcpy(gbuffer,text);

  return(res);
 }

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

Решимость: Undecidable
Введенный в R2019a

[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.