`

c库中snprintf返回值误区

    博客分类:
  • C
c 
阅读更多

       最近看开源代码中发现一个问题,下面是发表在内核开发论坛上到一篇文章:http://lwn.net/Articles/69419/,主要提到到问题就是stdio.h中的snprintf函数的返回值的问题,该函数定义如下:

       int snprintf(char *str, size_t size, const char *format, ...);

       很多开发者都会认为该函数的返回值是写入到指定str缓冲区的字符数量,这个想法是错误的,查看源代码可以得到结果是返回值是整个构建字符数,函数假定字数是可以全部被写入到缓冲区中的。当缓冲区小于字符总数时,这样使用返回值进行多次写入就可能会导致缓冲区溢出现象。如下情况:有关snprintf实现细节可查看 http://www.ijs.si/software/snprintf/

if ((len += snprintf (buf+len, buflen-len, "...", ...)) > buflen) {
        optionally deal with the error;
        len = buflen;
}

snprintf() confusion

Any C coder worth his or her salt knows that encoding text into a string with sprintf() invites buffer overflows, and is thus dangerous. The proper way of doing things is with snprintf() , which takes the length of the destination string as a parameter, and will not overrun it. Callers to snprintf() generally assume that the return value is the length of what was actually encoded into the destination array. That turns out, however, to not be the case. As per the C99 standard, snprintf() returns the length the resulting string would be, assuming it all fit into the destination array. As a result of this misunderstanding, the kernel is full of snprintf() calls which use the return value incorrectly.

This mistake is rarely a problem; snprintf() almost never has to truncate its output, so the return value is what the programmer is expecting. Every miscoded use is an invitation for trouble, however, and really should be fixed. To that end, the 2.6.2-rc3-mm1 tree contains a patch by Juergen Quade which adds a couple of new functions:

 

    int scnprintf(char *buf, size_t size, const char *format, ...);
    int vscnprintf(char *buf, size_t size, const char *format, va_list args);

The new functions work the way many programmers expected the old ones to: they return the length of the string actually created in buf . The plan is to migrate the kernel over to the new functions; the patch fixes well over 200 snprintf() and vsnprint() calls. Unless the old functions are eventually removed, however, they are likely to be a source of programming errors well into the future.

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics