I've had trouble with Xnews (<http://xnews.newsguy.com/>) since the big listview rewrite. This patch addresses some of the problems. Changelog: Paul Rupe <prupe@myrealbox.com> dlls/comctl32/listview.c - Initialize memory to prevent crashes when -debugmsg +listview is on - Fix various array bounds related errors dlls/comctl32/comctl32undoc.c - Resize dynamic pointer array more carefully when adding new entries -- Paul Rupe "She smiled, in the end." p r u p e @ m y r e a l b o x . c o m | Oppose government police-ware on your PC! | Stop the Consumer Broadband and Digital Television Promotion Act! | <http://www.eff.org/alerts/20020322_eff_cbdtpa_alert.html>
Index: dlls/comctl32/comctl32undoc.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/comctl32undoc.c,v retrieving revision 1.66 diff -u -r1.66 comctl32undoc.c --- dlls/comctl32/comctl32undoc.c 6 Sep 2002 19:41:17 -0000 1.66 +++ dlls/comctl32/comctl32undoc.c 24 Sep 2002 21:04:14 -0000 @@ -1957,11 +1957,7 @@ if (hdpa->nItemCount <= i) { /* within the old array */ - if (hdpa->nMaxCount > i) { - /* within the allocated space, set a new boundary */ - hdpa->nItemCount = i+1; - } - else { + if (hdpa->nMaxCount <= i) { /* resize the block of memory */ INT nNewItems = hdpa->nGrow * ((INT)(((i+1) - 1) / hdpa->nGrow) + 1); @@ -1972,9 +1968,10 @@ if (!lpTemp) return FALSE; - hdpa->nItemCount = nNewItems; + hdpa->nMaxCount = nNewItems; hdpa->ptrs = lpTemp; } + hdpa->nItemCount = i; } /* put the new entry in */ Index: dlls/comctl32/listview.c =================================================================== RCS file: /home/wine/wine/dlls/comctl32/listview.c,v retrieving revision 1.151 diff -u -r1.151 listview.c --- dlls/comctl32/listview.c 24 Sep 2002 18:27:21 -0000 1.151 +++ dlls/comctl32/listview.c 24 Sep 2002 21:04:16 -0000 @@ -2258,6 +2258,7 @@ LISTVIEW_RemoveAllSelections(infoPtr); + ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.state = LVIS_FOCUSED | LVIS_SELECTED; lvItem.stateMask = LVIS_FOCUSED | LVIS_SELECTED; LISTVIEW_SetItemState(infoPtr, nItem, &lvItem); @@ -3498,8 +3499,12 @@ nUpdateWidth = rcClip.right - rcClip.left; nTop = LISTVIEW_GetTopIndex(infoPtr); nItem = nTop + (rcClip.top - infoPtr->rcList.top) / infoPtr->nItemHeight; + if (nItem < nTop) + nItem = nTop; nLast = nItem + nUpdateHeight / infoPtr->nItemHeight; if (nUpdateHeight % infoPtr->nItemHeight) nLast++; + if (nLast > GETITEMCOUNT(infoPtr)) + nLast = GETITEMCOUNT(infoPtr); /* send cache hint notification */ if (lStyle & LVS_OWNERDATA) @@ -3559,6 +3564,7 @@ dis.rcItem.bottom = dis.rcItem.top + infoPtr->nItemHeight; OffsetRect(&dis.rcItem, ptOrig.x, 0); + ZeroMemory(&item, sizeof(item)); item.iItem = nItem; item.iSubItem = 0; item.mask = LVIF_PARAM; @@ -5541,13 +5547,15 @@ INT nLeftPos; INT nLabelWidth; INT nIndent; - LVITEMW lvItem; TRACE("(hwnd=%x, nItem=%d, lprc=%p, uview=%d)\n", infoPtr->hwndSelf, nItem, lprc, uView); if (uView & LVS_REPORT) { + LVITEMW lvItem; + + ZeroMemory(&lvItem, sizeof(lvItem)); lvItem.mask = LVIF_INDENT; lvItem.iItem = nItem; lvItem.iSubItem = 0; @@ -6591,11 +6599,6 @@ is_sorted = (lStyle & (LVS_SORTASCENDING | LVS_SORTDESCENDING)) && !(lStyle & LVS_OWNERDRAWFIXED) && (LPSTR_TEXTCALLBACKW != lpLVItem->pszText); - nItem = DPA_InsertPtr( infoPtr->hdpaItems, - is_sorted ? GETITEMCOUNT( infoPtr ) + 1 : lpLVItem->iItem, - hdpaSubItems ); - if (nItem == -1) goto fail; - if (!LISTVIEW_SetItemT(infoPtr, lpLVItem, isW)) goto fail; /* if we're sorted, sort the list, and update the index */ @@ -6606,6 +6609,14 @@ if (nItem == -1) goto fail; } + /* Add the subitem list to the items array. Do this last in case we go to + * fail during the above. + */ + nItem = DPA_InsertPtr( infoPtr->hdpaItems, + is_sorted ? GETITEMCOUNT( infoPtr ) + 1 : lpLVItem->iItem, + hdpaSubItems ); + if (nItem == -1) goto fail; + LISTVIEW_ShiftIndices(infoPtr, nItem, 1); lpItem->valid = TRUE; @@ -7284,7 +7295,10 @@ topvisible = LISTVIEW_GetTopIndex(infoPtr) + LISTVIEW_GetCountPerColumn(infoPtr) + 1; - infoPtr->hdpaItems->nItemCount = nItems; + /* Grow the hdpaItems array if necessary */ + if (nItems > infoPtr->hdpaItems->nMaxCount) + if (!DPA_SetPtr(infoPtr->hdpaItems, nItems - 1, NULL)) + return FALSE; infoPtr->nItemWidth = max(LISTVIEW_GetItemWidth(infoPtr), DEFAULT_COLUMN_WIDTH);