Module: wine Branch: master Commit: 6653d430236d829ab499be858d3ef4fdccb0517d URL: http://source.winehq.org/git/wine.git/?a=commit;h=6653d430236d829ab499be858d...
Author: Rafał Harabień rafalh1992@o2.pl Date: Sun Nov 5 19:28:38 2017 +0100
user32: Protect single-line edit against pasting new line character.
Signed-off-by: Rafał Harabień rafalh1992@o2.pl Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/user32/edit.c | 18 +++++++++-- dlls/user32/tests/edit.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c index 00a7fba..ee9b45e 100644 --- a/dlls/user32/edit.c +++ b/dlls/user32/edit.c @@ -3077,7 +3077,8 @@ static inline BOOL EDIT_IsInsideDialog(EDITSTATE *es) static void EDIT_WM_Paste(EDITSTATE *es) { HGLOBAL hsrc; - LPWSTR src; + LPWSTR src, new_src, ptr; + int len;
/* Protect read-only edit control from modification */ if(es->style & ES_READONLY) @@ -3086,7 +3087,20 @@ static void EDIT_WM_Paste(EDITSTATE *es) OpenClipboard(es->hwndSelf); if ((hsrc = GetClipboardData(CF_UNICODETEXT))) { src = GlobalLock(hsrc); - EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE); + + /* Protect single-line edit against pasting new line character */ + if (!(es->style & ES_MULTILINE) && ((ptr = strchrW(src, '\n')))) { + len = ptr - src; + if (len && src[len - 1] == '\r') + --len; + new_src = HeapAlloc(GetProcessHeap(), 0, (len+1) * sizeof(WCHAR)); + if (new_src != NULL) { + lstrcpynW(new_src, src, len+1); + EDIT_EM_ReplaceSel(es, TRUE, new_src, TRUE, TRUE); + HeapFree(GetProcessHeap(), 0, new_src); + } + } else + EDIT_EM_ReplaceSel(es, TRUE, src, TRUE, TRUE); GlobalUnlock(hsrc); } else if (es->style & ES_PASSWORD) { diff --git a/dlls/user32/tests/edit.c b/dlls/user32/tests/edit.c index b9aa1c9..d842dce 100644 --- a/dlls/user32/tests/edit.c +++ b/dlls/user32/tests/edit.c @@ -867,7 +867,7 @@ static LRESULT CALLBACK edit3_wnd_procA(HWND hWnd, UINT msg, WPARAM wParam, LPAR return DefWindowProcA(hWnd, msg, wParam, lParam); }
-/* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notificatisons sent in response +/* Test behaviour of WM_SETTEXT, WM_REPLACESEL and notifications sent in response * to these messages. */ static void test_edit_control_3(void) @@ -969,6 +969,19 @@ static void test_edit_control_3(void) ok(lstrlenA(str) == len, "text shouldn't have been truncated\n"); test_notify(1, 0, 1);
+ SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)""); + zero_notify(); + SendMessageA(hWnd, EM_REPLACESEL, 0, (LPARAM)str2); + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n"); + test_notify(1, 0, 1); + + zero_notify(); + SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)str2); + len = SendMessageA(hWnd, WM_GETTEXTLENGTH, 0, 0); + ok(lstrlenA(str2) == len, "text shouldn't have been truncated\n"); + test_notify(1, 0, 1); + SendMessageA(hWnd, EM_SETLIMITTEXT, 5, 0);
SendMessageA(hWnd, WM_SETTEXT, 0, (LPARAM)""); @@ -2831,6 +2844,74 @@ static void test_EM_GETHANDLE(void) DestroyWindow(hEdit); }
+static void test_paste(void) +{ + HWND hEdit, hMultilineEdit; + HANDLE hmem, hmem_ret; + char *buffer; + int r, len; + static const char *str = "this is a simple text"; + static const char *str2 = "first line\r\nsecond line"; + + hEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL, 0); + hMultilineEdit = create_editcontrol(ES_AUTOHSCROLL | ES_AUTOVSCROLL | ES_MULTILINE, 0); + + /* Prepare clipboard data with simple text */ + hmem = GlobalAlloc(GMEM_MOVEABLE, 255); + ok(hmem != NULL, "got %p (expected != NULL)\n", hmem); + buffer = GlobalLock(hmem); + ok(buffer != NULL, "got %p (expected != NULL)\n", buffer); + strcpy(buffer, str); + GlobalUnlock(hmem); + + r = OpenClipboard(hEdit); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + r = EmptyClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + hmem_ret = SetClipboardData(CF_TEXT, hmem); + ok(hmem_ret == hmem, "expected %p, got %p\n", hmem, hmem_ret); + r = CloseClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + + /* Paste single line */ + SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); + r = SendMessageA(hEdit, WM_PASTE, 0, 0); + len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); + ok(strlen(str) == len, "expected %d, got %d\n", strlen(str), len); + + /* Prepare clipboard data with multiline text */ + hmem = GlobalAlloc(GMEM_MOVEABLE, 255); + ok(hmem != NULL, "got %p (expected != NULL)\n", hmem); + buffer = GlobalLock(hmem); + ok(buffer != NULL, "got %p (expected != NULL)\n", buffer); + strcpy(buffer, str2); + GlobalUnlock(hmem); + + r = OpenClipboard(hEdit); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + r = EmptyClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + hmem_ret = SetClipboardData(CF_TEXT, hmem); + ok(hmem_ret == hmem, "expected %p, got %p\n", hmem, hmem_ret); + r = CloseClipboard(); + ok(r == TRUE, "expected %d, got %d\n", TRUE, r); + + /* Paste multiline text in singleline edit - should be cut */ + SendMessageA(hEdit, WM_SETTEXT, 0, (LPARAM)""); + r = SendMessageA(hEdit, WM_PASTE, 0, 0); + len = SendMessageA(hEdit, WM_GETTEXTLENGTH, 0, 0); + ok(strlen("first line") == len, "expected %d, got %d\n", strlen("first line"), len); + + /* Paste multiline text in multiline edit */ + SendMessageA(hMultilineEdit, WM_SETTEXT, 0, (LPARAM)""); + r = SendMessageA(hMultilineEdit, WM_PASTE, 0, 0); + len = SendMessageA(hMultilineEdit, WM_GETTEXTLENGTH, 0, 0); + ok(strlen(str2) == len, "expected %d, got %d\n", strlen(str2), len); + + /* Cleanup */ + DestroyWindow(hEdit); + DestroyWindow(hMultilineEdit); +}
START_TEST(edit) { @@ -2871,6 +2952,7 @@ START_TEST(edit) win_skip("EndMenu is not available\n");
test_EM_GETHANDLE(); + test_paste();
UnregisterWindowClasses(); }