cppcheck : 缓冲区被越界访问
Posted
技术标签:
【中文标题】cppcheck : 缓冲区被越界访问【英文标题】:cppcheck : Buffer is accessed out of bounds 【发布时间】:2020-01-27 22:27:55 【问题描述】:我有下面的代码。运行cppcheck工具后报错Buffer is access out of bounds?用snprintf在线报错。
#include <stdio.h>
int main(int argc, char * argv[])
if (argc > 1)
char testref[8] = "";
snprintf(testref, sizeof(testref), "Ref:%s", argv[1]);
printf("===>testref=%s\n", testref);
命令行交互下方:
amin@ubuntu:$ gcc test.c -o test
amin@ubuntu:$
amin@ubuntu:$ ./test hello_world
===>testref=Ref:hel
amin@ubuntu:$ cppcheck test.c
Checking test.c...
[test.c:7]: (error) Buffer is accessed out of bounds.
amin@ubuntu:$
cppcheck 报告这个错误是否正确?
【问题讨论】:
argv[1]
中的值如果长度超过 3 个字节,将被截断,但代码没有我能看到的其他问题。错误报告可能是合适的——或者,至少,在cppcheck
中询问为什么它不是错误。
您使用的是哪个版本的 cppcheck?使用 Cppcheck 1.82 我没有收到任何错误代码。
如果 snprintf()
返回 -1,那么 printf("===>testref=%s\n", testref);
不是是件好事。为了完整性。按照@wildplasser 的建议报告snprintf()
的返回值
@wildplasser,手册页确实非常有用,但您认为这对解决这个特定问题有何帮助? (如果您认为自己有解决方案,请考虑发布答案。)
@wildplasser,我已经搜索了有关此的文档,但找不到。当前的手册页指的是 AFAIK 不会发生缓冲区溢出的“正确”行为。在最初的 ANSI 标准中,snprintf() 函数不存在。我将不胜感激您提到的功能的参考。这确实可以解释观察到的问题。
【参考方案1】:
我认为,一般来说,cppcheck 报这个错误是正确的。 snprintf
函数的行为取决于实现,并且在某些实现中,如果字符串对于缓冲区来说太大,则不能保证写入空字符。在这种情况下,对printf()
的连续调用将读取缓冲区边界之外的内容。
我至少可以找到 one example 的 snprintf
实现,这会导致您的代码出现越界错误。根据this comment,c99 之前的 True64/DigitalUnix 也是如此。
看看cppcheck是否也报告以下代码的错误会很有趣(它不应该报告错误):
#include <stdio.h>
int main(int argc, char * argv[])
if (argc > 1)
char testref[8] = "";
int ret = snprintf(testref, sizeof(testref), "Ref:%s", argv[1]);
if (ret >= 0)
printf("===>testref=%s\n", testref);
另请注意,Cppcheck 1.82 版不会为您的代码报告错误。我不确定为什么 1.72 版会报告错误而 1.82 版不会。
【讨论】:
snprintf()
是由 c 标准定义的,cppcheck 应该考虑这些语义。因此,我会说新版本 1.82 的行为正确。
@Ctx,没有“C 标准”之类的东西 ;-) 在最初的 ANSI 标准中,这个功能不存在。在 C99 中似乎定义明确,但还有许多其他标准和实现。我不确定应该考虑哪个标准 cppcheck。
cppcheck 确实可以选择传递它应该检查的标准。如果您将-std=c99
标志传递给它,我希望它会使用snprintf
的c99 版本。以上是关于cppcheck : 缓冲区被越界访问的主要内容,如果未能解决你的问题,请参考以下文章