4848
4949/*
5050This code came from Gareth McCaughan, under the zlib license.
51- Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.15
51+ Specifically this: https://www.mccaughan.org.uk/software/qsort.c-1.16
5252
5353Everything below this comment until the HAVE_QSORT #endif was from Gareth
5454(any minor changes will be noted inline).
@@ -97,7 +97,7 @@ Update for SDL3: we have modified this from a qsort function to qsort_r.
9797 * Gareth McCaughan
9898 */
9999
100- /* Copyright (c) 1998-2016 Gareth McCaughan
100+ /* Copyright (c) 1998-2021 Gareth McCaughan
101101 *
102102 * This software is provided 'as-is', without any express or implied
103103 * warranty. In no event will the authors be held liable for any
@@ -133,17 +133,23 @@ Update for SDL3: we have modified this from a qsort function to qsort_r.
133133 * (pre-insertion-sort messed up).
134134 * Disable DEBUG_QSORT by default.
135135 * Tweak comments very slightly.
136+ * 2021-02-20 v1.16 Fix bug kindly reported by Ray Gardner
137+ * (error in recursion leading to possible
138+ * stack overflow).
139+ * When checking alignment, avoid casting
140+ * pointer to possibly-smaller integer.
136141 */
137142
138143/* BEGIN SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
139144#if 0
140145#include <assert.h>
146+ #include <stdint.h>
141147#include <stdlib.h>
142148#include <string.h>
143149
144150#undef DEBUG_QSORT
145151
146- static char _ID []= "<qsort.c gjm WITH CHANGES FOR SDL3 1.15 2016-03-10 >" ;
152+ static char _ID []= "<qsort.c gjm WITH CHANGES FOR SDL3 1.16 2021-02-20 >" ;
147153#endif
148154/* END SDL CHANGE ... commented this out with an #if 0 block. --ryan. */
149155
@@ -153,7 +159,8 @@ static char _ID[]="<qsort.c gjm WITH CHANGES FOR SDL3 1.15 2016-03-10>";
153159#define WORD_BYTES sizeof(int)
154160
155161/* How big does our stack need to be? Answer: one entry per
156- * bit in a |size_t|.
162+ * bit in a |size_t|. (Actually, a bit less because we don't
163+ * recurse all the way down to size-1 subarrays.)
157164 */
158165#define STACK_SIZE (8*sizeof(size_t))
159166
@@ -192,11 +199,12 @@ typedef struct { char * first; char * last; } stack_entry;
192199 * on large datasets for locality-of-reference reasons,
193200 * but it makes the code much nastier and increases
194201 * bookkeeping overhead.
195- * 2. We always save the shorter and get to work on the
196- * longer. This guarantees that every time we push
197- * an item onto the stack its size is <= 1/2 of that
198- * of its parent; so the stack can't need more than
199- * log_2(max-array-size) entries.
202+ * 2. We always save the longer and get to work on the
203+ * shorter. This guarantees that whenever we push
204+ * a k'th entry onto the stack we are about to get
205+ * working on something of size <= N/2^k where N is
206+ * the original array size; so the stack can't need
207+ * more than log_2(max-array-size) entries.
200208 * 3. We choose a pivot by looking at the first, last
201209 * and middle elements. We arrange them into order
202210 * because it's easy to do that in conjunction with
@@ -258,8 +266,8 @@ typedef struct { char * first; char * last; } stack_entry;
258266 if (r>=Trunc) doRight \
259267 else pop \
260268 } \
261- else if (l<=r) { pushLeft; doRight } \
262- else if (r>=Trunc) { pushRight; doLeft }\
269+ else if (l<=r) { pushRight; doLeft } \
270+ else if (r>=Trunc) { pushLeft; doRight }\
263271 else doLeft \
264272 }
265273
@@ -511,7 +519,7 @@ void SDL_qsort_r(void *base, size_t nmemb, size_t size,
511519 SDL_CompareCallback_r compare , void * userdata ) {
512520
513521 if (nmemb <=1 ) return ;
514- if (((size_t )base |size )& (WORD_BYTES - 1 ))
522+ if (((uintptr_t )base |size )& (WORD_BYTES - 1 ))
515523 qsort_r_nonaligned (base ,nmemb ,size ,compare ,userdata );
516524 else if (size != WORD_BYTES )
517525 qsort_r_aligned (base ,nmemb ,size ,compare ,userdata );
0 commit comments