缓冲区在 cppcheck 中被越界访问

Posted

技术标签:

【中文标题】缓冲区在 cppcheck 中被越界访问【英文标题】:Buffer is accessed out of bounds in cppcheck 【发布时间】:2018-12-13 07:10:32 【问题描述】:

代码可以编译,结果很好。 但是cppcheck会报错。

#define BUF_SIZE     1024
#define MAX_LENG     80

static unsigned char path[MAX_LENG];
unsigned char file_buf[BUF_SIZE*2];

memset(file_buf, 0, sizeof(file_buf));
strcpy(file_buf, "KID ");
strncat(file_buf, &path[strlen(path)-12], 10); //error this line

我试了几次,还是找不到原因。 任何人都可以给我一些提示吗?

谢谢大家的回答。

但我还有更多问题: 如果这是一个致命错误,为什么编译器通过并且结果是我想要的? 什么情况下会出问题?

还有其他的实现方式吗?

如果我把它改成

strncat(file_buf, &path[strlen(path)-12], 5);

cppcheack 错误将消失。为什么?

【问题讨论】:

【参考方案1】:

这里的缓冲区:

static unsigned char path[MAX_LENG];

是静态的,因此初始化为零。首次执行此代码时,第一个字符为 0。因此strlen(path) 将返回(size_t)0。从中减去 12,由于模运算,你会得到一个非常大的无符号数,这个数字肯定大于 1024

【讨论】:

【参考方案2】:

你访问一个索引太大的数组:

static unsigned char path[MAX_LENG];

作为static,它被初始化为零。这意味着strlen(path) 将返回 0。

strncat(file_buf, &path[strlen(path)-12], 10);

在这里你减去 12 即为 -12,但由于 strlen 返回一个无符号值,结果索引为 SIZE_MAX-12,这显然超出了界限。

【讨论】:

@M.M 由于数字圆圈实际索引为-12,如果strlen 返回零。有效的数组索引是正数,但实际上是对数组之前的访问。 @harper 不是的。

以上是关于缓冲区在 cppcheck 中被越界访问的主要内容,如果未能解决你的问题,请参考以下文章

cppcheck : 缓冲区被越界访问

cppcheck 报告“缓冲区访问越界”

对缓冲区大小施加限制

内存溢出内存泄露内存越界缓冲区溢出栈溢出

内存溢出内存泄露内存越界缓冲区溢出栈溢出

C++:带你搞定数组的疑难杂症--缓冲区溢出;数组越界;为什们打印内容能超出数组长度?