2. strcpy
该函数将源字符串复制到目标缓冲区,但并未指定要复制字符的数目。若源字符串来自用户输入且未限制其长度,则可能引发危险。规避的方法如下:
1) 若知道目标缓冲区大小,则可添加明确的检查(不建议该法):
2) 改用strncpy函数:
若szSrc比szDst大,则该函数不会返回错误;当达到指定长度(dwDstSize-1)时,停止复制字符。第二句将字符串结束符放在szDst数组的末尾。
3) 在源字符串上调用strlen()来为其分配足够的堆空间:
4) 某些情况下使用strcpy不会带来潜在的安全性问题:
即使该操作造成szDst溢出,但这几个字符显然不会造成危害——除非用其它方式覆盖字符串“Hello”所在的静态存储区。
安全的字符串处理函数通常体现在如下几个方面:
•显式指明目标缓冲区大小
•动态校验
•返回码(以指明成功或失败原因)
与strcpy函数具有相同问题的还有strcat函数。
3. strncpy/strncat
该对函数是strcpy/strcat调用的“安全”版本,但仍存在一些问题:
1) strncpy和strncat要求程序员给出剩余的空间,而不是给出缓冲区的总大小。缓冲区大小一经分配就不再变化,但缓冲区中剩余的空间量会在每次添加或删除数据时发生变化。这意味着程序员需始终跟踪或重新计算剩余的空间,而这种跟踪或重新计算很容易出错。
2) 在发生溢出(和数据丢失)时,strncpy和strncat返回结果字符串的起始地址(而不是其长度)。虽然这有利于链式表达,但却无法报告缓冲区溢出。
3) 若源字符串长度至少和目标缓冲区相同,则strncpy不会使用NUL来结束字符串;这可能会在以后导致严重破坏。因此,在执行strncpy后通常需要手工终止目标字符串。
4) strncpy还可复制源字符串的一部分到目标缓冲区,要复制的字符数目通常基于源字符串的相关信息来计算。这种操作也会产生未终止字符串。
5) strncpy会在源字符串结束时使用NUL来填充整个目标缓冲区,这在源字符串较短时存在性能问题。
4. sprintf
该函数使用控制字符串来指定输出格式,该字符串通常包括"%s"(字符串输出)。若指定字符串输出的精确指定符,则可通过指定输出的最大长度来防止缓冲区溢出(如%.10s将复制不超过10个字符)。也可以使用"*"作为精确指定符(如"%.*s"),这样就可传入一个最大长度值。精确字段仅指定一个参数的最大长度,但缓冲区需要针对组合起来的数据的最大尺寸调整大小。
注意,"字段宽度"(如"%10s",无点号)仅指定最小长度——而非最大长度,从而留下缓冲区溢出隐患。
5. scanf
scanf系列函数具有一个最大宽度值,函数不能读取超过最大宽度的数据。但并非所有规范都规定了这点,也不确定是否所有实现都能正确执行这些限制。若要使用这一特性,建议在安装或初始化期间运行小测试来确保它能正确工作。
6. streadd/strecpy
这对函数可将含有不可读字符的字符串转换成可打印的表示。其原型包含在libgen.h头文件内,编译时需加-lgen [library ...]选项。
char *strecpy(char *pszOut, const char *pszIn, const char *pszExcept);
char *streadd(char *pszOut, const char *pszIn, const char *pszExcept);
本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-30832-4.html
#杨洋icon##杨洋2015金投赏#杨洋金投赏
干掉敌人是唯一的选择
不能怠慢
更新了