Skip to content

Commit

Permalink
LibC: bsearch fix for large arrays (SerenityOS#3138)
Browse files Browse the repository at this point in the history
Implement unsigned arithmetic to compute middle without causing overflow.
And without mixed signed/unsigned operations.
  • Loading branch information
tryfinally committed Aug 14, 2020
1 parent bba2da6 commit cdae3f5
Showing 1 changed file with 9 additions and 10 deletions.
19 changes: 9 additions & 10 deletions Libraries/LibC/stdlib.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -745,18 +745,17 @@ char* mkdtemp(char* pattern)

void* bsearch(const void* key, const void* base, size_t nmemb, size_t size, int (*compar)(const void*, const void*))
{
int low = 0;
int high = nmemb - 1;
while (low <= high) {
int middle = (low + high) / 2;
void* middle_memb = const_cast<char*>((const char*)base + middle * size);
char* start = static_cast<char*>(const_cast<void*>(base));
while (nmemb > 0) {
char* middle_memb = start + (nmemb / 2) * size;
int comparison = compar(key, middle_memb);
if (comparison < 0)
high = middle - 1;
else if (comparison > 0)
low = middle + 1;
else
if (comparison == 0)
return middle_memb;
else if (comparison > 0) {
start = middle_memb + size;
--nmemb;
}
nmemb /= 2;
}

return NULL;
Expand Down

0 comments on commit cdae3f5

Please sign in to comment.