riched20: Protect read-only Richedit against pasting and cutting data.

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-06 23:12:23 +01:00 committed by Alexandre Julliard
parent d334097c09
commit 55412553e8
2 changed files with 49 additions and 28 deletions

View File

@ -2294,6 +2294,14 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO
struct paste_format *format; struct paste_format *format;
IDataObject *data; IDataObject *data;
/* Protect read-only edit control from modification */
if (editor->styleFlags & ES_READONLY)
{
if (!check_only)
MessageBeep(MB_ICONERROR);
return FALSE;
}
init_paste_formats(); init_paste_formats();
if (ps && ps->dwAspect != DVASPECT_CONTENT) if (ps && ps->dwAspect != DVASPECT_CONTENT)
@ -2351,6 +2359,30 @@ static BOOL ME_Copy(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
return SUCCEEDED(hr); return SUCCEEDED(hr);
} }
static BOOL copy_or_cut(ME_TextEditor *editor, BOOL cut)
{
BOOL result;
int offs, num_chars;
int start_cursor = ME_GetSelectionOfs(editor, &offs, &num_chars);
ME_Cursor *sel_start = &editor->pCursors[start_cursor];
if (cut && (editor->styleFlags & ES_READONLY))
{
MessageBeep(MB_ICONERROR);
return FALSE;
}
num_chars -= offs;
result = ME_Copy(editor, sel_start, num_chars);
if (result && cut)
{
ME_InternalDeleteText(editor, sel_start, num_chars, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor, TRUE);
}
return result;
}
/* helper to send a msg filter notification */ /* helper to send a msg filter notification */
static BOOL static BOOL
ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam) ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
@ -2645,22 +2677,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
case 'C': case 'C':
case 'X': case 'X':
if (ctrl_is_down) if (ctrl_is_down)
{ return copy_or_cut(editor, nKey == 'X');
BOOL result;
int nOfs, nChars;
int nStartCur = ME_GetSelectionOfs(editor, &nOfs, &nChars);
ME_Cursor *selStart = &editor->pCursors[nStartCur];
nChars -= nOfs;
result = ME_Copy(editor, selStart, nChars);
if (result && nKey == 'X')
{
ME_InternalDeleteText(editor, selStart, nChars, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor, TRUE);
}
return result;
}
break; break;
case 'Z': case 'Z':
if (ctrl_is_down) if (ctrl_is_down)
@ -4068,19 +4085,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
return 0; return 0;
case WM_CUT: case WM_CUT:
case WM_COPY: case WM_COPY:
{ copy_or_cut(editor, msg == WM_CUT);
int nFrom, nTo, nStartCur = ME_GetSelectionOfs(editor, &nFrom, &nTo);
int nChars = nTo - nFrom;
ME_Cursor *selStart = &editor->pCursors[nStartCur];
if (ME_Copy(editor, selStart, nChars) && msg == WM_CUT)
{
ME_InternalDeleteText(editor, selStart, nChars, FALSE);
ME_CommitUndo(editor);
ME_UpdateRepaint(editor, TRUE);
}
return 0; return 0;
}
case WM_GETTEXTLENGTH: case WM_GETTEXTLENGTH:
{ {
GETTEXTLENGTHEX how; GETTEXTLENGTHEX how;

View File

@ -5498,6 +5498,21 @@ static void test_WM_PASTE(void)
"test paste: strcmp = %i, actual = '%s'\n", result, buffer); "test paste: strcmp = %i, actual = '%s'\n", result, buffer);
release_key(VK_CONTROL); release_key(VK_CONTROL);
/* 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");
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");
ok(result == 0,
"test paste: strcmp = %i, actual = '%s'\n", result, buffer);
DestroyWindow(hwndRichEdit); DestroyWindow(hwndRichEdit);
} }