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

时间:2017-08-09 11:04:29

标签: 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;
}

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

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

正如问题标题所提到的,我不想增加它的大小,我只想截断并将null终止返回文本到最大缓冲区大小32767(如果TEXT_LENGTH超过{{ 1}})并将其分配给32767以用于其他目的。

非常感谢任何帮助。

3 个答案:

答案 0 :(得分:1)

基本上你需要为\n腾出空间,为什么你要插入它,而这样做的方法是在sizeof szText-1调用中使用WM_GETTEXT而不是32767。

注意如果您必须使用Simonyi表示法,请不要在不适用的地方使用它。 szText没有空格终止,您仅用于WM_GETTEXT的结果。

答案 1 :(得分:0)

一些事情:

  1. 最好将缓冲区动态分配给TEXT_LENGTH。 (+1代表'\ 0')
  2. 放弃&amp; WM_GETTEXT中szText的运算符,你只需要包含的地址,而不是指针的地址
  3. 当您明确使用char时,请使用SendMessageA,否则visual studio默认使用SendMessageW来使用wchar_t。 SendMessage是一个宏,根据您的项目设置扩展为wchar_t或char。或者将TCHAR类型与SendMessage一起使用,它也会扩展为正确的类型。
  4. 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;
    }
    

答案 2 :(得分:0)

SendMessage(hWnd, WM_GETTEXT, (WPARAM)32767, reinterpret_cast<LPARAM>(&szText));永远不会导致缓冲区溢出,因为提供了正确的缓冲区大小。实际上根本不需要这个临时缓冲区。

您真正的问题是您在不知道目标缓冲区大小的情况下将字符附加到以lParam提供的指针中。您应该在供应目的地缓冲区大小。