简体   繁体   English

C提示被覆盖

[英]C prompt being overwritten

I'm new to C and I encountered a weird problem. 我是C语言的新手,我遇到了一个奇怪的问题。

This code is part of a bigger program, but the problem is within here but I can't seem to figure it out. 这段代码是一个更大程序的一部分,但是问题在这里,但我似乎无法弄清楚。

#include <stdio.h>
#include <string.h>
#define WORDSIZE 512

int read_stdNum(const char prompt[], char store[], size_t n) {
    char inHold[WORDSIZE];
    char process[10];
    int status = 0;

    while (1) {
        fprintf(stderr, "%s", prompt);

        if(fgets(inHold, WORDSIZE, stdin) == NULL) {
            return 0;
        }

        sscanf(inHold, "%s", process);

        status = sscanf(process, "%s", store);

        if (status > 0 && strlen(store) == n) {
            return 1;
        } else if (status == -1) {
            continue;
        } else {
            continue;
        }
    }
}

int main(void) {
    char arrow[] = "\n==> ";
    char stdNum[10];

    printf("%s\n", "store_student called.");

    fprintf(stderr, "%s", "\nEnter a student number (axxxxxxxx)\n");
    read_stdNum(arrow, stdNum, 9);
    return 0;
}

The program asks for user input, and the test here is for the program to truncate the extra digits, but when I type something like " a123456789101112131415 ", the output is nothing, which works fine, but then the prompt gets over written and the prompt looks like this: 该程序要求用户输入,此处的测试是该程序截断多余的数字,但是当我键入类似“ a123456789101112131415 ”的内容时,输出为空,效果很好,但是提示被覆盖并且提示看起来像这样:

==> a123456789101112131415
131415_

The underscore is where I can still enter in input. 下划线是我仍然可以输入的地方。 The the character array 'process' is also storing more than 9 characters. 字符数组“ process”也存储了9个以上的字符。 I've asked some of my classmates, and also one of them said that it worked fine on his computer. 我问了我的一些同学,其中一个说在他的电脑上工作正常。 I know I'm going to get flamed for being dumb but I really want to know why this is not working. 我知道我会因为愚蠢而被炒鱿鱼,但我真的很想知道为什么这不起作用。 Thanks. 谢谢。

scanf function with " %s " may be unsafe and create buffer overflow (it may write more bytes into output string than the space allocated for the string, overwriting some useful data), check https://cwe.mitre.org/data/definitions/120.html "CWE-120: Buffer Copy without Checking Size of Input ('Classic Buffer Overflow')" & example 1 具有“ %s ”的scanf函数可能不安全,并且会导致缓冲区溢出(它可能会在输出字符串中写入比分配给该字符串的空间更多的字节,从而覆盖一些有用的数据),请检查https://cwe.mitre.org/data/ definitions / 120.html “ CWE-120:不检查输入大小的缓冲区复制('经典缓冲区溢出')”和示例1

https://en.wikipedia.org/wiki/Scanf_format_string#Vulnerabilities https://zh.wikipedia.org/wiki/Scanf_format_string#漏洞

This means that uses of %s placeholders without length specifiers are inherently insecure and exploitable for buffer overflows. 这意味着使用不带长度说明符的%s占位符本质上是不安全的,可用于缓冲区溢出。

Documentation of scanf has some requirements about s format usage (array must be long enough) http://man7.org/linux/man-pages/man3/scanf.3.html scanf文档对使用s格式有一些要求(数组必须足够长) http://man7.org/linux/man-pages/man3/scanf.3.html

  s Matches a sequence of non-white-space characters; the next pointer must be a pointer to the initial element of a character array that is long enough to hold the input sequence and the terminating null byte ('\\0'), which is added automatically. The input string stops at white space or at the maximum field width, whichever occurs first. 

The safer usage of scanf-like functions is to use "maximum field width" like %9s or m for dynamic memory allocation. 类似scanf的函数的更安全用法是使用%9sm类的“最大字段宽度”进行动态内存分配。

(Your check with strlen is too late; sscanf already did the overflow/overwrite of string because it had no limit on length to read.) (您对strlen检查为时已晚; sscanf已经对字符串进行了溢出/覆盖,因为它对读取的长度没有限制。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM