Gcc 无符号短覆盖

Gcc 无符号短覆盖,gcc,unsigned,Gcc,Unsigned,而(fscanf(fp,“%s”,字符串[cnt++])!=EOF) cnt是一个无符号的短字符。它有65535个。因此,当文件到达的字数超过这些字数时,cnt再次初始化为0并继续。我的问题是,这是发生在所有编译器上,还是只发生在gcc上 char filename[128]; strcpy(filename, argv[1]); 文件名只能存储128个字符(127+空字符)。当用户传递的参数超过127个字符(如paxdiablo所指出)时,可能会发生溢出 理想情况下,应用程序将计算输入参数中

而(fscanf(fp,“%s”,字符串[cnt++])!=EOF)

cnt是一个无符号的短字符。它有65535个。因此,当文件到达的字数超过这些字数时,cnt再次初始化为0并继续。我的问题是,这是发生在所有编译器上,还是只发生在gcc上

char filename[128];
strcpy(filename, argv[1]);
文件名
只能存储128个字符(127+空字符)。当用户传递的参数超过127个字符(如paxdiablo所指出)时,可能会发生溢出

理想情况下,应用程序将计算输入参数中有多少个字符,并分配一个足够大的变量来存储此信息:

int param_size = strlen(argv[1]);
char* filename = malloc(param_size+1);
if (!filename)
{
     // TODO: memory allocation failed! Need to handle error.
     // (notify the user, quit the application or something).
}
strcpy(filename, argv[1]);

这里有3种不同的能力:

  • strcpy(文件名,argv[1]),其他人已经提到

  • strings[cnt++]
    -如果文件包含的行数超过
    USHRT\u MAX
    行数,您将超过
    strings
    数组。您将开始读取用于其他内容的堆栈区域

  • fscanf(fscanf(fp,“%s”,…)
    -如果一行包含的字符超过79个,您将覆盖下一行。这将是无害的,除非您超过整个字符串数组

  • 漏洞:

    1) 没有检查argc以查看是否确实存在argv[1]。如果用户只键入了没有任何命令行参数的家庭作业.exe,则索引可能无效

    2) 无法检查argv[1]的内容是否适合文件名缓冲区。现在,它假设文件是由文本行构建的,其中任何一行都不超过79个字符


    3) fscanf()采用特定的文件格式。这可能是一个漏洞,也可能不是。如果它不包含给定格式的字符串,或者如果它包含的行数超过了无符号短字符的行数,则程序将崩溃并烧掉。

    您可能可以避免这样的代码:

    char filename[128];
    strcpy(filename, argv[1]);
    
    #define BUFSIZE 128
    char filename[BUFSIZE];
    strncpy(filename, argv[1], BUFSIZE);
    
    …并编写更像这样的代码:

    char filename[128];
    strcpy(filename, argv[1]);
    
    #define BUFSIZE 128
    char filename[BUFSIZE];
    strncpy(filename, argv[1], BUFSIZE);
    
    strcpy版本的strcpy限制了可以复制的字符。对大小使用宏是很好的,所以您可以在以后更改这些缓冲区大小,并且您不会用神奇的数字填充代码

    出于同样的原因,您应该避免直接使用fscanf,您可以使用函数传递固定大小的字符串,而不是无界字符串。或者你可以这样做

    strings[STRINGSIZE] = 0; 
    cnt = cnt %  STRINGSIZE;
    

    …因此您可以保证字符串的大小限制在限制之内

    事实上,超过127个,因为它也存储空终止符,但+1,因为错误很小,不会真正影响答案。还有一个建议,Karl,没有必要将内存归零,因为你知道你无论如何都要用
    strcpy
    覆盖它。您可能想查看malloc的退货,但我觉得我今天太挑剔了:-)我明白了,谢谢。memset()所做的另一件事是在末尾设置NULL字符。我想我会简化这项任务,几分钟后再来。
    strcpy
    也会将空值放在末尾,但我会等待:-)你怎么可能没有twitter帐户?Linux上有cmd行Twitter客户端,你知道:)80个字符应该是79个。这可能是一个无意的bug,可能有人忘记了空终止的空间。谢谢@Lundin,80个字符就足够溢出了。固定答案。我不会说有人忘记了空终止-更像是有人忘记了缓冲区大小很重要。文件每行很容易超过80个字符(除非它们是从穿孔卡读取的)。