[PATCH 1/3] user32: The app own the text buffer memory after a EM_GETHANDLE [bug 4742]

Detlef Riekenberg wine.dev at web.de
Thu May 2 16:50:17 CDT 2013


The newtestbot failures on win8 are not related to this patch.
http://newtestbot.winehq.org/JobDetails.pl?Key=824

After a EM_GETHANDLE, the app is the owner of the text buffer memory handle
and the app is responsible for the LocalFree().

Behavior of messages is undocumented after EM_GETHANDLE

Some messages return a previous result (EM_GETHANDLE or WM_GETTEXTLENGTH).
Some messages just fail (WM_SETTEXT, which does not create a new buffer).
After the app LocalFree() the old memory handle, various messages crash
the app (EM_GETHANDLE or WM_SETTEXT as examples)

--
By by ... Detlef
---
 dlls/user32/edit.c |   23 ++++++++++++++++++++---
 1 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/dlls/user32/edit.c b/dlls/user32/edit.c
index 74e0ea4..d9e2ff9 100644
--- a/dlls/user32/edit.c
+++ b/dlls/user32/edit.c
@@ -151,6 +151,7 @@ typedef struct
 	HLOCAL hloc32W;			/* our unicode local memory block */
 	HLOCAL hloc32A;			/* alias for ANSI control receiving EM_GETHANDLE
 				   	   or EM_SETHANDLE */
+        HLOCAL hlocapp;                 /* The text buffer handle belongs to the app */
 	/*
 	 * IME Data
 	 */
@@ -1264,6 +1265,10 @@ static inline void text_buffer_changed(EDITSTATE *es)
  */
 static void EDIT_LockBuffer(EDITSTATE *es)
 {
+        /* The text buffer handle belongs to the app */
+        if(es->hlocapp)
+            return;
+
 	if (!es->text) {
 
 	    if(!es->hloc32W) return;
@@ -1305,6 +1310,9 @@ static void EDIT_LockBuffer(EDITSTATE *es)
  */
 static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force)
 {
+        /* The text buffer handle belongs to the app */
+        if(es->hlocapp)
+            return;
 
 	/* Edit window might be already destroyed */
 	if(!IsWindow(es->hwndSelf))
@@ -1353,7 +1361,7 @@ static void EDIT_UnlockBuffer(EDITSTATE *es, BOOL force)
                     LocalUnlock(es->hloc32A);
 		}
 
-		LocalUnlock(es->hloc32W);
+                if (es->text) LocalUnlock(es->hloc32W);
 		es->text = NULL;
 	    }
 	    else {
@@ -2485,6 +2493,11 @@ static HLOCAL EDIT_EM_GetHandle(EDITSTATE *es)
 	    hLocal = es->hloc32A;
 	}
 
+        EDIT_UnlockBuffer(es, TRUE);
+
+        /* The text buffer handle belongs to the app */
+        es->hlocapp = hLocal;
+        /* The app has knowledge of the text buffer handle */
         es->flags |= EF_APP_HAS_HANDLE;
 	TRACE("Returning %p, LocalSize() = %ld\n", hLocal, LocalSize(hLocal));
 	return hLocal;
@@ -2826,6 +2839,9 @@ static void EDIT_EM_SetHandle(EDITSTATE *es, HLOCAL hloc)
 
 	es->buffer_size = LocalSize(es->hloc32W)/sizeof(WCHAR) - 1;
 
+        /* The text buffer handle belongs to the control */
+        es->hlocapp = NULL;
+        /* The app has knowledge of the text buffer handle */
         es->flags |= EF_APP_HAS_HANDLE;
 	EDIT_LockBuffer(es);
 
@@ -4597,10 +4613,11 @@ static LRESULT EDIT_WM_NCDestroy(EDITSTATE *es)
 {
 	LINEDEF *pc, *pp;
 
-	if (es->hloc32W) {
+        /* The app can own the text buffer handle */
+        if (es->hloc32W && (es->hloc32W != es->hlocapp)) {
 		LocalFree(es->hloc32W);
 	}
-	if (es->hloc32A) {
+        if (es->hloc32A && (es->hloc32A != es->hlocapp)) {
 		LocalFree(es->hloc32A);
 	}
 	EDIT_InvalidateUniscribeData(es);
-- 
1.7.5.4




More information about the wine-patches mailing list