在缓冲区溢出时自动截断和空终止字符串缓冲区

Blu*_*789 5 c++ winapi truncate buffer-overflow

我有以下代码,它可以从指定父窗口的所有子窗口加载文本。它工作正常,但有时,有一些父窗口(例如打开的带有很长 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;
}
Run Code Online (Sandbox Code Playgroud)

该行SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));有时会导致缓冲区溢出并且我的应用程序崩溃。

我知道如何检测这种溢出if (TEXT_LENGTH > 32767),但我无法动态增加缓冲区的大小szText

正如问题标题所提到的,我不想增加它的大小,我只想截断和空终止返回文本到最大缓冲区大小32767(如果TEXT_LENGTH已结束32767)并将其分配szWindowText用于其他目的。

任何帮助是极大的赞赏。

Ser*_*sen 1

一些东西:

  1. 最好动态地将缓冲区分配给TEXT_LENGTH。('\0' 为 +1)
  2. 将WM_GETTEXT中的szText的&运算符去掉,只需要包含的地址,而不是指针的地址
  3. 当您显式使用 char 时,请使用 SendMessageA,否则 Visual Studio 默认使用 wchar_t 和 SendMessageW。SendMessage 是一个宏,根据您的项目设置,它会扩展为 wchar_t 或 char。或者将 TCHAR 类型与 SendMessage 一起使用,它也可以扩展为正确的类型。

DWORD l = SendMessage(hWnd, WM_GETTEXTLENGTH, NULL, NULL);

if (l > 0){
   TCHAR *szText = new TCHAR[l + 1];
   SendMessage(hWnd, WM_GETTEXT, (WPARAM)l + 1, reinterpret_cast<LPARAM>(szText));

  // use szText

   delete[] szText;
}
Run Code Online (Sandbox Code Playgroud)