[PATCH v3 06/10] shell32/autocomplete: Dynamically allocate hwndText so it can handle arbitrary sizes

Gabriel Ivăncescu gabrielopcode at gmail.com
Sat Sep 8 06:50:52 CDT 2018


Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
---

v3: Split from the next patch in the series, even if some of the added code
will be removed, hopefully that's ok.

 dlls/shell32/autocomplete.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/dlls/shell32/autocomplete.c b/dlls/shell32/autocomplete.c
index 3fed020..5038bb5 100644
--- a/dlls/shell32/autocomplete.c
+++ b/dlls/shell32/autocomplete.c
@@ -136,10 +136,11 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
 {
     IAutoCompleteImpl *This = GetPropW(hwnd, autocomplete_propertyW);
     HRESULT hr;
-    WCHAR hwndText[255];
+    WCHAR *hwndText;
+    UINT len, size, cpt;
     RECT r;
     BOOL displayall = FALSE;
-    int cpt, height, sel;
+    int height, sel;
 
     if (!This->enabled) return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
 
@@ -156,10 +157,11 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
             }
             return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
         case WM_KEYUP:
-        {
-            int len;
-
-            GetWindowTextW(hwnd, hwndText, ARRAY_SIZE(hwndText));
+            len = SendMessageW(hwnd, WM_GETTEXTLENGTH, 0, 0);
+            size = len+1;
+            if (!(hwndText = heap_alloc(size * sizeof(WCHAR))))
+                return 0;
+            len = SendMessageW(hwnd, WM_GETTEXT, size, (LPARAM)hwndText);
 
             switch(wParam) {
                 case VK_RETURN:
@@ -167,7 +169,6 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                     if (This->quickComplete && (GetKeyState(VK_CONTROL) & 0x8000))
                     {
                         WCHAR *buf;
-                        size_t len = strlenW(hwndText);
                         size_t sz = strlenW(This->quickComplete) + 1 + len;
                         if ((buf = heap_alloc(sz * sizeof(WCHAR))))
                         {
@@ -180,9 +181,11 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
 
                     if (This->options & ACO_AUTOSUGGEST)
                         ShowWindow(This->hwndListBox, SW_HIDE);
+                    heap_free(hwndText);
                     return 0;
                 case VK_LEFT:
                 case VK_RIGHT:
+                    heap_free(hwndText);
                     return 0;
                 case VK_UP:
                 case VK_DOWN:
@@ -198,6 +201,7 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                          /* We must display all the entries */
                          displayall = TRUE;
                     } else {
+                        heap_free(hwndText);
                         if (IsWindowVisible(This->hwndListBox)) {
                             int count;
 
@@ -232,21 +236,23 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
                 case VK_BACK:
                 case VK_DELETE:
                     if ((! *hwndText) && (This->options & ACO_AUTOSUGGEST)) {
+                        heap_free(hwndText);
                         ShowWindow(This->hwndListBox, SW_HIDE);
                         return CallWindowProcW(This->wpOrigEditProc, hwnd, uMsg, wParam, lParam);
                     }
                     break;
             }
 
+            if (len+1 != size)
+                hwndText = heap_realloc(hwndText, len+1);
+
             SendMessageW(This->hwndListBox, LB_RESETCONTENT, 0, 0);
 
+            /* Set txtbackup to point to hwndText itself (which must not be released) */
             heap_free(This->txtbackup);
-            len = strlenW(hwndText);
-            This->txtbackup = heap_alloc((len + 1)*sizeof(WCHAR));
-            lstrcpyW(This->txtbackup, hwndText);
+            This->txtbackup = hwndText;
 
-            /* Returns if there is no text to search and we doesn't want to display all the entries */
-            if ((!displayall) && (! *hwndText) )
+            if (!displayall && !len)
                 break;
 
             IEnumString_Reset(This->enumstr);
@@ -298,7 +304,6 @@ static LRESULT APIENTRY ACEditSubclassProc(HWND hwnd, UINT uMsg, WPARAM wParam,
             }
 
             break;
-        }
         case WM_DESTROY:
         {
             WNDPROC proc = This->wpOrigEditProc;
-- 
1.9.1




More information about the wine-devel mailing list