简体   繁体   English

这个缓冲区怎么可能被覆盖?

[英]How could this buffer be overrun?

I apologize in advance for the useless title of this question, but nothing seemed to fit better. 我提前为这个问题的无用标题道歉,但似乎没有什么比这更合适了。

The idea here is to replicate argv in another variable, essentially making a copy of it. 这里的想法是在另一个变量中复制argv ,基本上是复制它。 So the basic idea of what the function does is, use malloc() to request some space for a copy and then iterate through argv making copies of each element. 因此,该函数的基本思想是,使用malloc()为副本请求一些空间,然后遍历argv制作每个元素的副本。

This is the code I'm working with, the development environment is right now Visual Studio 2019 (even if it's not strictly a C compiler...): 这是我正在使用的代码,开发环境现在是Visual Studio 2019(即使它不是严格意义上的C编译器......):

// Returns a copy of an array of strings (inteded 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;
}

I've been trying different ways to make a copy of argv but each and everyone of them lets VS to believe there can be a buffer overrun when I make a copy of an argument (line: argsCopy[i] = _wcsdup(argv[i]); ) or reading invalid data in the next line, meaning reading out of the bounds of the reserved space. 我一直在尝试不同的方法来制作argv的副本但是每个人都让VS相信当我制作一个参数的副本时会有一个缓冲区溢出(行: argsCopy[i] = _wcsdup(argv[i]); )或读取下一行中的无效数据,意味着读出保留空间的边界。

All of this has leeds me to believe the problem lies in the (now) only malloc() call to reserve space for the array of arguments. 所有这一切都让我相信问题在于(现在)只有malloc()调用为参数数组保留空间。

Yet I'm banging my head against the wall trying to figure out what the problem is, I mean, I think I'm asking for enough space. 然而,我正在撞墙,试图弄清问题是什么,我的意思是,我想我要求足够的空间。

I've tried other compilers as well, latest stable versions of Clang and GCC don't seem to show any such warning. 我也尝试了其他编译​​器,Clang和GCC的最新稳定版本似乎没有显示任何此类警告。 So I decided to ask you, seasoned programmers, if you can spot the problem, or it's some sort of compiler bug (unlikely I bet). 所以我决定问你,经验丰富的程序员,你是否能发现问题,或者是某种编译器错误(我不太可能打赌)。

For reference these are the exact warnings VS2019 is throwing (in a 64-bit compilation): 作为参考,这些是VS2019正在抛出的确切警告(在64位编译中):

In the assignment: 在作业中:

Buffer overrun while writing to 'argsCopy': the writable size is '((argc+1))*sizeof(wchar_t *)' bytes, but '16' bytes might be written. 写入'argsCopy'时缓冲区溢出:可写大小为'((argc + 1))* sizeof(wchar_t *)'字节,但可写入'16'字节。

Next line, the test for NULL: 下一行,测试为NULL:

Reading invalid data from 'argsCopy': the readable size is '((argc+1))*sizeof(wchar_t *)' bytes, but '16' bytes may be read. 从'argsCopy'读取无效数据:可读大小为'((argc + 1))* sizeof(wchar_t *)'字节,但可读取'16'字节。

These are warnings from the static analyzer. 这些是来自静态分析仪的警告。 It tries, for example, to recognize buffer overflow situations. 例如,它尝试识别缓冲区溢出情况。

Warning 警告

It is important to note that these are warnings and not error messages. 请务必注意,这些是警告而不是错误消息。 The compiler says that there might be something potentially wrong . 编译器说可能存在潜在的错误 Static analysis is generally a difficult thing. 静态分析通常是一件困难的事情。

False Positive 假阳性

There is no buffer overrun situation, so it is a false positive. 没有缓冲区溢出的情况,所以这是误报。 I would assume, that this message disappears in a future update. 我认为,此消息将在未来的更新中消失。

Change the Code a Bit 稍微改变代码

