[COMCTL32] Fix edit UAF by importing wine commit fed0c33fe02a3fcb477086a32dc8d52c1e347889

This commit is contained in:
Mark Jansen 2022-10-27 23:52:36 +02:00
parent ed4b16b7ff
commit cf08f9271e
No known key found for this signature in database
GPG key ID: B39240EE84BEAE8B

View file

@ -160,15 +160,13 @@ typedef struct
#define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0) #define SWAP_UINT32(x,y) do { UINT temp = (UINT)(x); (x) = (UINT)(y); (y) = temp; } while(0)
#define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0) #define ORDER_UINT(x,y) do { if ((UINT)(y) < (UINT)(x)) SWAP_UINT32((x),(y)); } while(0)
/* used for disabled or read-only edit control */ static inline BOOL notify_parent(const EDITSTATE *es, INT code)
#define EDIT_NOTIFY_PARENT(es, wNotifyCode) \ {
do \ HWND hwnd = es->hwndSelf;
{ /* Notify parent which has created this edit control */ \ TRACE("notification %d sent to %p.\n", code, es->hwndParent);
TRACE("notification " #wNotifyCode " sent to hwnd=%p\n", es->hwndParent); \ SendMessageW(es->hwndParent, WM_COMMAND, MAKEWPARAM(GetWindowLongPtrW(es->hwndSelf, GWLP_ID), code), (LPARAM)es->hwndSelf);
SendMessageW(es->hwndParent, WM_COMMAND, \ return IsWindow(hwnd);
MAKEWPARAM(GetWindowLongPtrW((es->hwndSelf),GWLP_ID), wNotifyCode), \ }
(LPARAM)(es->hwndSelf)); \
} while(0)
static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap); static LRESULT EDIT_EM_PosFromChar(EDITSTATE *es, INT index, BOOL after_wrap);
@ -1293,7 +1291,7 @@ static BOOL EDIT_MakeFit(EDITSTATE *es, UINT size)
if (es->buffer_size < size) { if (es->buffer_size < size) {
WARN("FAILED ! We now have %d+1\n", es->buffer_size); WARN("FAILED ! We now have %d+1\n", es->buffer_size);
EDIT_NOTIFY_PARENT(es, EN_ERRSPACE); notify_parent(es, EN_ERRSPACE);
return FALSE; return FALSE;
} else { } else {
TRACE("We now have %d+1\n", es->buffer_size); TRACE("We now have %d+1\n", es->buffer_size);
@ -1340,7 +1338,7 @@ static void EDIT_UpdateTextRegion(EDITSTATE *es, HRGN hrgn, BOOL bErase)
{ {
if (es->flags & EF_UPDATE) { if (es->flags & EF_UPDATE) {
es->flags &= ~EF_UPDATE; es->flags &= ~EF_UPDATE;
EDIT_NOTIFY_PARENT(es, EN_UPDATE); if (!notify_parent(es, EN_UPDATE)) return;
} }
InvalidateRgn(es->hwndSelf, hrgn, bErase); InvalidateRgn(es->hwndSelf, hrgn, bErase);
} }
@ -1355,7 +1353,7 @@ static void EDIT_UpdateText(EDITSTATE *es, const RECT *rc, BOOL bErase)
{ {
if (es->flags & EF_UPDATE) { if (es->flags & EF_UPDATE) {
es->flags &= ~EF_UPDATE; es->flags &= ~EF_UPDATE;
EDIT_NOTIFY_PARENT(es, EN_UPDATE); if (!notify_parent(es, EN_UPDATE)) return;
} }
InvalidateRect(es->hwndSelf, rc, bErase); InvalidateRect(es->hwndSelf, rc, bErase);
} }
@ -1636,9 +1634,9 @@ static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy)
EDIT_UpdateScrollInfo(es); EDIT_UpdateScrollInfo(es);
} }
if (dx && !(es->flags & EF_HSCROLL_TRACK)) if (dx && !(es->flags & EF_HSCROLL_TRACK))
EDIT_NOTIFY_PARENT(es, EN_HSCROLL); notify_parent(es, EN_HSCROLL);
if (dy && !(es->flags & EF_VSCROLL_TRACK)) if (dy && !(es->flags & EF_VSCROLL_TRACK))
EDIT_NOTIFY_PARENT(es, EN_VSCROLL); notify_parent(es, EN_VSCROLL);
return TRUE; return TRUE;
} }
@ -2460,8 +2458,9 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
/* Issue the EN_MAXTEXT notification and continue with replacing text /* Issue the EN_MAXTEXT notification and continue with replacing text
* so that buffer limit is honored. */ * so that buffer limit is honored. */
if ((honor_limit) && (size > es->buffer_limit)) { if ((honor_limit) && (size > es->buffer_limit))
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); {
if (!notify_parent(es, EN_MAXTEXT)) return;
/* Buffer limit can be smaller than the actual length of text in combobox */ /* Buffer limit can be smaller than the actual length of text in combobox */
if (es->buffer_limit < (tl - (e-s))) if (es->buffer_limit < (tl - (e-s)))
strl = 0; strl = 0;
@ -2519,7 +2518,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
strl = 0; strl = 0;
e = s; e = s;
hrgn = CreateRectRgn(0, 0, 0, 0); hrgn = CreateRectRgn(0, 0, 0, 0);
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); if (!notify_parent(es, EN_MAXTEXT)) return;
} }
} }
else { else {
@ -2536,7 +2535,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
EDIT_CalcLineWidth_SL(es); EDIT_CalcLineWidth_SL(es);
} }
text_buffer_changed(es); text_buffer_changed(es);
EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); if (!notify_parent(es, EN_MAXTEXT)) return;
} }
} }
@ -2627,7 +2626,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r
if(send_update || (es->flags & EF_UPDATE)) if(send_update || (es->flags & EF_UPDATE))
{ {
es->flags &= ~EF_UPDATE; es->flags &= ~EF_UPDATE;
EDIT_NOTIFY_PARENT(es, EN_CHANGE); if (!notify_parent(es, EN_CHANGE)) return;
} }
EDIT_InvalidateUniscribeData(es); EDIT_InvalidateUniscribeData(es);
} }
@ -2877,7 +2876,7 @@ static BOOL EDIT_EM_Undo(EDITSTATE *es)
EDIT_EM_ReplaceSel(es, TRUE, utext, ulength, TRUE, TRUE); EDIT_EM_ReplaceSel(es, TRUE, utext, ulength, TRUE, TRUE);
EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE); EDIT_EM_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE);
/* send the notification after the selection start and end are set */ /* send the notification after the selection start and end are set */
EDIT_NOTIFY_PARENT(es, EN_CHANGE); if (!notify_parent(es, EN_CHANGE)) return TRUE;
EDIT_EM_ScrollCaret(es); EDIT_EM_ScrollCaret(es);
heap_free(utext); heap_free(utext);
@ -3379,8 +3378,8 @@ static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key)
{ {
if (EDIT_EM_SetSel(es, 0, get_text_length(es), FALSE)) if (EDIT_EM_SetSel(es, 0, get_text_length(es), FALSE))
{ {
EDIT_NOTIFY_PARENT(es, EN_UPDATE); if (!notify_parent(es, EN_UPDATE)) break;
EDIT_NOTIFY_PARENT(es, EN_CHANGE); notify_parent(es, EN_CHANGE);
} }
} }
break; break;
@ -3397,19 +3396,20 @@ static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key)
static LRESULT EDIT_WM_KillFocus(HTHEME theme, EDITSTATE *es) static LRESULT EDIT_WM_KillFocus(HTHEME theme, EDITSTATE *es)
{ {
UINT flags = RDW_INVALIDATE | RDW_UPDATENOW; UINT flags = RDW_INVALIDATE | RDW_UPDATENOW;
HWND hwndSelf = es->hwndSelf;
es->flags &= ~EF_FOCUSED; es->flags &= ~EF_FOCUSED;
DestroyCaret(); DestroyCaret();
if (!(es->style & ES_NOHIDESEL)) if (!(es->style & ES_NOHIDESEL))
EDIT_InvalidateText(es, es->selection_start, es->selection_end); EDIT_InvalidateText(es, es->selection_start, es->selection_end);
EDIT_NOTIFY_PARENT(es, EN_KILLFOCUS); if (!notify_parent(es, EN_KILLFOCUS)) return 0;
/* Throw away left over scroll when we lose focus */ /* Throw away left over scroll when we lose focus */
es->wheelDeltaRemainder = 0; es->wheelDeltaRemainder = 0;
if (theme) if (theme)
flags |= RDW_FRAME; flags |= RDW_FRAME;
RedrawWindow(es->hwndSelf, NULL, NULL, flags); RedrawWindow(hwndSelf, NULL, NULL, flags);
return 0; return 0;
} }
@ -3702,7 +3702,7 @@ static void EDIT_WM_SetFocus(HTHEME theme, EDITSTATE *es)
#endif #endif
EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP);
ShowCaret(es->hwndSelf); ShowCaret(es->hwndSelf);
EDIT_NOTIFY_PARENT(es, EN_SETFOCUS); if (!notify_parent(es, EN_SETFOCUS)) return;
if (theme) if (theme)
flags |= RDW_FRAME | RDW_ERASE; flags |= RDW_FRAME | RDW_ERASE;
@ -3806,8 +3806,8 @@ static void EDIT_WM_SetText(EDITSTATE *es, LPCWSTR text)
*/ */
if( !((es->style & ES_MULTILINE) || es->hwndListBox)) if( !((es->style & ES_MULTILINE) || es->hwndListBox))
{ {
EDIT_NOTIFY_PARENT(es, EN_UPDATE); if (!notify_parent(es, EN_UPDATE)) return;
EDIT_NOTIFY_PARENT(es, EN_CHANGE); if (!notify_parent(es, EN_CHANGE)) return;
} }
EDIT_EM_ScrollCaret(es); EDIT_EM_ScrollCaret(es);
EDIT_UpdateScrollInfo(es); EDIT_UpdateScrollInfo(es);
@ -4008,7 +4008,7 @@ static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos)
if (!dx) { if (!dx) {
/* force scroll info update */ /* force scroll info update */
EDIT_UpdateScrollInfo(es); EDIT_UpdateScrollInfo(es);
EDIT_NOTIFY_PARENT(es, EN_HSCROLL); notify_parent(es, EN_HSCROLL);
} }
break; break;
case SB_ENDSCROLL: case SB_ENDSCROLL:
@ -4131,7 +4131,7 @@ static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos)
{ {
/* force scroll info update */ /* force scroll info update */
EDIT_UpdateScrollInfo(es); EDIT_UpdateScrollInfo(es);
EDIT_NOTIFY_PARENT(es, EN_VSCROLL); notify_parent(es, EN_VSCROLL);
} }
break; break;
case SB_ENDSCROLL: case SB_ENDSCROLL: