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