From 211432e7ebe6d00385ac068537c0a799ec66dda4 Mon Sep 17 00:00:00 2001 From: Aikawa Yataro Date: Thu, 20 Jun 2024 00:48:53 +0000 Subject: [PATCH 1/2] Add bounds checks to SDL_qsort --- src/stdlib/SDL_qsort.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/stdlib/SDL_qsort.c b/src/stdlib/SDL_qsort.c index 4ed2863e504b7..2b4c0ccc98238 100644 --- a/src/stdlib/SDL_qsort.c +++ b/src/stdlib/SDL_qsort.c @@ -333,7 +333,7 @@ typedef struct { char * first; char * last; } stack_entry; char *test; \ /* Find the right place for |first|. \ * My apologies for var reuse. */ \ - for (test=first-size;compare(userdata,test,first)>0;test-=size) ; \ + for (test=first-size;test>(char*)base&&compare(userdata,test,first)>0;test-=size) ; \ test+=size; \ if (test!=first) { \ /* Shift everything in [test,first) \ @@ -418,6 +418,7 @@ static void qsort_r_nonaligned(void *base, size_t nmemb, size_t size, while (1) { /* Select pivot */ { char * mid=first+size*((last-first)/size >> 1); + if (mid>=last) break; Pivot(SWAP_nonaligned,size); memcpy(pivot,mid,size); } @@ -449,6 +450,7 @@ static void qsort_r_aligned(void *base, size_t nmemb, size_t size, while (1) { /* Select pivot */ { char * mid=first+size*((last-first)/size >> 1); + if (mid>=last) break; Pivot(SWAP_aligned,size); memcpy(pivot,mid,size); } @@ -484,6 +486,7 @@ fprintf(stderr,"Doing %d:%d: ", #endif /* Select pivot */ { char * mid=first+WORD_BYTES*((last-first) / (2*WORD_BYTES)); + if (mid>=last) break; Pivot(SWAP_words,WORD_BYTES); *(int*)pivot=*(int*)mid; #ifdef DEBUG_QSORT @@ -506,7 +509,7 @@ fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base) /* Find the right place for |first|. My apologies for var reuse */ int *pl=(int*)(first-WORD_BYTES),*pr=(int*)first; *(int*)pivot=*(int*)first; - for (;compare(userdata,pl,pivot)>0;pr=pl,--pl) { + for (;pl>(int*)base&&compare(userdata,pl,pivot)>0;pr=pl,--pl) { *pr=*pl; } if (pr!=(int*)first) *pr=*(int*)pivot; } From 5ec61c4bb54e90561f8b2820e217d6a75803f615 Mon Sep 17 00:00:00 2001 From: Aikawa Yataro Date: Mon, 3 Nov 2025 07:47:25 +0000 Subject: [PATCH 2/2] Fix bound check condition in SDL_qsort --- src/stdlib/SDL_qsort.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/stdlib/SDL_qsort.c b/src/stdlib/SDL_qsort.c index 2b4c0ccc98238..5bcdba5ec2b10 100644 --- a/src/stdlib/SDL_qsort.c +++ b/src/stdlib/SDL_qsort.c @@ -333,7 +333,7 @@ typedef struct { char * first; char * last; } stack_entry; char *test; \ /* Find the right place for |first|. \ * My apologies for var reuse. */ \ - for (test=first-size;test>(char*)base&&compare(userdata,test,first)>0;test-=size) ; \ + for (test=first-size;test>=(char*)base&&compare(userdata,test,first)>0;test-=size) ; \ test+=size; \ if (test!=first) { \ /* Shift everything in [test,first) \ @@ -509,7 +509,7 @@ fprintf(stderr, "after partitioning first=#%lu last=#%lu\n", (first-(char*)base) /* Find the right place for |first|. My apologies for var reuse */ int *pl=(int*)(first-WORD_BYTES),*pr=(int*)first; *(int*)pivot=*(int*)first; - for (;pl>(int*)base&&compare(userdata,pl,pivot)>0;pr=pl,--pl) { + for (;pl>=(int*)base&&compare(userdata,pl,pivot)>0;pr=pl,--pl) { *pr=*pl; } if (pr!=(int*)first) *pr=*(int*)pivot; } @@ -574,4 +574,3 @@ void *SDL_bsearch(const void *key, const void *base, size_t nmemb, size_t size, // qsort_non_r_bridge just happens to match calling conventions, so reuse it. return SDL_bsearch_r(key, base, nmemb, size, qsort_non_r_bridge, compare); } -