CERT C++: STR34-C

Бросьте символы к char без знака прежде, чем преобразовать в большие целочисленные размеры

Описание

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

Бросьте символы к char без знака прежде, чем преобразовать в большие целочисленные размеры. [1]

Примеры

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

Описание

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

Риск

Сравнение с EOF: Предположим, ваш компилятор реализует плоскость тип char, как подписано. В этой реализации символ с десятичной формой 255 (–1 в дополнительной форме two) хранится как значение со знаком. Когда вы преобразовываете переменную char в более широкий тип данных int, например, знаковый бит сохраняется (расширение знака). Это расширение знака приводит к символу с десятичной формой 255 преобразовываемый в целое число –1, который нельзя отличить от EOF.

Использование в качестве индекса массива: подобным обоснованием вы не можете использовать расширенные знаком простые переменные char в качестве индекса массива. Если знаковый бит сохраняется, преобразование от char до int может привести к отрицательным целым числам. Необходимо использовать положительные целочисленные значения для индекса массива.

Аргумент к обрабатывающей символ функции: подобным обоснованием вы не можете использовать расширенные знаком простые переменные char в качестве аргументов к обрабатывающим символ функциям, объявленным в ctype.h, например, isalpha() или isdigit(). Согласно стандарту C11 (Раздел 7.4), если вы предоставляете целочисленный аргумент, который не может быть представлен как unsigned char или EOF, получившееся поведение не определено.

Фиксация

Перед преобразованием в более широкий целочисленный тип данных, бросок со знаком или плоскость значение char явным образом к unsigned char.

Пример - значение расширенного символа знака по сравнению с EOF

#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

extern char parsed_token_buffer[20];

static int parser(char *buf)
{
    int c = EOF;
    if (buf && *buf) {
        c = *buf++;    
    }
    return c;
}

void func()
{
    if (parser(parsed_token_buffer) == EOF) { 
        /* Handle error */
        fatal_error();
    }
}

В этом примере функциональный parser может пересечь вход buf строки. Если символ в строке имеет десятичную форму 255, когда преобразовано в переменную int c, его значение становится –1, который неотличим от EOF. Более позднее сравнение с EOF может привести к положительной лжи.

Исправление — бросок к unsigned char перед преобразованием

Одно возможное исправление должно бросить плоскость значение char к unsigned char перед преобразованием в более широкий тип int.

#include <stdio.h>
#include <stdlib.h>
#define fatal_error() abort()

extern char parsed_token_buffer[20];

static int parser(char *buf)
{
    int c = EOF;
    if (buf && *buf) {
        c = (unsigned char)*buf++;    
    }
    return c;
}

void func()
{
    if (parser(parsed_token_buffer) == EOF) { 
        /* Handle error */
        fatal_error();
    }
}

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

Группа: 05. Символы и строки (STR)

Введенный в 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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ВЫРАЗИЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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