If we change the memory allocation line as follows: 如果我们更改内存分配行如下:

wchar_t** argsCopy = (wchar_t**)calloc(argc + 1, sizeof(wchar_t*));

then there will be no more warnings from Visual Studio 2019. 那么Visual Studio 2019将不再有警告。

The number of bytes allocated remains the same. 分配的字节数保持不变。 However, the warnings disappear. 但是,警告消失了。

Test 测试

Before the change the VS Error list looks like this: 在更改之前,VS Error列表如下所示:

之前

After the application of my proposed changes, the warnings have disappeared: 应用我提议的更改后,警告已消失:

后

I could be mistaken, however, after playing around with an online copy of visual studio ( https://rextester.com/l/c_online_compiler_visual ), I am forced to assume that you have forgotten to include string.h or wchar.h (either one works). 然而,在使用visual studio的在线副本( https://rextester.com/l/c_online_compiler_visual )后,我可能会弄错,我不得不假设您忘记包含string.hwchar.h (任何一个工作)。 Visual Studio appears to assume that your return type is an integer instead of a wchar_t* as the function is not defined. Visual Studio似乎假设您的返回类型是整数而不是wchar_t *,因为未定义函数。 It seems that there is a bit of "magic" due to the fact that it is a reserved function starting with an _ and therefore it doesn't issue other warnings? 似乎有一点“魔力”,因为它是一个以_开头的保留函数,因此它不会发出其他警告? Again without your exact environment though I am forced to partially speculate (your comment on your target changing the warning gave me a hopefully correct hint). 再次没有你的确切环境虽然我被迫部分推测(你的目标评论改变警告给了我一个希望正确的提示)。

The key point might be you didn't malloc the enough space to hold the data you want to copy. 关键点可能是你没有malloc足够的空间来容纳你想要复制的数据。

I don't know whether I actually understand what you want to do, I assume you want to copy two-dimensional character array to another memory segment and then return its address, and the array has 'argc' lines, the address of each line of string is stored in the array of argv. 我不知道我是否真的理解你想做什么,我假设你想要将二维字符数组复制到另一个内存段然后返回它的地址,并且数组有'argc'行,每行的地址string的数据存储在argv数组中。

But why did you use argc+1 instead of argc ? 但是你为什么用argc+1而不是argc For malloc extra space to prevent buffer overrun? 对于malloc额外的空间来防止缓冲区溢出? and more important is sizeof(wchar_t*) will return the size of a pointer ( 8 bytes in 64 bits system ). 更重要的是sizeof(wchar_t*)将返回指针的大小(64位系统中的8个字节)。 It will not return the size of one of the string in the two-dimensional array we want. 它不会返回我们想要的二维数组中的一个字符串的大小。

1) One way to replicate argv is explained below but., 2) I am unable to understand why you want to make a replica of argv? 1)复制argv的一种方法解释如下,但是,2)我无法理解为什么要制作argv的副本? what use-case/user-problems does it solve? 它解决了什么用例/用户问题?

as I mentioned in (1), here is one of the ways, which is essentially about copying all the contents that argv has into your buffer. 正如我在(1)中提到的,这是其中一种方法,主要是将argv中的所有内容复制到缓冲区中。 It goes something like this (PS: there could be compilation erros as I"m typing in my phone while being in a taxi, so don't have access to a hi quality C compiler to cross check) 它是这样的(PS:可能有编译错误,因为我在打电话时输入我的手机,因此无法访问高质量的C编译器进行交叉检查)

int numArgc = argc
char** argvCopy;

for (i=0;i<argc,i++)
{

 argvCopy[i] = malloc(sizeof(char)*strlen(argv[i]));
 strcpy(argvCopy[i], argv[i]);

}

//please do not forget to Free this malloc'ed memory (a very common C programming error) //when you don't need it anymore 

please do tell the problem that you want to solve 请告诉您要解决的问题

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM