Module: wine Branch: master Commit: 403221c2281197630f0c6479e818bc2b02dd2b3d URL: http://source.winehq.org/git/wine.git/?a=commit;h=403221c2281197630f0c6479e8...
Author: Jan de Mooij jandemooij@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);