基础知识 | 每日一面(83)

古代的剑客们与对手相逢时,无论对手多么强大,明知不敌,也要亮出自己的剑!

读者:我怎样才知道对于任意的 sprintf 调用需要多大的目标缓冲区?

怎样才能避免 sprintf() 目标缓冲区溢出?

小林:当用于 sprintf() 的格式串已知且相对简单时, 你有时可以预测出缓冲区的大小。如果格式串中包含一个或两个 %s, 你可以数出固定字符的个数再加上对插入的字符串的 strlen() 调用的返回值。对于整形, %d 输出的字符数不会超过((sizeof(int) * CHAR_BIT + 2) / 3 + 1) /* +1 for ’-’ */CHAR BIT 在 <limits.h> 中定义, 但是这个计算可能有些过于保守了。它计算的是数字以八进制存储需要的字节数; 十进制的存储可以保证使用同样或更少的字节数。当格式串更复杂或者在运行前未知的时候, 预测缓冲区大小会变得跟重新实现 sprintf 一样困难, 而且会很容易出错。有一种最后防线的技术, 就是 fprintf() 向一块内存区或临时文件输出同样的内容, 然后检查 fprintf 的返回值或临时文件的大,并提防写文件错误。

正文完