C中受污染的字符串

C中受污染的字符串,c,string,coverity,C,String,Coverity,我正在文件操作函数中运行Coverity工具,并得到以下错误 正如您在下面看到的,在将这个变量传递到错误消息中显示的行号之前,我使用了一个snprintf()。我猜字符串的某些清理必须作为snprintf()的一部分来完成。但警告仍然显示出来 Error:TAINTED_STRING (TAINTED string "fn" was passed to a tainted string sink content.) [coverity] char fn[100]; int id = 0; ch

我正在文件操作函数中运行Coverity工具,并得到以下错误

正如您在下面看到的,在将这个变量传递到错误消息中显示的行号之前,我使用了一个snprintf()。我猜字符串的某些清理必须作为snprintf()的一部分来完成。但警告仍然显示出来

Error:TAINTED_STRING (TAINTED string "fn" was passed to a tainted string sink content.) [coverity]

char fn[100]; int id = 0;
char* id_str = getenv("ID");
if (id_str) {
    id = atoi(id_str);
}
memset(fn, '\0', sizeof(fn));
snprintf(fn, 100, LOG_FILE, id);
if(fn[100-1] != '\0') {
     fn[100-1] = '\0';
}
log_fp = fopen (fn, "a");
任何帮助都将不胜感激。

请尝试以下方法:

char* id_str = getenv("ID");
if (id_str) {
   id_str = strdup(id_str);
   id = atoi(id_str);
   free( id_str );
}

传递给fopen的
fn
字符串被环境变量污染。使用strdup可能会起到“消毒”的作用。

错误:受污染的字符串
是一种警告,表明(就Coverity所知)行为的某些方面受到某些外部输入的影响,并且在外部输入影响执行之前未对其进行“安全性”检查

在这个特定的例子中,Coverity似乎是错误的,因为LOG_FILE的值是“/LOG/test%d.LOG”,并且与
snprintf
中的
int
一起使用,这意味着
char fn[100]
的内容总是定义良好的


因此,合理的做法是将错误标记为非问题,以便在以后的运行中忽略它。

Coverity希望确保您清理来自程序外部的任何字符串,无论是getenv、argv还是某些文件读取

您可能有一个函数来清理输入(受污染的字符串),Coverty提供了一条注释,告诉Coverty输入字符串已清理,SA警告将消失

// coverity[ +tainted_string_sanitize_content : arg-0 ]
int sanitize_mystring(char* s) 
{
    // Do some string validation
    if validated()
        return SUCCESS;
    else
        return FAILED;
}
//Coverty[+污染的字符串\u清理\u内容:arg-0]是Coverty正在查找的行


希望这有帮助。

什么是
LOG\u文件
设置为?它的“/LOG/test%d.LOG”在
LOG\u文件中没有
%d
。为什么要将
id
传递到
snprintf()
?对不起。我已经编辑了上面的回复。没有行号。哪一行?给出的答案引入了一个错误:如果
getenv(“ID”)
返回NULL,那么从手册页上可以看出
strdup
的行为是未定义的。(实际上,我的崩溃)@ Munelle解决了我的观点,但是我最好避免使用C函数,而完全支持C++ STD::字符串等。但原来的问题似乎是C所以。。。比C++ IMO更容易编写C++中的覆盖性干净代码,我猜另一点是“充当消毒”而不是实际地处理StEntEdType字符串错误。例如,如果此代码以提升的权限运行,则可能导致系统文件被打开并写入。@SimonD文件名是使用LOG\u文件字符串和“受污染”的整数生成的。我不知道你怎么能打开系统文件。你将如何解决这个问题(在C中)?啊,是的。我现在在一条评论中看到,LOG_FILE的值是“/LOG/test%d.LOG”,并且与printf中的int一起使用-之前没有正确阅读问题,而且说话太笼统。