Jan de Mooij : comctl32/treeview: Fix pszText NULL pointer dereference.

Alexandre Julliard julliard at winehq.org
Thu Sep 18 07:56:08 CDT 2008


Module: wine
Branch: master
Commit: 403221c2281197630f0c6479e818bc2b02dd2b3d
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=403221c2281197630f0c6479e818bc2b02dd2b3d

Author: Jan de Mooij <jandemooij at gmail.com>
Date:   Tue Sep 16 11:25:18 2008 +0200

comctl32/treeview: Fix pszText NULL pointer dereference.

---

 dlls/comctl32/tests/treeview.c |   40 ++++++++++++++++++++++++++++++++++++++++
 dlls/comctl32/treeview.c       |   39 ++++++++++++++++++++++++++++-----------
 2 files changed, 68 insertions(+), 11 deletions(-)

diff --git a/dlls/comctl32/tests/treeview.c b/dlls/comctl32/tests/treeview.c
index c1ba7f3..a873e3c 100644
--- a/dlls/comctl32/tests/treeview.c
+++ b/dlls/comctl32/tests/treeview.c
@@ -64,6 +64,13 @@ static const struct message DoTest2Seq[] = {
     { 0 }
 };
 
+static const struct message DoTest3Seq[] = {
+    { TVM_INSERTITEM, sent },
+    { TVM_GETITEM, sent },
+    { TVM_DELETEITEM, sent },
+    { 0 }
+};
+
 static const struct message DoFocusTestSeq[] = {
     { TVM_INSERTITEM, sent },
     { TVM_INSERTITEM, sent },
@@ -295,6 +302,35 @@ static void DoTest2(void)
     ok(!strcmp(sequence, "1(nR)nR23(RC)RC45(CR)CR."), "root-child select test\n");
 }
 
+static void DoTest3(void)
+{
+    TVINSERTSTRUCTA ins;
+    HTREEITEM hChild;
+    TVITEM tvi;
+
+    int nBufferSize = 80;
+    CHAR szBuffer[80] = "Blah";
+
+    /* add an item without TVIF_TEXT mask and pszText == NULL */
+    ins.hParent = hRoot;
+    ins.hInsertAfter = TVI_ROOT;
+    U(ins).item.mask = 0;
+    U(ins).item.pszText = NULL;
+    U(ins).item.cchTextMax = 0;
+    hChild = TreeView_InsertItem(hTree, &ins);
+    assert(hChild);
+
+    /* retrieve it with TVIF_TEXT mask */
+    tvi.hItem = hChild;
+    tvi.mask = TVIF_TEXT;
+    tvi.cchTextMax = nBufferSize;
+    tvi.pszText = szBuffer;
+
+    SendMessageA( hTree, TVM_GETITEM, 0, (LPARAM)&tvi );
+    ok(!strcmp(szBuffer, ""), "szBuffer=\"%s\", expected \"\"\n", szBuffer);
+    ok(SendMessageA(hTree, TVM_DELETEITEM, 0, (LPARAM)hChild), "DeleteItem failed\n");
+}
+
 static void DoFocusTest(void)
 {
     TVINSERTSTRUCTA ins;
@@ -700,6 +736,10 @@ START_TEST(treeview)
     ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest2Seq, "DoTest2", FALSE);
 
     flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
+    DoTest3();
+    ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoTest3Seq, "DoTest3", FALSE);
+
+    flush_sequences(MsgSequences, NUM_MSG_SEQUENCES);
     DoFocusTest();
     ok_sequence(MsgSequences, LISTVIEW_SEQ_INDEX, DoFocusTestSeq, "DoFocusTest", TRUE);
 
diff --git a/dlls/comctl32/treeview.c b/dlls/comctl32/treeview.c
index a77792d..dabe5d9 100644
--- a/dlls/comctl32/treeview.c
+++ b/dlls/comctl32/treeview.c
@@ -23,8 +23,7 @@
  *
  * Note that TREEVIEW_INFO * and HTREEITEM are the same thing.
  *
