Ale*_*Row 14 c malloc buffer-overflow
对于这个问题的标题,我事先表示歉意,但是似乎没有比这更好的了。
这里的想法是argv在另一个变量中复制,本质上是复制它。因此,函数功能的基本思想是,malloc()用于为副本请求一些空间,然后遍历argv每个元素的副本进行迭代。
这是我正在使用的代码,开发环境现在是Visual Studio 2019(即使严格来讲不是C编译器...):
// Returns a copy of an array of strings (intended for argv, but should work with any of them):
wchar_t** copyArgv(size_t argc, wchar_t* argv[]) {
// Allocate space for the array of arguments:
wchar_t** argsCopy = malloc(((argc + 1) * sizeof(wchar_t*)));
if (!argsCopy)
return NULL;
// Copy each one of them:
for (size_t i = 0; i < argc; i++) {
argsCopy[i] = _wcsdup(argv[i]);
if (!argsCopy[i]) {
// Should also free any previous copied string I left that part out in the paste.
free(argsCopy);
return NULL;
}
}
argsCopy[argc] = NULL;
return argsCopy;
}
Run Code Online (Sandbox Code Playgroud)
我一直在尝试不同的方法来复制argv,但是每一个方法都让VS相信当我复制参数(行argsCopy[i] = _wcsdup(argv[i]);:)或在下一行中读取无效数据时,缓冲区可能会溢出,表示读取预留空间的边界。
所有这些使我相信问题出在(现在)仅malloc()调用来为参数数组保留空间。
但是我要把头撞在墙上,试图弄清楚问题出在哪里,我的意思是,我想我要的是足够的空间。
我也尝试过其他编译器,但是Clang和GCC的最新稳定版本似乎未显示任何此类警告。因此,我决定问您,经验丰富的程序员,是否可以发现问题,或者是某种编译器错误(我敢打赌)。
作为参考,以下是VS2019发出的确切警告(在64位编译中):
在作业中:
写入'argsCopy'时缓冲区溢出:可写大小为'(((argc + 1))* sizeof(wchar_t *)''字节,但可能会写入'16'字节。
下一行,测试NULL:
从'argsCopy'读取无效数据:可读大小为'(((argc + 1))* sizeof(wchar_t *)'字节,但可以读取'16'字节。
这些是来自静态分析器的警告。例如,它尝试识别缓冲区溢出情况。
警告
请务必注意,这些是警告而不是错误消息。编译器表示可能存在潜在错误。静态分析通常是一件困难的事情。
假阳性
不存在缓冲区溢出情况,因此属于误报。我假设这条消息会在未来的更新中消失。
稍微改变一下代码
如果我们按如下方式更改内存分配行:
wchar_t** argsCopy = (wchar_t**)calloc(argc + 1, sizeof(wchar_t*));
Run Code Online (Sandbox Code Playgroud)
那么 Visual Studio 2019 将不再发出警告。
分配的字节数保持不变。然而,警告消失了。
测试
更改之前 VS 错误列表如下所示:
应用我建议的更改后,警告消失了: