Гарантируйте, что целочисленные преобразования не приводят к потерянным или неправильно истолкованным данным
Целочисленное переполнение преобразования происходит при преобразовании целого числа в меньший целочисленный тип. Если переменная не имеет достаточного количества байтов, чтобы представлять исходное значение, переполнение преобразования.
Точное выделение ресурсов хранения для различных типов с плавающей точкой зависит от вашего процессора. Смотрите Target processor type (-target)
.
Целочисленное преобразование переполняет результата в неопределенном поведении.
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Используйте этот список событий, чтобы определить, как переменные в переполняющемся вычислении получают свои текущие значения. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Можно зафиксировать дефект:
Используя больший тип данных для результата преобразования так, чтобы все значения могли быть размещены.
Проверка значения, которые приводят к переполнению и выполнению соответствующей обработки ошибок.
В целом избегайте преобразований в меньшие целочисленные типы.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
int
до char
char convert(void) {
int num = 1000000;
return (char)num;
}
В операторе возврата целочисленная переменная num
преобразован в char
. Однако 8-битный или 16-битный символ не может представлять 1000000, потому что требуется по крайней мере 20 битов. Так переполнение операции преобразования.
Одно возможное исправление должно преобразовать в различный целочисленный тип, который может представлять целый номер.
long convert(void) { int num = 1000000; return (long)num; }
Вызов memset с непреднамеренным значением происходит, когда Polyspace® Bug Finder™ обнаруживает использование memset
или функции wmemset
с возможно неправильными аргументами.
void *memset (void *ptr, int value, size_t num)
заполняет первые байты num
блока памяти, на который указывает ptr
с заданным value
. Если аргумент value
является неправильным, блок памяти инициализируется с непреднамеренным значением.
Непреднамеренная инициализация может произойти в следующих случаях.
Проблема | Риск | Возможная фиксация |
---|---|---|
Вторым аргументом является '0' вместо 0 или '\0' . | Значением ASCII символьного '0' является 48 (десятичное число), (шестнадцатеричный) 0x30 , (восьмеричный) 069 , но не 0 (или '\0' ). | Если вы хотите инициализировать с '0' , используйте одно из значений ASCII. В противном случае используйте 0 или '\0' . |
Вторые и третьи аргументы, вероятно, инвертируются. Например, третий аргумент является литералом, и второй аргумент не является литералом. | Если порядок инвертируется, блок памяти непреднамеренного размера инициализируется с неправильными аргументами. | Инвертируйте порядок аргументов. |
Второй аргумент не может быть представлен в байте. | Если второй аргумент не может быть представлен в байте, и вы ожидаете, что каждый байт блока памяти будет заполнен тем аргументом, инициализация не происходит, как предназначено. | Примените немного маски к аргументу, чтобы привести к перенесенному или усеченному результату, который может быть представлен в байте. Когда вы применяете немного маски, убедитесь, что она производит ожидаемый результат. Например, замените |
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
#include <string.h>
#define SIZE 32
void func(void) {
char buf[SIZE];
int c = -2;
memset(buf, (char)c, sizeof(buf));
}
В этом примере (char)c
не может быть представлен в байте.
Одно возможное исправление должно применить бросок так, чтобы результат мог быть представлен в байте. Однако проверяйте, что результатом броска является приемлемое значение инициализации.
#include <string.h> #define SIZE 32 void func(void) { char buf[SIZE ]; int c = -2; memset(buf, (unsigned char)c, sizeof(buf)); }
Подпишитесь целочисленное переполнение преобразования изменения происходит при преобразовании беззнакового целого в целое число со знаком. Если переменная не имеет достаточного количества байтов, чтобы представлять и исходную константу и знаковый бит, переполнение преобразования.
Точное выделение ресурсов хранения для различных типов с плавающей точкой зависит от вашего процессора. Смотрите Target processor type (-target)
.
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
unsigned char
до char
char sign_change(void) {
unsigned char count = 255;
return (char)count;
}
В операторе возврата символьная переменная count
без знака преобразована в символ со знаком. Однако char
имеет 8 битов, 1 для знака константы и 7, чтобы представлять номер. Операция преобразования переполняется потому что 255 использования 8 битов.
Одно возможное исправление использует больший целочисленный тип. При помощи int
существует достаточно битов, чтобы представлять знак и числовое значение.
int sign_change(void) { unsigned char count = 255; return (int)count; }
Испорченное преобразование изменения знака ищет значения из небезопасных источников, которые преобразованы, неявно или явным образом, от со знаком до значений без знака.
Например, функции, которые используют size_t
в качестве аргументов неявно, преобразовывают аргумент в беззнаковое целое. Некоторые функции, которые неявно преобразовывают size_t
:
bcmp memcpy memmove strncmp strncpy calloc malloc memalign
Если вы преобразовываете маленькое отрицательное число в без знака, результатом является большое положительное число. Большое положительное число может создать уязвимости системы обеспечения безопасности. Например, если вы используете значение без знака в:
Стандартные программы емкости памяти — причины, выделяющие проблемы памяти.
Стандартные программы обработки строк — вызывают переполнение буфера.
Контуры цикла — вызывают бесконечные циклы.
Чтобы постараться не преобразовывать отрицательные величины без знака, проверяйте, что преобразовываемое значение в допустимом диапазоне. Например, если значение представляет размер, подтвердите это, значение не отрицательно и меньше, чем размер максимального значения.
#include <stdlib.h>
#include <string.h>
enum {
SIZE10 = 10,
SIZE100 = 100,
SIZE128 = 128
};
void bug_taintedsignchange(int size) {
char str[SIZE128] = "";
if (size<SIZE128) {
memset(str, 'c', size);
}
}
В этом примере буфер char
создается и заполнил использование memset
. Аргумент размера к memset
является входным параметром к функции.
Вызов memset
неявно преобразовывает size
в беззнаковое целое. Если size
является большим отрицательным числом, абсолютное значение могло бы быть слишком большим, чтобы представлять как целое число, вызвав переполнение буфера.
size
Одно возможное исправление должно проверять, ли size
в допустимой области значений. Это исправление проверяет, больше ли size
, чем нуль и меньше, чем buffer size прежде, чем вызвать memset
.
#include <stdlib.h> #include <string.h> enum { SIZE10 = 10, SIZE100 = 100, SIZE128 = 128 }; void corrected_taintedsignchange(int size) { char str[SIZE128] = ""; if (size>0 && size<SIZE128) { memset(str, 'c', size); } }
Переполнение преобразования беззнаковых целых чисел происходит при преобразовании беззнакового целого в меньший тип беззнаковых целых чисел. Если переменная не имеет достаточного количества байтов, чтобы представлять исходную константу, переполнение преобразования.
Точное выделение ресурсов хранения для различных типов с плавающей точкой зависит от вашего процессора. Смотрите Target processor type (-target)
.
Целочисленное преобразование переполняет результата в неопределенном поведении.
Фиксация зависит от первопричины дефекта. Часто детали результата показывают последовательность событий, которые привели к дефекту. Можно реализовать закрепление на любом событии в последовательности. Если детали результата не показывают историю события, можно проследить использование, щелкните правой кнопкой по опциям по исходному коду и смотрите предыдущие связанные события. См. также Интерпретируют Результаты Polyspace Bug Finder.
Можно зафиксировать дефект:
Используя больший тип данных для результата преобразования так, чтобы все значения могли быть размещены.
Проверка значения, которые приводят к переполнению и выполнению соответствующей обработки ошибок.
В целом избегайте преобразований в меньшие целочисленные типы.
Смотрите примеры мер ниже.
Если вы не хотите устранять проблему, добавьте комментарии в свой результат или код, чтобы избежать другого анализа. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.
int
до char
unsigned char convert(void) {
unsigned int unum = 1000000U;
return (unsigned char)unum;
}
В операторе возврата переменная unum
беззнаковых целых чисел преобразована в тип символов без знака. Однако преобразование переполняется, потому что 1000000 требует по крайней мере 20 битов. Стандарт языка программирования C не просматривает переполнение без знака как ошибку, потому что программа автоматически уменьшает результат модулем максимальное значение плюс 1. В этом примере unum
уменьшается 2^8
по модулю, потому что символьный тип данных может только представлять 2^8-1
.
Одно возможное исправление должно преобразовать в различный целочисленный тип, который может представлять целый номер. Например, long
.
unsigned long convert(void) { unsigned int unum = 1000000U; return (unsigned long)unum; }
Группа: правило 04. Целые числа (INT) |
[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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.
Это программное обеспечение и сопоставленная документация не были рассмотрены, ни являются подтвержденным Университетом Карнеги-Меллон или его Институтом программной инженерии.
1. Если смысл перевода понятен, то лучше оставьте как есть и не придирайтесь к словам, синонимам и тому подобному. О вкусах не спорим.
2. Не дополняйте перевод комментариями “от себя”. В исправлении не должно появляться дополнительных смыслов и комментариев, отсутствующих в оригинале. Такие правки не получится интегрировать в алгоритме автоматического перевода.
3. Сохраняйте структуру оригинального текста - например, не разбивайте одно предложение на два.
4. Не имеет смысла однотипное исправление перевода какого-то термина во всех предложениях. Исправляйте только в одном месте. Когда Вашу правку одобрят, это исправление будет алгоритмически распространено и на другие части документации.
5. По иным вопросам, например если надо исправить заблокированное для перевода слово, обратитесь к редакторам через форму технической поддержки.