`

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.

分享到:
评论

相关推荐

    理解snprintf()函数

    snprintf()函数是C标准库中的一个输出函数,用于格式化输出并将结果存入字符串中,它是sprintf()的变体,增加了缓冲区大小限制的功能,从而避免了缓冲区溢出的风险。 snprintf()函数的声明如下: ```c int snprintf...

    snprintf 的实现

    `snprintf` 函数是C语言中的一个标准库函数,属于`stdio.h`头文件的一部分。它主要用于格式化输出字符串到内存缓冲区,而不是直接输出到屏幕或文件。`snprintf`的名字来源于“sprintf”(用于格式化输出到字符串)与...

    inttypes.h snprintf.c snprintf.h stdint.h

    接下来,`snprintf.c` 和 `snprintf.h` 涉及到的是C语言中的`snprintf()`函数。`snprintf()`是`printf()`系列函数的一个变种,它的主要特点是能够限制输出字符串的长度,防止缓冲区溢出。当需要向有限大小的缓冲区...

    C标准库源代码(学习C/C++必备)

    C标准库源代码,能提高对C的理解,不错的哦 下载文件列表 Pack : clibsource.rar C 标准库源代码\ABORT.C C标准库源代码\ABS.C C标准库源代码\ACCESS.C C标准库源代码\ADJUSTFD.C C标准库源代码\ALGRITHM C标准库源...

    字符串拷贝,最好用snprintf。

    在C语言编程中,字符串处理是非常常见的操作之一,其中涉及到字符串复制、连接等操作时,开发者通常会遇到`strncpy`、`strncat`以及`snprintf`这三个函数。本文将详细介绍这三种函数的特点,并解释为什么在某些情况...

    C标准库源代码 很全

    1. 输入/输出(I/O):stdio.h头文件中的函数,如`printf`和`scanf`,是C语言中最常用的输入输出工具。它们允许开发者将数据格式化输出到屏幕或从键盘读取输入。 2. 字符串处理:strings.h和string.h头文件提供了...

    C语言标准库源码

    C语言标准库,通常被称为libc,是C编程语言的核心组成部分,它包含了大量的基本函数和工具,使得程序员可以处理输入输出、内存管理、字符串操作、数学计算等任务。在这个压缩包`glibc-2.26`中,我们讨论的是GNU C ...

    C语言函数速查库

    这个速查库涵盖了C语言中的大量标准库函数,帮助开发者快速查找和理解各个函数的功能、用法以及参数。 C语言的库函数主要包括以下几个方面: 1. 输入/输出(I/O)函数:如`printf`用于格式化输出,`scanf`用于从...

    安全函数strcpy_s、strncpy_s、snprintf_s、memcpy_s

    为了解决这个问题,C标准库引入了安全版本的这些函数,例如`strcpy_s`, `strncpy_s`, `snprintf_s`, 和 `memcpy_s`。下面我们将详细探讨这些安全函数的功能和使用方法。 1. **strcpy_s**: 这是`strcpy`的安全版本。...

    snprintf:snprintf的独立实现

    独立的snprintf和vsnprintf 该存储库中包含一个相对简单的snprintf和vsnprintf ,我在一两个小时的时间内编写了这些信息,用于业余爱好者的微内核。 我发现自己过去几次编写此代码或类似代码,因此决定编写一个涵盖...

    snprintf函数的用法解析

    `snprintf` 函数是C语言中的一个标准库函数,用于格式化输出字符串,并将其存储在指定的缓冲区中。这个函数的安全性在于它能够防止缓冲区溢出,因为你可以指定缓冲区的最大长度,`snprintf` 会确保不超过这个限制。 ...

    C语言函数库速查

    1. 输入输出函数:如`printf`和`scanf`,是C语言中最基本的输入输出方式。`printf`用于格式化输出,可以处理整型、浮点型、字符型等多种数据类型;`scanf`则用于从标准输入设备读取数据,与`printf`对应。 2. 字符...

    C语言库函数大全(HTML帮助文件格式)

    这个资源被整理成HTML帮助文件格式,旨在提供一个便捷、易查阅的平台,帮助开发者快速查找和理解C语言中的函数用法。CHM(Compiled Help Manual)文件是一种微软开发的帮助文档格式,它将多个HTML页面、图像和其他...

    strncpy与snprintf 的用法比较

    在C语言中,`strncpy` 和 `snprintf` 都是用来进行字符串处理的函数,但它们有着不同的特性和用途。下面将详细分析这两个函数的用法和它们之间的区别。 `strncpy` 函数用于安全地复制字符串,其原型定义为: ```c ...

    c标准库

    1. `printf`与`scanf`:这两个函数是C语言中最常用的I/O函数,分别用于格式化输出和输入。例如,`printf`可以用来打印变量值,`scanf`可以读取用户输入。 2. `fopen`与`fclose`:文件操作的核心函数,`fopen`用于...

    c语言 函数查询工具

    "C语言函数查询工具"就是为了帮助开发者更加便捷地查找和理解C语言中的函数而设计的实用软件。 这个工具允许用户输入关键词,快速查询C语言标准库中的函数,包括它们的功能、参数、返回值以及使用示例。通过这样的...

    c函数大全包含了所有c语言函数

    "C函数大全"是一个集合了C语言中所有标准库函数的参考资料,对于学习和使用C语言的人来说,这是一个不可或缺的工具。下面,我们将深入探讨C语言中的主要函数类别及其功能。 1. 输入/输出函数: - `printf` 和 `...

    字符串拷贝函数memcpy和strncpy以及snprintf 的性能比较

    问题:函数memcpy(dest, src, sizeof(dest))、strncpy(dest, src, sizeof(dest))和snprintf(dest, sizeof(dest), “%s”, src)都可以将src字符串中的内容拷贝到dest字符串中。哪一种方式效率最高呢?就是说,哪种...

    C语言中char型转string

    在C语言中,字符类型(char)与字符串(strinng)之间的转换是常见的操作。C语言中的字符串实际上是由字符数组表示的,通常以空字符'\0'作为结束标志。本篇文章将详细探讨如何在C语言中将`char`类型转换为`string`。 ...

    libharu 静态库源码 vc6.0

    它提供了C语言接口,易于集成到各种应用程序中。在本资源中,我们得到了libharu的静态库源码,特别适用于Visual C++ 6.0(VC6.0)开发环境。 **1. libharu库介绍** libharu库的主要功能包括: - 创建新的PDF文档 - ...

Global site tag (gtag.js) - Google Analytics