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:
parent
d334097c09
commit
55412553e8
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue