使用MACRO将sprintf转换为snprintf

时间:2014-06-09 07:26:47

标签: c printf

我们有一些代码如下:

#define MAXINT  1000000000

#define SPRINTF(a, b, c)    ((sizeof (a) > 8) ? snprintf(a, sizeof (a), b, c) : snprintf(a, MAXINT, b, c))
                            // avoids buffer overrun for static buffers of size > 8 else behaves like default sprintf()
                            // note max. size of char pointer is 8, so if sizeof (a) > 8, it means it is static array

我记得开发人员被要求将所有sprintf()转换为更安全的版本snprintf(),并且他确实如上所示进行了更改。

我知道上面的MACRO只能避免缓冲区损坏,只适用于大小为&gt;的静态缓冲区。 8,对于其他,即动态缓冲区和大小<= 8的静态缓冲区的行为类似于普通的sprintf(),假设被复制的字符串不大于“MAXINT”。这是对的吗?

对于前。如果被复制的字符串小于dest缓冲区或大于dest缓冲区,则此语句/上面的MACRO将始终正常运行,如snprintf(a,sizeof(a),b,c)或类似普通的默认sprintf() - 这是友好的好的行为暂时我假设它永远不会用MAXINT填充dest缓冲区(太大而src字符串永远不会那么大)字符数量?

1 个答案:

答案 0 :(得分:0)

宏具有条件&#39; a&gt; 8&#39;检查a是char *类型还是char []类型。如果是char *,则无法知道分配了多少内存以及我们可以写入多少内存。如果是char [],那么我们知道为它保留了多少内存。因此对于char [],我们可以使用snprintf,从而确保我们永远不会溢出更安全。对于char *,我们不能提供相同的。代码假设你永远不想写超过MAXINT。

如果我正在编写宏,我会将snprintf(a,MAXINT,b,c)更改为sprintf(a,b,c),以便更清楚地表明我们无法在该场景中提供任何保证。 / p>