Когда инициализируются глобальные статические константные переменные?

Я попытался найти сайт для этого вопроса, но не нашел его точно, хотя этот вопрос обсуждается много...

У меня есть это объявление в файле 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 константой.