[PATCH 2/2] riched20: Protect read-only Richedit against pasting and cutting data.

Rafał Harabień rafalh1992 at o2.pl
Sun Nov 5 12:28:39 CST 2017


Signed-off-by: Rafał Harabień <rafalh1992 at o2.pl>
---
 dlls/riched20/editor.c       | 60 +++++++++++++++++++++++---------------------
 dlls/riched20/tests/editor.c | 15 +++++++++++
 2 files changed, 47 insertions(+), 28 deletions(-)

diff --git a/dlls/riched20/editor.c b/dlls/riched20/editor.c
index a7b1bc7..3da19fa 100644
--- a/dlls/riched20/editor.c
+++ b/dlls/riched20/editor.c
@@ -2294,6 +2294,13 @@ static BOOL paste_special(ME_TextEditor *editor, UINT cf, REPASTESPECIAL *ps, BO
     struct paste_format *format;
     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();
 
     if (ps && ps->dwAspect != DVASPECT_CONTENT)
@@ -2351,6 +2358,29 @@ static BOOL ME_Copy(ME_TextEditor *editor, const ME_Cursor *start, int nChars)
   return SUCCEEDED(hr);
 }
 
+static BOOL copy_or_cut(ME_TextEditor *editor, BOOL cut)
+{
+    BOOL result;
+    int nOfs, nChars;
+    int nStartCur = ME_GetSelectionOfs(editor, &nOfs, &nChars);
+    ME_Cursor *selStart = &editor->pCursors[nStartCur];
+
+    if (cut && (editor->styleFlags & ES_READONLY)) {
+        MessageBeep(MB_ICONERROR);
+        return FALSE;
+    }
+
+    nChars -= nOfs;
+    result = ME_Copy(editor, selStart, nChars);
+    if (result && cut)
+    {
+      ME_InternalDeleteText(editor, selStart, nChars, FALSE);
+      ME_CommitUndo(editor);
+      ME_UpdateRepaint(editor, TRUE);
+    }
+    return result;
+}
+
 /* helper to send a msg filter notification */
 static BOOL
 ME_FilterEvent(ME_TextEditor *editor, UINT msg, WPARAM* wParam, LPARAM* lParam)
@@ -2645,22 +2675,7 @@ ME_KeyDown(ME_TextEditor *editor, WORD nKey)
     case 'C':
     case 'X':
       if (ctrl_is_down)
-      {
-        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;
-      }
+        return copy_or_cut(editor, nKey == 'X');
       break;
     case 'Z':
       if (ctrl_is_down)
@@ -4068,19 +4083,8 @@ LRESULT ME_HandleMessage(ME_TextEditor *editor, UINT msg, WPARAM wParam,
     return 0;
   case WM_CUT:
   case WM_COPY:
-  {
-    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);
-    }
+    copy_or_cut(editor, msg == WM_CUT);
     return 0;
-  }
   case WM_GETTEXTLENGTH:
   {
     GETTEXTLENGTHEX how;
diff --git a/dlls/riched20/tests/editor.c b/dlls/riched20/tests/editor.c
index 20189c6..a19ec85 100644
--- a/dlls/riched20/tests/editor.c
+++ b/dlls/riched20/tests/editor.c
@@ -5498,6 +5498,21 @@ static void test_WM_PASTE(void)
         "test paste: strcmp = %i, actual = '%s'\n", result, buffer);
     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);
 }
 
-- 
2.7.4




More information about the wine-patches mailing list