- * Note2: All items always! have valid (allocated) pszText field.
- *      If item's text == LPSTR_TEXTCALLBACKA we allocate buffer
+ * Note2: If item's text == LPSTR_TEXTCALLBACKA we allocate buffer
  *      of size TEXT_CALLBACK_SIZE in DoSetItem.
  *      We use callbackMask to keep track of fields to be updated.
  *
@@ -2083,7 +2082,12 @@ TREEVIEW_GetItemT(const TREEVIEW_INFO *infoPtr, LPTVITEMEXW tvItem, BOOL isW)
 
     if (tvItem->mask & TVIF_TEXT)
     {
-        if (isW)
+        if (wineItem->pszText == NULL)
+        {
+            if (tvItem->cchTextMax > 0)
+                tvItem->pszText[0] = '\0';
+        }
+        else if (isW)
         {
             if (wineItem->pszText == LPSTR_TEXTCALLBACKW)
             {
@@ -3662,8 +3666,11 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     }
 
     /* Get string length in pixels */
-    GetTextExtentPoint32W(hdc, editItem->pszText, strlenW(editItem->pszText),
-			  &sz);
+    if (editItem->pszText)
+        GetTextExtentPoint32W(hdc, editItem->pszText, strlenW(editItem->pszText),
+                        &sz);
+    else
+        GetTextExtentPoint32A(hdc, "", 0, &sz);
 
     /* Add Extra spacing for the next character */
     GetTextMetricsW(hdc, &textMetric);
@@ -3712,7 +3719,10 @@ TREEVIEW_EditLabel(TREEVIEW_INFO *infoPtr, HTREEITEM hItem)
     }
 
     infoPtr->selectedItem = hItem;
-    SetWindowTextW(hwndEdit, editItem->pszText);
+
+    if (editItem->pszText)
+        SetWindowTextW(hwndEdit, editItem->pszText);
+
     SetFocus(hwndEdit);
     SendMessageW(hwndEdit, EM_SETSEL, 0, -1);
     ShowWindow(hwndEdit, SW_SHOW);
@@ -4186,10 +4196,14 @@ TREEVIEW_CreateDragImage(TREEVIEW_INFO *infoPtr, LPARAM lParam)
     hdc = CreateCompatibleDC(htopdc);
 
     hOldFont = SelectObject(hdc, infoPtr->hFont);
-    GetTextExtentPoint32W(hdc, dragItem->pszText, strlenW(dragItem->pszText),
+
+    if (dragItem->pszText)
+        GetTextExtentPoint32W(hdc, dragItem->pszText, strlenW(dragItem->pszText),
 			  &size);
-    TRACE("%d %d %s %d\n", size.cx, size.cy, debugstr_w(dragItem->pszText),
-	  strlenW(dragItem->pszText));
+    else
+        GetTextExtentPoint32A(hdc, "", 0, &size);
+
+    TRACE("%d %d %s\n", size.cx, size.cy, debugstr_w(dragItem->pszText));
     hbmp = CreateCompatibleBitmap(htopdc, size.cx, size.cy);
     hOldbmp = SelectObject(hdc, hbmp);
 
@@ -4210,8 +4224,11 @@ TREEVIEW_CreateDragImage(TREEVIEW_INFO *infoPtr, LPARAM lParam)
 /* draw item text */
 
     SetRect(&rc, cx, 0, size.cx, size.cy);
-    DrawTextW(hdc, dragItem->pszText, strlenW(dragItem->pszText), &rc,
-	      DT_LEFT);
+
+    if (dragItem->pszText)
+        DrawTextW(hdc, dragItem->pszText, strlenW(dragItem->pszText), &rc,
+                  DT_LEFT);
+
     SelectObject(hdc, hOldFont);
     SelectObject(hdc, hOldbmp);
 




More information about the wine-cvs mailing list