我正在尝试分析项目合作伙伴编写的函数,以弄清楚为什么它会给我造成堆缓冲区溢出。我已经通过valgrind和cppcheck进行了测试,但是它们并没有使我更加接近。
该函数旨在解析字符串并提取值进行排序。要处理的特殊情况是空值,以及带有逗号的电影标题。 (由于我们正在解析CSV文件,因此如果数据中包含逗号,则需要对数据进行不同的处理。)以下是相关代码段:
char* findKey(char lineBuffer[], int columnNumber ){
char tempArray[512];
int commasCounted = 0;
int i =0;
for(i = 0; i< 1024; i++){
if (commasCounted == columnNumber){
commasCounted = i;
break;
}
if (lineBuffer[i] == '\"'){
while(lineBuffer[i] != '\"'){
i++;
}
}
if (lineBuffer[i] == ','){
commasCounted++;
}
}
if(lineBuffer[commasCounted] == ','){
tempArray[0] = '0';
tempArray[1] = '0';
tempArray[2] = '0';
tempArray[3] = '0';
tempArray[4] = '\0';
}else{
int j = 0;
for(i = commasCounted; i < 1024; i++){
if(lineBuffer[i] == '\"'){
i++;
while(lineBuffer[i] != '\"'){
tempArray[j] = lineBuffer[i];
i++;
j++;
}
break;
}else if(lineBuffer[i] == ','){
break;
}else
tempArray[j] = lineBuffer[i];
j++;
}
tempArray[j] = '\0';
}
char* tempString = strtok(tempArray, "\n");
return tempString;
}
我相信爆炸的部分是以下部分:
while(lineBuffer[i] != '\"'){
tempArray[j] = lineBuffer[i];
i++;
j++;
}
我只是不知道为什么。有没有办法来解决这个问题?我不知道这是不是原因,但这是lineBuffer中断时的输入:
Color,Glenn Ficarra,310,118,43,7000,Emma Stone,33000,84244877,Comedy|Drama|Romance,Ryan Gosling,"Crazy, Stupid, Love. ",375456,57426,Steve Carell,7,bar|divorce|friend|girl|male objectification,http://www.imdb.com/title/tt1570728/?ref_=fn_tt_tt_1,292,English,USA,PG-13,50000000,2011,15000,7.4,2.39,44000,
任何帮助将不胜感激。谢谢!
答案 0 :(得分:2)
您在这里遇到一些问题。
首先,您将返回一个指向局部变量的指针。这会调用未定义的行为。您应该用malloc
分配字符串,或者用tempArray
重复strdup
,然后返回它。
第二,您不应声明大小为tmpArray
的{{1}},它似乎是一个任意数字。 512
的大小至少应适合tmpArray
,因此您应将其声明为lineBuffer
搜索逗号时,您从char tmpArray[strlen(lineBuffer)+1];
迭代到0
,可能会超出范围访问1023
,更好的选择是将形式lineBuffer
迭代为{{1 }}。由于您还在循环内递增0
,因此应始终检查索引是否在边界内。
但是对于提供的测试字符串来说,所有这些事情似乎都不是问题,因为它适合所有缓冲区。 我认为问题出在这里:
strlen(lineBuffer)-1
如果找到i
,则要跳过所有内容,直到找到下一个。如果您考虑一下,由于根本无法输入if (lineBuffer[i] == '\"')
{
while(lineBuffer[i] != '\"')
{
i++;
}
}
循环,因此您的代码根本没有任何作用。您应该将其更改为:
'\"'
答案 1 :(得分:0)
确保索引i不会超过lineBuffer的结尾:
if (lineBuffer[i] && lineBuffer[i] == '\"'){...