@@ -283,9 +283,8 @@ static int
283283list_compare (v , w )
284284 PyListObject * v , * w ;
285285{
286- int len = (v -> ob_size < w -> ob_size ) ? v -> ob_size : w -> ob_size ;
287286 int i ;
288- for (i = 0 ; i < len ; i ++ ) {
287+ for (i = 0 ; i < v -> ob_size && i < w -> ob_size ; i ++ ) {
289288 int cmp = PyObject_Compare (v -> ob_item [i ], w -> ob_item [i ]);
290289 if (cmp != 0 )
291290 return cmp ;
@@ -587,18 +586,26 @@ listappend(self, args)
587586 function is NULL. */
588587
589588static int
590- docompare (x , y , compare )
589+ docompare (x , y , compare , list )
591590 PyObject * x ;
592591 PyObject * y ;
593592 PyObject * compare ;
593+ PyListObject * list ;
594594{
595+ int size = list -> ob_size ; /* Number of elements to sort */
596+ PyObject * * array = list -> ob_item ; /* Start of array to sort */
595597 PyObject * args , * res ;
596598 int i ;
597599
598600 if (compare == NULL ) {
599601 i = PyObject_Compare (x , y );
600602 if (i && PyErr_Occurred ())
601603 i = CMPERROR ;
604+ else if (size != list -> ob_size || array != list -> ob_item ) {
605+ PyErr_SetString (PyExc_SystemError ,
606+ "list changed size during sort" );
607+ i = CMPERROR ;
608+ }
602609 return i ;
603610 }
604611
@@ -615,6 +622,11 @@ docompare(x, y, compare)
615622 "comparison function should return int" );
616623 return CMPERROR ;
617624 }
625+ if (size != list -> ob_size || array != list -> ob_item ) {
626+ PyErr_SetString (PyExc_SystemError ,
627+ "list changed size during sort" );
628+ return CMPERROR ;
629+ }
618630 i = PyInt_AsLong (res );
619631 Py_DECREF (res );
620632 if (i < 0 )
@@ -643,11 +655,12 @@ docompare(x, y, compare)
643655 (i.e. no items have been removed or duplicated). */
644656
645657static int
646- quicksort (array , size , compare )
647- PyObject * * array ; /* Start of array to sort */
648- int size ; /* Number of elements to sort */
658+ quicksort (list , compare )
659+ PyListObject * list ; /* List to sort */
649660 PyObject * compare ;/* Comparison function object, or NULL for default */
650661{
662+ int size = list -> ob_size ; /* Number of elements to sort */
663+ PyObject * * array = list -> ob_item ; /* Start of array to sort */
651664 register PyObject * tmp , * pivot ;
652665 register PyObject * * l , * * r , * * p ;
653666 PyObject * * lo , * * hi , * * notp ;
@@ -675,7 +688,8 @@ quicksort(array, size, compare)
675688 pivot = * r ;
676689 do {
677690 p = l + ((r - l ) >> 1 );
678- k = docompare (pivot , * p , compare );
691+ k = docompare (pivot , * p ,
692+ compare , list );
679693 if (k == CMPERROR )
680694 return -1 ;
681695 if (k < 0 )
@@ -699,19 +713,19 @@ quicksort(array, size, compare)
699713 p = lo + (n >>1 ); /* Middle */
700714 r = hi - 1 ; /* Last */
701715
702- k = docompare (* p , * l , compare );
716+ k = docompare (* p , * l , compare , list );
703717 if (k == CMPERROR )
704718 return -1 ;
705719 if (k < 0 )
706720 { tmp = * p ; * p = * l ; * l = tmp ; }
707721
708- k = docompare (* r , * p , compare );
722+ k = docompare (* r , * p , compare , list );
709723 if (k == CMPERROR )
710724 return -1 ;
711725 if (k < 0 )
712726 { tmp = * r ; * r = * p ; * p = tmp ; }
713727
714- k = docompare (* p , * l , compare );
728+ k = docompare (* p , * l , compare , list );
715729 if (k == CMPERROR )
716730 return -1 ;
717731 if (k < 0 )
@@ -727,7 +741,7 @@ quicksort(array, size, compare)
727741
728742 /* Move left index to element >= pivot */
729743 while (l < p ) {
730- k = docompare (* l , pivot , compare );
744+ k = docompare (* l , pivot , compare , list );
731745 if (k == CMPERROR )
732746 return -1 ;
733747 if (k < 0 )
@@ -739,7 +753,7 @@ quicksort(array, size, compare)
739753 }
740754 /* Move right index to element <= pivot */
741755 while (r > p ) {
742- k = docompare (pivot , * r , compare );
756+ k = docompare (pivot , * r , compare , list );
743757 if (k == CMPERROR )
744758 return -1 ;
745759 if (k < 0 )
@@ -804,7 +818,7 @@ quicksort(array, size, compare)
804818 * This wastes a compare if it fails, but can win big
805819 * when there are runs of duplicates.
806820 */
807- k = docompare (pivot , * l , compare );
821+ k = docompare (pivot , * l , compare , list );
808822 if (k == CMPERROR )
809823 return -1 ;
810824 if (!(k < 0 )) {
@@ -817,7 +831,7 @@ quicksort(array, size, compare)
817831 */
818832 while (r > lo ) {
819833 /* because r-1 < p, *(r-1) <= pivot is known */
820- k = docompare (* (r - 1 ), pivot , compare );
834+ k = docompare (* (r - 1 ), pivot , compare , list );
821835 if (k == CMPERROR )
822836 return -1 ;
823837 if (k < 0 )
@@ -829,7 +843,7 @@ quicksort(array, size, compare)
829843 l ++ ;
830844 while (l < hi ) {
831845 /* because l > p, pivot <= *l is known */
832- k = docompare (pivot , * l , compare );
846+ k = docompare (pivot , * l , compare , list );
833847 if (k == CMPERROR )
834848 return -1 ;
835849 if (k < 0 )
@@ -866,8 +880,7 @@ listsort(self, compare)
866880 PyListObject * self ;
867881 PyObject * compare ;
868882{
869- /* XXX Don't you *dare* changing the list's length in compare()! */
870- if (quicksort (self -> ob_item , self -> ob_size , compare ) < 0 )
883+ if (quicksort (self , compare ) < 0 )
871884 return NULL ;
872885 Py_INCREF (Py_None );
873886 return Py_None ;
@@ -922,11 +935,7 @@ PyList_Sort(v)
922935 PyErr_BadInternalCall ();
923936 return -1 ;
924937 }
925- v = listsort ((PyListObject * )v , (PyObject * )NULL );
926- if (v == NULL )
927- return -1 ;
928- Py_DECREF (v );
929- return 0 ;
938+ return quicksort ((PyListObject * )v , (PyObject * )NULL );
930939}
931940
932941PyObject *
0 commit comments