diff options
author | Muhammad Zahalqa <m@tryfinally.com> | 2020-08-15 01:18:52 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-15 00:18:52 +0200 |
commit | cdae3f53f1b3cc2175d3712717e368d1fe3bce1d (patch) | |
tree | e90292e1963e071d17b2011d734403fd9088a15b /Libraries | |
parent | bba2da66e76376261510d6ca5d79362b291e5631 (diff) | |
download | serenity-cdae3f53f1b3cc2175d3712717e368d1fe3bce1d.zip |
LibC: bsearch fix for large arrays (#3138)
Implement unsigned arithmetic to compute middle without causing overflow.
And without mixed signed/unsigned operations.
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibC/stdlib.cpp | 19 |
1 files changed, 9 insertions, 10 deletions
diff --git a/Libraries/LibC/stdlib.cpp b/Libraries/LibC/stdlib.cpp index b1cea40aa0..8fd6d975b3 100644 --- a/Libraries/LibC/stdlib.cpp +++ b/Libraries/LibC/stdlib.cpp @@ -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; |