诊断堆缓冲区溢出时遇到问题

时间:2018-10-02 15:35:52

标签: c

我正在尝试分析项目合作伙伴编写的函数,以弄清楚为什么它会给我造成堆缓冲区溢出。我已经通过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,

任何帮助将不胜感激。谢谢!

2 个答案:

答案 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] == '\"'){...