Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Опасность использования multi-character-констант 
:(
    Опции темы
pvsstudio
Дата 27.6.2019, 12:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.1.2019

Репутация: нет
Всего: нет



Во время анализа кода, PVS-Studio выполняет анализ потока данных и оперирует значениями переменных. Значения берутся из констант или выводятся из условных выражений. Мы называем их виртуальными значениями. Недавно мы улучшали их для работы с multi-character-константами и это стало поводом для создания нового диагностического правила.

user posted image

Введение

Multi-character-литерал является implementation-defined, поэтому различные компиляторы могут кодировать эти литералы по-разному. К примеру, GCC и Clang задают значение, основываясь на порядке символов в литерале, тогда как MSVC перемещает их в зависимости от типа символа (обычный или escape).

Например, литерал 'T\x65s\x74' будет закодирован разными способами, в зависимости от компилятора. Похожую логику пришлось добавить и в анализатор. В итоге мы сделали новое диагностическое правило V1039 для выявления таких литералов в коде. Такие литералы представляют опасность в кросс-платформенных проектах, использующих несколько компиляторов для сборки.

Диагностика V1039

Рассмотрим пример. Код ниже, скомпилированный различными компиляторами, будет вести себя по-разному:

Код

#include <stdio.h>

void foo(int c)
{
  if (c == 'T\x65s\x74')                       // <= V1039
  {
    printf("Compiled with GCC or Clang.\n");
  }
  else
  {
    printf("It's another compiler (for example, MSVC).\n");
  }
}

int main(int argc, char** argv)
{
  foo('Test');
  return 0;
}


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

Для проекта, использующего определенный компилятор, это не будет заметно, однако при портировании могут возникнуть проблемы, поэтому следует заменить такие литералы простыми числовыми константами, к примеру, 'Test' поменять на 0x54657374.

Чтобы продемонстрировать разницу между компиляторами, напишем небольшую утилиту, где взяты последовательности из 3-х и 4-х символов, например, 'GHIJ' и 'GHI', и выводятся на экран их представление в памяти после компиляции.

Код утилиты:

Код

#include <stdio.h>

typedef int char_t;

void PrintBytes(const char* format, char_t lit)
{
  printf("%20s : ", format);

  const unsigned char *ptr = (const unsigned char*)&lit;
  for (int i = sizeof(lit); i--;)
  {
    printf("%c", *ptr++);
  }
  putchar('\n');
}

int main(int argc, char** argv)
{
  printf("Hex codes are: G(%02X) H(%02X) I(%02X) J(%02X)\n",'G','H','I','J');
  PrintBytes("'GHIJ'", 'GHIJ');
  PrintBytes("'\\x47\\x48\\x49\\x4A'", '\x47\x48\x49\x4A');
  PrintBytes("'G\\x48\\x49\\x4A'", 'G\x48\x49\x4A');
  PrintBytes("'GH\\x49\\x4A'", 'GH\x49\x4A');
  PrintBytes("'G\\x48I\\x4A'", 'G\x48I\x4A');
  PrintBytes("'GHI\\x4A'", 'GHI\x4A');
  PrintBytes("'GHI'", 'GHI');
  PrintBytes("'\\x47\\x48\\x49'", '\x47\x48\x49');
  PrintBytes("'GH\\x49'", 'GH\x49');
  PrintBytes("'\\x47H\\x49'", '\x47H\x49');
  PrintBytes("'\\x47HI'", '\x47HI');
  return 0;
}


Вывод утилиты, скомпилированной Visual C++:

Код

Hex codes are: G(47) H(48) I(49) J(4A)
              'GHIJ' : JIHG
  '\x47\x48\x49\x4A' : GHIJ
     'G\x48\x49\x4A' : HGIJ
        'GH\x49\x4A' : JIHG
        'G\x48I\x4A' : JIHG
           'GHI\x4A' : JIHG
               'GHI' : IHG
      '\x47\x48\x49' : GHI
            'GH\x49' : IHG
         '\x47H\x49' : HGI
            '\x47HI' : IHG


Вывод утилиты, скомпилированной GCC или Clang:

Код

Hex codes are: G(47) H(48) I(49) J(4A)
              'GHIJ' : JIHG
  '\x47\x48\x49\x4A' : JIHG
     'G\x48\x49\x4A' : JIHG
        'GH\x49\x4A' : JIHG
        'G\x48I\x4A' : JIHG
           'GHI\x4A' : JIHG
               'GHI' : IHG
      '\x47\x48\x49' : IHG
            'GH\x49' : IHG
         '\x47H\x49' : IHG
            '\x47HI' : IHG


Заключение

Диагностика V1039 добавлена в анализатор PVS-Studio версии 7.03, релиз которой недавно состоялся. Скачать последнюю версию анализатора можно на странице загрузки.

Это сообщение отредактировал(а) pvsstudio - 27.6.2019, 12:44
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Visual C++/MFC/WTL | Следующая тема »


 




[ Время генерации скрипта: 0.0978 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.