[util] Fix an out-by-one in QF_bsearch_r

And rename _bsearch to QF_bsearch_r since that's far less confusing.
Also, update the test to make it possible for valgrind to detect the
out-by-one. The problem was found when trying to remove components from
an entity when using subpools.
This commit is contained in:
Bill Currie 2023-03-05 15:22:01 +09:00
parent 370c36f6cc
commit 76ac446156
4 changed files with 19 additions and 13 deletions

View file

@ -35,7 +35,7 @@
typedef int (*__compar_d_fn_t)(const void *, const void *, void *);
#endif
void *_bsearch(const void *key, const void *base, size_t nmemb, size_t size,
__compar_d_fn_t cmp, void *arg);
void *QF_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
__compar_d_fn_t cmp, void *arg);
#endif// quicksort_h

View file

@ -109,7 +109,7 @@ size_t strndup (const char *str, size_t len);
#ifndef HAVE_BSEARCH_R
# include "bsearch.h"
# define bsearch_r _bsearch
# define bsearch_r QF_bsearch_r
#endif
#ifndef HAVE_QSORT_R

View file

@ -63,13 +63,12 @@ void *fbsearch_r (const void *key, const void *_base, size_t nmemb, size_t size,
}
void *
_bsearch(const void *key, const void *_base, size_t nmemb, size_t size,
__compar_d_fn_t cmp, void *arg)
QF_bsearch_r(const void *key, const void *_base, size_t nmemb, size_t size,
__compar_d_fn_t cmp, void *arg)
{
// fuzzy bsearh
const char *base = (const char *) _base;
unsigned left = 0;
unsigned right = nmemb;
unsigned right = nmemb - 1;
unsigned mid;
const void *p = 0;
int c;

View file

@ -29,16 +29,19 @@
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "QF/fbsearch.h"
#include "bsearch.h"
// will be prefix-summed
int data[] = {
int srcdata[] = {
2, 1, 3, 1, 2, 2, 5, 4,
2, 1, 3, 1, 2, 2, 5, 4,
};
#define nele ((int) (sizeof (data) / sizeof (data[0])))
#define nele ((int) (sizeof (srcdata) / sizeof (srcdata[0])))
int *data;
static int
compare (const void *a, const void *b)
@ -83,6 +86,9 @@ main(int argc, const char **argv)
int ret = 0;
int *p;
data = malloc (nele * sizeof (int));
memcpy (data, srcdata, nele * sizeof (int));
for (int i = 1; i < nele; i++) {
data[i] += data[i - 1];
}
@ -99,18 +105,19 @@ main(int argc, const char **argv)
ret |= 1;
}
if (p && i == *p) {
p = _bsearch (&i, data, nele, sizeof (int), compared, 0);
p = QF_bsearch_r (&i, data, nele, sizeof (int), compared, 0);
if (!p || *p != i) {
printf ("_bsearch did not find %d, but should have\n", i);
printf ("QF_bsearch_r did not find %d, but should have\n", i);
ret |= 1;
}
} else {
p = _bsearch (&i, data, nele, sizeof (int), compared, 0);
p = QF_bsearch_r (&i, data, nele, sizeof (int), compared, 0);
if (p) {
printf ("_bsearch found %d, but should not have\n", i);
printf ("QF_bsearch_r found %d, but should not have\n", i);
ret |= 1;
}
}
}
free (data);
return ret;
}