From cf08f9271e4ec30bbf01f3072e6af045156c4f34 Mon Sep 17 00:00:00 2001 From: Mark Jansen Date: Thu, 27 Oct 2022 23:52:36 +0200 Subject: [PATCH] [COMCTL32] Fix edit UAF by importing wine commit fed0c33fe02a3fcb477086a32dc8d52c1e347889 --- dll/win32/comctl32/edit.c | 58 +++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/dll/win32/comctl32/edit.c b/dll/win32/comctl32/edit.c index 07277740168..15365715bb3 100644 --- a/dll/win32/comctl32/edit.c +++ b/dll/win32/comctl32/edit.c @@ -160,15 +160,13 @@ typedef struct #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) -/* used for disabled or read-only edit control */ -#define EDIT_NOTIFY_PARENT(es, wNotifyCode) \ - do \ - { /* Notify parent which has created this edit control */ \ - TRACE("notification " #wNotifyCode " sent to hwnd=%p\n", es->hwndParent); \ - SendMessageW(es->hwndParent, WM_COMMAND, \ - MAKEWPARAM(GetWindowLongPtrW((es->hwndSelf),GWLP_ID), wNotifyCode), \ - (LPARAM)(es->hwndSelf)); \ - } while(0) +static inline BOOL notify_parent(const EDITSTATE *es, INT code) +{ + HWND hwnd = es->hwndSelf; + TRACE("notification %d sent to %p.\n", code, es->hwndParent); + SendMessageW(es->hwndParent, WM_COMMAND, MAKEWPARAM(GetWindowLongPtrW(es->hwndSelf, GWLP_ID), code), (LPARAM)es->hwndSelf); + return IsWindow(hwnd); +} 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) { WARN("FAILED ! We now have %d+1\n", es->buffer_size); - EDIT_NOTIFY_PARENT(es, EN_ERRSPACE); + notify_parent(es, EN_ERRSPACE); return FALSE; } else { 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) { es->flags &= ~EF_UPDATE; - EDIT_NOTIFY_PARENT(es, EN_UPDATE); + if (!notify_parent(es, EN_UPDATE)) return; } 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) { es->flags &= ~EF_UPDATE; - EDIT_NOTIFY_PARENT(es, EN_UPDATE); + if (!notify_parent(es, EN_UPDATE)) return; } InvalidateRect(es->hwndSelf, rc, bErase); } @@ -1636,9 +1634,9 @@ static BOOL EDIT_EM_LineScroll_internal(EDITSTATE *es, INT dx, INT dy) EDIT_UpdateScrollInfo(es); } 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)) - EDIT_NOTIFY_PARENT(es, EN_VSCROLL); + notify_parent(es, EN_VSCROLL); 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 * so that buffer limit is honored. */ - if ((honor_limit) && (size > es->buffer_limit)) { - EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); + if ((honor_limit) && (size > es->buffer_limit)) + { + if (!notify_parent(es, EN_MAXTEXT)) return; /* Buffer limit can be smaller than the actual length of text in combobox */ if (es->buffer_limit < (tl - (e-s))) strl = 0; @@ -2519,7 +2518,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r strl = 0; e = s; hrgn = CreateRectRgn(0, 0, 0, 0); - EDIT_NOTIFY_PARENT(es, EN_MAXTEXT); + if (!notify_parent(es, EN_MAXTEXT)) return; } } else { @@ -2536,7 +2535,7 @@ static void EDIT_EM_ReplaceSel(EDITSTATE *es, BOOL can_undo, const WCHAR *lpsz_r EDIT_CalcLineWidth_SL(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)) { es->flags &= ~EF_UPDATE; - EDIT_NOTIFY_PARENT(es, EN_CHANGE); + if (!notify_parent(es, EN_CHANGE)) return; } 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_SetSel(es, es->undo_position, es->undo_position + es->undo_insert_count, FALSE); /* 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); 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)) { - EDIT_NOTIFY_PARENT(es, EN_UPDATE); - EDIT_NOTIFY_PARENT(es, EN_CHANGE); + if (!notify_parent(es, EN_UPDATE)) break; + notify_parent(es, EN_CHANGE); } } break; @@ -3397,19 +3396,20 @@ static LRESULT EDIT_WM_KeyDown(EDITSTATE *es, INT key) static LRESULT EDIT_WM_KillFocus(HTHEME theme, EDITSTATE *es) { UINT flags = RDW_INVALIDATE | RDW_UPDATENOW; + HWND hwndSelf = es->hwndSelf; es->flags &= ~EF_FOCUSED; DestroyCaret(); if (!(es->style & ES_NOHIDESEL)) 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 */ es->wheelDeltaRemainder = 0; if (theme) flags |= RDW_FRAME; - RedrawWindow(es->hwndSelf, NULL, NULL, flags); + RedrawWindow(hwndSelf, NULL, NULL, flags); return 0; } @@ -3702,7 +3702,7 @@ static void EDIT_WM_SetFocus(HTHEME theme, EDITSTATE *es) #endif EDIT_SetCaretPos(es, es->selection_end, es->flags & EF_AFTER_WRAP); ShowCaret(es->hwndSelf); - EDIT_NOTIFY_PARENT(es, EN_SETFOCUS); + if (!notify_parent(es, EN_SETFOCUS)) return; if (theme) 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)) { - EDIT_NOTIFY_PARENT(es, EN_UPDATE); - EDIT_NOTIFY_PARENT(es, EN_CHANGE); + if (!notify_parent(es, EN_UPDATE)) return; + if (!notify_parent(es, EN_CHANGE)) return; } EDIT_EM_ScrollCaret(es); EDIT_UpdateScrollInfo(es); @@ -4008,7 +4008,7 @@ static LRESULT EDIT_WM_HScroll(EDITSTATE *es, INT action, INT pos) if (!dx) { /* force scroll info update */ EDIT_UpdateScrollInfo(es); - EDIT_NOTIFY_PARENT(es, EN_HSCROLL); + notify_parent(es, EN_HSCROLL); } break; case SB_ENDSCROLL: @@ -4131,7 +4131,7 @@ static LRESULT EDIT_WM_VScroll(EDITSTATE *es, INT action, INT pos) { /* force scroll info update */ EDIT_UpdateScrollInfo(es); - EDIT_NOTIFY_PARENT(es, EN_VSCROLL); + notify_parent(es, EN_VSCROLL); } break; case SB_ENDSCROLL: