From 127db85b2507515bc3c61b5bc04d3d499dd18adf Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Tue, 9 Sep 2008 09:47:35 +0000 Subject: [PATCH] 2008-09-09 11:47 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/vm/asort.c ! fixed GPF when user sort code block reduces the size of sorted array --- harbour/ChangeLog | 4 +++ harbour/source/vm/asort.c | 61 ++++++++++++++++++++++----------------- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/harbour/ChangeLog b/harbour/ChangeLog index 25f05d5e9f..e019ed98f8 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,10 @@ 2008-12-31 13:59 UTC+0100 Foo Bar (foo.bar foobar.org) */ +2008-09-09 11:47 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/source/vm/asort.c + ! fixed GPF when user sort code block reduces the size of sorted array + 2008-09-09 11:34 UTC+0200 Viktor Szakats (harbour.01 syenar hu) * contrib/hbct/numconv.prg ! Fixed typo. Thanks to Grigory Filatov for reporting it. diff --git a/harbour/source/vm/asort.c b/harbour/source/vm/asort.c index b6f005831b..5e65bf2c7d 100644 --- a/harbour/source/vm/asort.c +++ b/harbour/source/vm/asort.c @@ -63,7 +63,7 @@ #include "hbvm.h" #include "hbstack.h" -static BOOL hb_itemIsLess( PHB_ITEM pItem1, PHB_ITEM pItem2, PHB_ITEM pBlock ) +static BOOL hb_itemIsLess( PHB_ITEM pItem1, PHB_ITEM pItem2, PHB_ITEM pBlock, PHB_BASEARRAY pBaseArray, ULONG ulLast ) { if( pBlock ) { @@ -73,7 +73,9 @@ static BOOL hb_itemIsLess( PHB_ITEM pItem1, PHB_ITEM pItem2, PHB_ITEM pBlock ) hb_vmPush( pItem2 ); hb_vmSend( 2 ); - if( HB_IS_LOGICAL( hb_stackReturnItem() ) ) + if( pBaseArray->ulLen <= ulLast ) + return FALSE; + else if( HB_IS_LOGICAL( hb_stackReturnItem() ) ) return hb_itemGetL( hb_stackReturnItem() ); } @@ -119,16 +121,14 @@ static BOOL hb_itemIsLess( PHB_ITEM pItem1, PHB_ITEM pItem2, PHB_ITEM pBlock ) /* partition array pItems[lb..ub] */ -static LONG hb_arraySortQuickPartition( PHB_ITEM pItems, LONG lb, LONG ub, PHB_ITEM pBlock ) +static LONG hb_arraySortQuickPartition( PHB_BASEARRAY pBaseArray, LONG lb, LONG ub, PHB_ITEM pBlock ) { - LONG i, j, p; + LONG i, j; /* select pivot and exchange with 1st element */ - p = lb + ( ( ub - lb ) >> 1 ); - if( p != lb ) - { - hb_itemSwap( pItems + lb, pItems + p ); - } + i = lb + ( ( ub - lb ) >> 1 ); + if( i != lb ) + hb_itemSwap( pBaseArray->pItems + lb, pBaseArray->pItems + i ); /* sort lb+1..ub based on pivot */ i = lb + 1; @@ -136,54 +136,61 @@ static LONG hb_arraySortQuickPartition( PHB_ITEM pItems, LONG lb, LONG ub, PHB_I while( TRUE ) { - while( i < j && hb_itemIsLess( pItems + i, pItems + lb, pBlock ) ) - { - i++; - } - - while( j >= i && hb_itemIsLess( pItems + lb, pItems + j, pBlock ) ) + while( j >= i && !hb_itemIsLess( pBaseArray->pItems + j, pBaseArray->pItems + lb, pBlock, pBaseArray, j ) ) { j--; } + while( i < j && !hb_itemIsLess( pBaseArray->pItems + lb, pBaseArray->pItems + i, pBlock, pBaseArray, i ) ) + { + i++; + } + if( i >= j ) { break; } /* Swap the items */ - hb_itemSwap( pItems + i, pItems + j ); + hb_itemSwap( pBaseArray->pItems + i, pBaseArray->pItems + j ); j--; i++; } - /* pivot belongs in pItems[j] */ - if( j > lb ) - { - hb_itemSwap( pItems + lb, pItems + j ); - } + /* pivot belongs in pBaseArray->pItems[j] */ + if( j > lb && pBaseArray->ulLen > ( ULONG ) j ) + hb_itemSwap( pBaseArray->pItems + lb, pBaseArray->pItems + j ); return j; } -/* sort array pItems[lb..ub] */ +/* sort array pBaseArray->pItems[lb..ub] */ -static void hb_arraySortQuick( PHB_ITEM pItems, LONG lb, LONG ub, PHB_ITEM pBlock ) +static void hb_arraySortQuick( PHB_BASEARRAY pBaseArray, LONG lb, LONG ub, PHB_ITEM pBlock ) { + LONG m; + while( lb < ub ) { + if( ( ULONG ) ub >= pBaseArray->ulLen ) + { + ub = pBaseArray->ulLen - 1; + if( lb >= ub ) + break; + } + /* partition into two segments */ - LONG m = hb_arraySortQuickPartition( pItems, lb, ub, pBlock ); + m = hb_arraySortQuickPartition( pBaseArray, lb, ub, pBlock ); /* sort the smallest partition to minimize stack requirements */ if( m - lb <= ub - m ) { - hb_arraySortQuick( pItems, lb, m - 1, pBlock ); + hb_arraySortQuick( pBaseArray, lb, m - 1, pBlock ); lb = m + 1; } else { - hb_arraySortQuick( pItems, m + 1, ub, pBlock ); + hb_arraySortQuick( pBaseArray, m + 1, ub, pBlock ); ub = m - 1; } } @@ -220,7 +227,7 @@ BOOL hb_arraySort( PHB_ITEM pArray, ULONG * pulStart, ULONG * pulCount, PHB_ITEM /* Optimize when only one or no element is to be sorted */ if( ulCount > 1 ) - hb_arraySortQuick( pBaseArray->pItems, ulStart - 1, ulEnd, pBlock ); + hb_arraySortQuick( pBaseArray, ulStart - 1, ulEnd, pBlock ); } return TRUE;