Когда инициализируются глобальные статические константные переменные?
Я попытался найти сайт для этого вопроса, но не нашел его точно, хотя этот вопрос обсуждается много...
У меня есть это объявление в файле cpp, но не внутри любой функции:
static const char* gText = "xxxxxxxxxxx";
Хотя он имеет фиксированный размер, я получаю предупреждение от инструмента статического анализа (Klocwork), когда я пытаюсь скопировать его в другую переменную char * - о возможном нарушении вне границ:
char xText[32];
SecureZeroMemory(xText, 32);
memcpy(xText, gText, strlen(gText));
Является ли это ложным положительным или глобальная переменная инициализируется позже?
Спасибо!
Ответы
Ответ 1
Это ложный позитив. strlen
, вероятно, абстрагируется как возвращающее неизвестное положительное число, так что при анализе шаблона memcpy(dest,src,strlen(src));
анализатор не понимает, что считывающая часть копии безопасна, как только src
является хорошо сформированной строкой.
Если вы использовали strcpy
, анализатор, вероятно, заключил бы, что в этом случае все в порядке. У вас есть причина не делать этого? Функция strcpy
считается "небезопасной", но ваш memcpy(..,src,strlen(src))
тоже небезопасен.
EDIT: Кроме того, sellibitze поднимает очень хорошую точку в комментариях: атрибут const
в исходном коде применяется только к символам, указанным gText
, а не к gText
.
Ответ 2
Я бы сказал, что это не ложный позитив. Существует потенциальный риск того, что кто-то может прийти и изменить длину gText, не понимая, что не может быть более 32 символов. Я определенно поставил бы какую-то проверку перед memcpy, чтобы убедиться, что переполнение буфера не может быть.
например.
char xText[32];
SecureZeroMemory(xText, 32);
size_t lenToCopy = MIN(strlen(gText), 32);
memcpy(xText, gText, lenToCopy);
Также я заменил бы магическое число 32 константой.