]> granicus.if.org Git - nethack/commitdiff
fix crash during Drop unpaid
authornethack.allison <nethack.allison>
Fri, 1 Feb 2002 00:36:54 +0000 (00:36 +0000)
committernethack.allison <nethack.allison>
Fri, 1 Feb 2002 00:36:54 +0000 (00:36 +0000)
The patch is attached. Array bounds went unchecked in
the menu page operations (, \ ~)  This resulted in
memory corruption.

The actual crash depends on your luck actually. It will
only crash if  heap headers are corrupted, otherwise it
can go unnoticed.  When you do "Du," the list page size
is 18 (on my screen) with only 2 items in the menu. The
program assigned count of -1 to 18 items in the array
of 2. Ka-boom.  I put bounds checking code in several
places.  The window size does not have anything to do
with it.

<Someone>.

win/win32/mhmenu.c

index de15457110547334d9c9e6cdd4f993a048861a1f..3c1fe47af29c0e657dc1a254b245b94bfe60b92b 100644 (file)
@@ -879,11 +879,14 @@ BOOL onListChar(HWND hWnd, HWND hwndList, WORD ch)
 
        case MENU_SELECT_PAGE:
                if( data->how == PICK_ANY ) {
+                       int from, to;
                        reset_menu_count(hwndList, data);
                        topIndex = ListView_GetTopIndex( hwndList );
                        pageSize = ListView_GetCountPerPage( hwndList );
-                       for(i=0; i<pageSize; i++ ) {
-                               SelectMenuItem(hwndList, data, topIndex+i, -1);
+                       from = max(0, topIndex);
+                       to = min(data->menu.size, from+pageSize);
+                       for(i=from; i<to; i++ ) {
+                               SelectMenuItem(hwndList, data, i, -1);
                        }
                        return -2;
                }
@@ -891,11 +894,14 @@ BOOL onListChar(HWND hWnd, HWND hwndList, WORD ch)
 
        case MENU_UNSELECT_PAGE:
                if( data->how == PICK_ANY ) {
+                       int from, to;
                        reset_menu_count(hwndList, data);
                        topIndex = ListView_GetTopIndex( hwndList );
                        pageSize = ListView_GetCountPerPage( hwndList );
-                       for(i=0; i<pageSize; i++ ) {
-                               SelectMenuItem(hwndList, data, topIndex+i, 0);
+                       from = max(0, topIndex);
+                       to = min(data->menu.size, from+pageSize);
+                       for(i=from; i<to; i++ ) {
+                               SelectMenuItem(hwndList, data, i, 0);
                        }
                        return -2;
                }
@@ -903,15 +909,18 @@ BOOL onListChar(HWND hWnd, HWND hwndList, WORD ch)
 
        case MENU_INVERT_PAGE:
                if( data->how == PICK_ANY ) {
+                       int from, to;
                        reset_menu_count(hwndList, data);
                        topIndex = ListView_GetTopIndex( hwndList );
                        pageSize = ListView_GetCountPerPage( hwndList );
-                       for(i=0; i<pageSize; i++ ) {
+                       from = max(0, topIndex);
+                       to = min(data->menu.size, from+pageSize);
+                       for(i=from; i<to; i++ ) {
                                SelectMenuItem(
                                        hwndList, 
                                        data, 
-                                       topIndex+i, 
-                                       NHMENU_IS_SELECTED(data->menu.items[topIndex+i])? 0 : -1
+                                       i, 
+                                       NHMENU_IS_SELECTED(data->menu.items[i])? 0 : -1
                                );
                        }
                        return -2;
@@ -1096,6 +1105,9 @@ void mswin_menu_window_size (HWND hWnd, LPSIZE sz)
 void SelectMenuItem(HWND hwndList, PNHMenuWindow data, int item, int count)
 {
        int i;
+
+       if( item<0 || item>=data->menu.size ) return;
+
        if( data->how==PICK_ONE && count!=0 ) {
                for(i=0; i<data->menu.size; i++) 
                        if( item!=i && data->menu.items[i].count!=0 ) {
@@ -1190,3 +1202,4 @@ LRESULT CALLBACK NHMenuTextWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARA
        else 
                return 0;
 }
+