我观察到 Microsoft 实现中存在一个有趣的问题strncat
。它超出了源缓冲区 1 个字节。考虑以下代码:
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <string.h>
void main()
{
char dstBuf[1024];
char* src = malloc(112);
memset(src, 'a', 112);
dstBuf[0] = 0;
strncat(dstBuf, src, 112);
}
strncat
在 112 字节块之后读取 1 字节。因此,如果您不幸在无效页面边界上获得分配,您的应用程序就会崩溃。大型应用程序可能会在这些地方间歇性崩溃。 (请注意,这种情况可以用以下方式模拟gflags 页堆环境;块大小必须能被指针大小整除才能正确对齐。)
这是预期的行为还是错误?有任何链接证实这一点吗? (我读了一些描述strncat
但它们可以有两种解释,具体取决于您最初的想法......)
Update(回答有关证据的问题):
如果上面的文字不清楚,我深表歉意,但这是一个实验事实。我观察到应用程序间歇性崩溃strncat
读取地址src+srcBufSize。在这个小例子中运行gflags 页堆崩溃时一致重现(100%)。据我所知,证据非常确凿。
Update2(有关编译器的信息)
MS Visual Studio 2005 版本 8.0.50727.867。
构建平台:64 位版本(32 位没有重现)。
用于重现崩溃的操作系统:Windows Server 2008 R2。
Update 3使用 MS Visual Studio 2012 11.0.50727.1 中内置的二进制文件也会重现该问题
Update 4 Microsoft Connect 上的问题链接 https://connect.microsoft.com/VisualStudio/feedback/details/800199/strncat-reads-bytes-outside-of-source-buffer-range; MSDN 论坛讨论的链接 http://social.msdn.microsoft.com/Forums/vstudio/en-US/6bbdc440-f8d0-48a8-b1a8-08f21aa9e4f5/strncat-reads-bytes-outside-of-source-buffer-range#3ec313ff-4373-4615-aed1-9a13300693f2
Update 5该问题将在下一个 VS 版本中修复。没有计划对旧版本进行修复。请参阅上面的“Microsoft Connect”链接。