Не нулевая заканчивая строка - ошибка Klockwork без понятной причины
Вопрос
Я недавно установил «Klocworks» и пытаюсь избавиться от ошибок в существующем коде. Показанная ошибка, кажется, проста. Нет нулевого при расторжении char * _p_
. Отказ Я вручную добавил нулевое прекращение (даже несмотря на то, что нет необходимости), но это не порадует Klocworks. Любые идеи?
Точное сообщение: -
Неправильно прекращенная строка 'п«вызывает переполнение буфера в п.
char *ptr;
int writtenchars = 0 ;
va_list args;
char* destStr;
if (argc != 2) {
printf(" wrong parameters number - %d instead of %d\n", argc, 2);
char str[25]="wrong parameters number ";
char *_p_; /********************************************************/
va_start(args, str);
destStr = (char*) malloc(SNMP_BUF_LEN);
_p_= destStr;
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in in function \"snmp_rebuildstringinbuf!!!\" \n");
destStr="kukuRiko";
}
else {
writtenchars = (int) vsnprintf(destStr, 4095, str, args);
if (writtenchars>SNMP_BUF_LEN) {
printf("WARNING: Too long string rebuilded in function \"snmp_rebuildstringinbuf!!!\" %d chars\n",writtenchars);
}
destStr[writtenchars] = '\0' ; //Moshe - making sure the last value of the string is null terminated in order to prevent future buffer overflows.
}
va_end(args);
/******************************************************************************/
//The KlocWork error relates to this line //
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
free (_p_);
=================================================== ========= Привет, ребята, спасибо за ваши ответы, но кажется немного более неясным, чем это. Я изыскал код до этого простого случая: - Когда код записывается все в одной функции, нет ошибок, тогда как, когда раздел распределения попадает в функцию (и текст, передаваемый в качестве параметра). Смотрите этот код: - Версия без ошибки: -
char *_p_; /*+++++++++++++++++++*/
int writtenchars = 0 ;
va_list args;
char* destStr;
char* str = "hello World";
va_start(args, str);
destStr = (char*)malloc(SNMP_BUF_LEN);
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in function \n");
}
else {
writtenchars = (int) vsnprintf(destStr, (SNMP_BUF_LEN) - 1, str, args);
}
/*+++++++++++++++++++*/
_p_ = destStr ;
if (_p_ != NULL) {
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
}
free (_p_);
/***********************************************************/
Принимая во внимание, что при прохождении кода между / * ++++ * / и упаковывая его в функцию, возвращает ошибку выше KLOCWORK.
Следовательно,
char *writingToSomeBuffer (char * str) {
int writtenchars = 0 ;
va_list args;
char* destStr;
va_start(args, str);
destStr = (char*)malloc(SNMP_BUF_LEN);
if (destStr == NULL) {
printf("WARNING: Failed to alloc memory in function \n");
}
else {
writtenchars = (int) vsnprintf(destStr, (SNMP_BUF_LEN) - 1, str, args);
}
return destStr;
}
int main () {
char *_p_;
_p_ = writingToSomeBuffer("hello world");
if (_p_ != NULL) {
logCWriteLog_msg(moduleId, level, __FILE__, __LINE__, _p_, ltrue);
}
free (_p_);
return 0 ;
}
Любые идеи?
Решение
Джонатан имеет право. Мы недавно сломали эту проверку на две семьи, которые могут объяснить его лучше:
http://www.klocworkwork.com/products/documentation/insight-9.1/checkers:nnts.might. http://www.klocwork.com/products/documentation/insight-9.1/checkers :nnts.must.nt
В настоящее время мы находимся в том, чтобы убрать это и облегчить понять. Не только проблема, но и решение.
Другие советы
Klocworkworks правильно диагностирует проблему, которую вы можете писать с нулевым указателем, если выделение памяти не удается:
_p_= destStr;
if (destStr == NULL)
{
printf("WARNING: Failed to alloc memory in in function ...\n");
destStr = "kukuRiko";
На данный момент, (ужасно названный)_p_
«Переменная все еще нулевая, но вы идете вперед и используете ее в операции печати ниже.
Также обратите внимание, что «тривиальное» исправление добавления_p_
«После этого нарушает ваше управление памятью; Вы позже сделаетеfree(_p_);
«Что приведет к ужасным проблемам, если»_p_
«Указывает на постоянную строку.
У вас также есть память в в Функция 'в сообщении. И «неправильный номер параметров» значит примерно так же, как «неправильное количество параметров», но последний является более идиоматическим английским языком. Я не уверен, что никакие восклицательные знаки полезны в сообщении об ошибке; Существует сильный аргумент, что они должны выходить за пределы двойных цитат, окружающих имя функции, даже если один из них считается желательным.
С пересмотренной версией проблемы, мне интересно, если KLOCWORK диагностирует то, что Microsoft говорит о своем vsnprintf (), что он не гарантирует нулевое завершение (которое отличается от того, что C99 и Поставка говорит).
Ошибка Klocwork в стороне, я думаю, что этот код не прав. Почему вы ограничиваете vsnprintf
до 4096, в то время как размер буфера SNMP_BUF_LEN
? Как эти два связаны друг с другом? Если SNMP_BUF_LEN
<4096, тогда вы, возможно, просто переполнили ваш буфер. Почему бы вы не пройдете SNMP_BUF_LEN
Как ограничительный аргумент в vsnprintf?
Кроме того, запись в destStr[writtenchars]
подозреваемый В зависимости от варианта vsnprintf (они варьируются), Writtenchars может быть количеством персонажей в розыске Написать, что бы снова заставило вас записать конец вашего буфера.
Что все сказано, Klocworks не идеален. У нас были макросы, которые были очень явно пытаются быть в безопасности, а Klocworks неиспользованно обнаружил их как потенциально превосходные строки. Я думаю, что это был случай Snprintf.
В целом хороший продукт, но у него есть несколько отверстий, и вы не можете исправить все это жалобы.