【发布时间】:2017-08-09 11:04:28
【问题描述】:
我有以下代码,它可以从指定父窗口的所有子窗口加载文本。它工作正常,但有时,有一些父窗口(例如打开的记事本带有很长的 C++ 源文件)有大量文本并导致缓冲区溢出。
BOOL CALLBACK EnumChildProc(__in HWND hWnd, __in LPARAM lParam) {
LRESULT TEXT_LENGTH = NULL;
WCHAR szText[32767];
LPWSTR szWindowText;
UINT nBuffer = NULL, nText = NULL;
szWindowText = reinterpret_cast<LPWSTR>(lParam); szText[0] = L'\0';
nBuffer = (UINT)wcslen(szWindowText);
TEXT_LENGTH = SendMessage(hWnd, WM_GETTEXTLENGTH, NULL, NULL);
if (TEXT_LENGTH > NULL)
{
SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));
szText[TEXT_LENGTH] = L'\n'; szText[TEXT_LENGTH + 1] = L'\0';
while ((nBuffer < 32766) && (szText[nText] != L'\0'))
{ szWindowText[nBuffer++] = szText[nText++]; }
szWindowText[nBuffer] = L'\0';
}
return TRUE;
}
SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText)); 行有时会导致缓冲区溢出,我的应用程序崩溃。
我知道如何检测像if (TEXT_LENGTH > 32767) 这样的溢出,但我无法动态增加缓冲区szText 的大小。
正如问题标题所提到的,我不想增加它的大小,我只想截断和空终止返回文本到32767 的最大缓冲区大小(如果TEXT_LENGTH 超过32767)并分配将其转至szWindowText 以用于其他目的。
非常感谢任何帮助。
【问题讨论】:
-
不要将整数与
NULL进行比较,或将整数初始化为它。NULL应该是一个空指针。即使使用NULL定义为0在语义上是错误的,并且会误导阅读您的代码的人。 -
WCHAR szText[32767]!!!为什么不使用 std::wstring 并在知道长度后动态调整其大小? -
SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));永远不会导致缓冲区溢出,因为提供了正确大小的缓冲区。实际上这个临时缓冲区根本不需要。您真正的问题是您在不知道目标缓冲区大小的情况下写入以lParam提供的指针。 -
@VTT 是的,可以,您可以使用
&some_string_object[0]获取指向字符串中第一个元素的指针(正确调整大小后)。 -
@Blueeyes789 我不知道。 reading the documentation 怎么样?
标签: c++ winapi truncate buffer-overflow