riched20: Protect against pasting multi-line text in single-line control.

Signed-off-by: Rafał Harabień <rafalh1992@o2.pl>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Rafał Harabień 2017-11-15 02:18:53 +01:00 committed by Alexandre Julliard
parent 7aa4b6d170
commit 585dfa1409
3 changed files with 76 additions and 18 deletions

View file

@ -551,6 +551,10 @@ void ME_InsertTextFromCursor(ME_TextEditor *editor, int nCursor,
ME_DisplayItem *tp, *end_run, *run, *prev;
int eol_len = 0;
/* Check if new line is allowed for this control */
if (!(editor->styleFlags & ES_MULTILINE))
break;
/* Find number of CR and LF in end of paragraph run */
if (*pos =='\r')
{

View file

@ -176,7 +176,7 @@
+ ES_DISABLENOSCROLL (scrollbar is always visible)
- ES_EX_NOCALLOLEINIT
+ ES_LEFT
- ES_MULTILINE (currently single line controls aren't supported)
+ ES_MULTILINE
- ES_NOIME
- ES_READONLY (I'm not sure if beeping is the proper behaviour)
+ ES_RIGHT
@ -3421,21 +3421,7 @@ static void ME_SetText(ME_TextEditor *editor, void *text, BOOL unicode)
int textLen;
LPWSTR wszText = ME_ToUnicode(codepage, text, &textLen);
if (textLen > 0)
{
int len = -1;
/* uses default style! */
if (!(editor->styleFlags & ES_MULTILINE))
{
WCHAR *p = wszText;
while (*p != '\0' && *p != '\r' && *p != '\n') p++;
len = p - wszText;
}
ME_InsertTextFromCursor(editor, 0, wszText, len, editor->pBuffer->pDefaultStyle);
}
ME_InsertTextFromCursor(editor, 0, wszText, textLen, editor->pBuffer->pDefaultStyle);
ME_EndToUnicode(codepage, wszText);
}

View file

@ -70,6 +70,10 @@ static HWND new_richedit(HWND parent) {
return new_window(RICHEDIT_CLASS20A, ES_MULTILINE, parent);
}
static HWND new_richedit_with_style(HWND parent, DWORD style) {
return new_window(RICHEDIT_CLASS20A, style, parent);
}
static HWND new_richeditW(HWND parent) {
return new_windowW(RICHEDIT_CLASS20W, ES_MULTILINE, parent);
}
@ -3748,6 +3752,20 @@ static void test_WM_SETTEXT(void)
TEST_SETTEXTW(urtftextW, urtftextW) /* interpreted as ascii text */
DestroyWindow(hwndRichEdit);
#undef TEST_SETTEXTW
/* Single-line richedit */
hwndRichEdit = new_richedit_with_style(NULL, 0);
result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"line1\r\nline2");
ok(result == 1, "WM_SETTEXT returned %ld, expected 12\n", result);
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buf);
ok(result == 5, "WM_GETTEXT returned %ld, expected 5\n", result);
ok(!strcmp(buf, "line1"), "WM_GETTEXT returned incorrect string '%s'\n", buf);
result = SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)"{\\rtf1 ABC\\rtlpar\\par DEF\\par HIJ\\pard\\par}");
ok(result == 1, "WM_SETTEXT returned %ld, expected 1\n", result);
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buf);
ok(result == 3, "WM_GETTEXT returned %ld, expected 3\n", result);
ok(!strcmp(buf, "ABC"), "WM_GETTEXT returned incorrect string '%s'\n", buf);
DestroyWindow(hwndRichEdit);
}
/* Set *pcb to one to show that the remaining cb-1 bytes are not
@ -4406,6 +4424,17 @@ static void test_EM_SETTEXTEX(void)
}
DestroyWindow(hwndRichEdit);
/* Single-line richedit */
hwndRichEdit = new_richedit_with_style(NULL, 0);
setText.flags = ST_DEFAULT;
setText.codepage = CP_ACP;
result = SendMessageA(hwndRichEdit, EM_SETTEXTEX, (WPARAM)&setText, (LPARAM)"line1\r\nline2");
ok(result == 1, "EM_SETTEXTEX incorrectly returned %d, expected 1\n", result);
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)bufACP);
ok(result == 5, "WM_GETTEXT incorrectly returned %d, expected 5\n", result);
ok(!strcmp(bufACP, "line1"), "EM_SETTEXTEX: Test single-line text: Result: %s\n", bufACP);
DestroyWindow(hwndRichEdit);
}
static void test_EM_LIMITTEXT(void)
@ -5351,6 +5380,15 @@ static void test_EM_REPLACESEL(int redraw)
SendMessageA(hwndRichEdit, WM_SETREDRAW, TRUE, 0);
DestroyWindow(hwndRichEdit);
/* Single-line richedit */
hwndRichEdit = new_richedit_with_style(NULL, 0);
r = SendMessageA(hwndRichEdit, EM_REPLACESEL, 0, (LPARAM)"line1\r\nline2");
ok(r == 12, "EM_REPLACESEL returned %d, expected 12\n", r);
r = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
ok(r == 5, "WM_GETTEXT returned %d, expected 5\n", r);
ok(!strcmp(buffer, "line1"), "WM_GETTEXT returned incorrect string '%s'\n", buffer);
DestroyWindow(hwndRichEdit);
}
/* Native riched20 inspects the keyboard state (e.g. GetKeyState)
@ -5498,21 +5536,39 @@ static void test_WM_PASTE(void)
"test paste: strcmp = %i, actual = '%s'\n", result, buffer);
release_key(VK_CONTROL);
/* Copy multiline text to clipboard for future use */
SendMessageA(hwndRichEdit, WM_SETTEXT, 0, (LPARAM)text3);
SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1);
SendMessageA(hwndRichEdit, WM_COPY, 0, 0);
SendMessageA(hwndRichEdit, EM_SETSEL, 0, 0);
/* Paste into read-only control */
result = SendMessageA(hwndRichEdit, EM_SETREADONLY, TRUE, 0);
SendMessageA(hwndRichEdit, WM_PASTE, 0, 0);
SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
result = strcmp(buffer,"cut\r\n");
result = strcmp(buffer, text3);
ok(result == 0,
"test paste: strcmp = %i, actual = '%s'\n", result, buffer);
/* Cut from read-only control */
SendMessageA(hwndRichEdit, EM_SETSEL, 0, -1);
SendMessageA(hwndRichEdit, WM_CUT, 0, 0);
result = strcmp(buffer,"cut\r\n");
SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
result = strcmp(buffer, text3);
ok(result == 0,
"test paste: strcmp = %i, actual = '%s'\n", result, buffer);
/* FIXME: Wine doesn't flush Ole clipboard when window is destroyed so do it manually */
OleFlushClipboard();
DestroyWindow(hwndRichEdit);
/* Paste multi-line text into single-line control */
hwndRichEdit = new_richedit_with_style(NULL, 0);
SendMessageA(hwndRichEdit, WM_PASTE, 0, 0);
SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
result = strcmp(buffer, "testing paste");
ok(result == 0,
"test paste: strcmp = %i, actual = '%s'\n", result, buffer);
DestroyWindow(hwndRichEdit);
}
@ -5973,6 +6029,18 @@ static void test_EM_STREAMIN(void)
ok(es.dwError == 0, "EM_STREAMIN: Test 5 set error %d, expected %d\n", es.dwError, 0);
DestroyWindow(hwndRichEdit);
/* Single-line richedit */
hwndRichEdit = new_richedit_with_style(NULL, 0);
ptr = "line1\r\nline2";
es.dwCookie = (DWORD_PTR)&ptr;
es.dwError = 0;
es.pfnCallback = test_EM_STREAMIN_esCallback;
result = SendMessageA(hwndRichEdit, EM_STREAMIN, SF_TEXT, (LPARAM)&es);
ok(result == 12, "got %ld, expected %d\n", result, 12);
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
ok (!strcmp(buffer, "line1"),
"EM_STREAMIN: Unexpected text '%s'\n", buffer);
}
static void test_EM_StreamIn_Undo(void)