昨天写程序,Debug 版本运行正常,Release 版本却总是崩溃。经过一番苦战,终于弄清楚了崩溃的原因。其实说简单也简单,根本不是老汉的错误,而是微软的 RichEdit 控件有错误。
按照微软的规范,窗口对 WM_GETTEXT 消息的响应中要对用户提供的缓冲区长度进行检查,但 RichEdit 控件对该消息的响应代码中存在问题,会导致当文本是中英文混合(或者是只要不是全英文?)的时候,不理会用户传入的缓冲区大小的限制,而直接向缓冲区内复制超长的文本,从而覆盖用户程序的代码或数据。
示例代码如下,在 Windows XP SP2 上测试通过。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
#include <windows.h> #include <tchar.h> int _tmain() { LoadLibrary(TEXT("Riched20.dll")); // 5.30.23.1221 LPCTSTR pszContent = TEXT("I am 张老汉,难道 you are 李老汉?"); HWND hwnd = CreateWindowEx(0, TEXT("RichEdit20W"), pszContent, WS_OVERLAPPEDWINDOW, 0, 0, 0, 0, NULL, NULL, NULL, NULL); #define _BUF_SIZE 30 TCHAR szText[_BUF_SIZE] = { 0 }; UINT cch = SendMessage(hwnd, WM_GETTEXT, _BUF_SIZE, (LPARAM)szText); if(cch > _BUF_SIZE) MessageBox(NULL, TEXT("Buffer overrun found!"), NULL, MB_OK); else if(cch) MessageBox(NULL, szText, NULL, MB_OK); else MessageBox(NULL, TEXT("Get window text failed!"), NULL, MB_OK); #undef _BUF_SIZE return 0; } |