为何fgets()需指定输入最大长度?相关安全问题咨询
聊聊fgets()里的参数n:作用、安全逻辑和常见疑问
先明确fgets()的官方原型:
char *fgets(char *str, int n, FILE *stream);
1. 为什么必须指定n?是防溢出还是设计缺陷?
这绝对是主动防缓冲区溢出的安全设计,和“缺陷”完全不沾边——恰恰是踩过gets()的致命坑,才特意加了这个参数。
gets()之所以被彻底废弃,就是因为它不管缓冲区容量,一股脑把输入往里塞,只要输入长度超过缓冲区,直接溢出覆盖内存,轻则程序崩成段错误,重则被黑客利用做代码注入。而fgets()的n就是给函数划死了红线:最多读取n-1个字符(最后要留位置放字符串结束符\0),达到上限就停止读取,从根源上堵死了无限制输入导致的溢出风险。
2. 这和fgets()作为文件函数的属性有关吗?
当然有关系。文件流的输入完全不可控——比如读文本文件时,某一行可能只有几个字符,也可能有几千个。作为文件操作工具,fgets()必须明确知道目标缓冲区的容量,才能在读取时做边界控制:既把能装下的内容读进来,又不越界乱写内存。要是没了n,它处理文件输入时就和gets()一样,完全是个定时炸弹。
3. 从安全角度看,n参数有风险吗?
风险不在参数本身,全在开发者会不会用错:
- 要是你给的
n比实际缓冲区大小大,比如缓冲区只有100字节,你传个n=200,那fgets()照样会往缓冲区外面写,溢出风险还是存在; - 要是传个
n=1,函数只能读0个字符(因为要留位置放\0),这属于逻辑错误,但不是安全问题。
只要老老实实传缓冲区的实际大小(比如用sizeof(str)),n就是最靠谱的安全防护手段。
4. 这个长度限制会引发段错误吗?
正常使用绝对不会。段错误的本质是程序访问了不该碰的内存,而fgets()的长度限制就是为了避免这种情况。只有两种情况会出问题:要么你把n设错了(比缓冲区大太多),要么str本身是个无效指针(比如空指针、指向只读内存的指针)——这都是开发者的使用错误,和长度限制没关系。
内容的提问来源于stack exchange,提问作者Cccc
相关产品推荐
相关产品推荐

