1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-07 18:30:25 +02:00

* sort.c (quicksort): Added condition to protect the algorithm

from crashing the interpreter if the less predicate is buggy.
This commit is contained in:
Mikael Djurfeldt 1999-08-19 23:02:00 +00:00
parent 0eb2e8cd94
commit a34af05ece

View file

@ -154,6 +154,8 @@ typedef int (*cmp_fun_t) (SCM less,
const void*, const void*,
const void*); const void*);
static const char s_buggy_less[] = "buggy less predicate used when sorting";
static void static void
quicksort (void *const pbase, quicksort (void *const pbase,
size_t total_elems, size_t total_elems,
@ -215,10 +217,20 @@ quicksort (void *const pbase,
do do
{ {
while ((*cmp) (less, (void *) left_ptr, (void *) pivot)) while ((*cmp) (less, (void *) left_ptr, (void *) pivot))
left_ptr += size; {
left_ptr += size;
/* The comparison predicate may be buggy */
if (left_ptr > hi)
scm_misc_error (0, s_buggy_less, SCM_EOL);
}
while ((*cmp) (less, (void *) pivot, (void *) right_ptr)) while ((*cmp) (less, (void *) pivot, (void *) right_ptr))
right_ptr -= size; {
right_ptr -= size;
/* The comparison predicate may be buggy */
if (right_ptr < lo)
scm_misc_error (0, s_buggy_less, SCM_EOL);
}
if (left_ptr < right_ptr) if (left_ptr < right_ptr)
{ {
@ -297,7 +309,12 @@ quicksort (void *const pbase,
{ {
tmp_ptr = run_ptr - size; tmp_ptr = run_ptr - size;
while ((*cmp) (less, (void *) run_ptr, (void *) tmp_ptr)) while ((*cmp) (less, (void *) run_ptr, (void *) tmp_ptr))
tmp_ptr -= size; {
tmp_ptr -= size;
/* The comparison predicate may be buggy */
if (tmp_ptr < base_ptr)
scm_misc_error (0, s_buggy_less, SCM_EOL);
}
tmp_ptr += size; tmp_ptr += size;
if (tmp_ptr != run_ptr) if (tmp_ptr != run_ptr)
@ -348,6 +365,7 @@ static int
closureless (SCM code, const void *a, const void *b) closureless (SCM code, const void *a, const void *b)
{ {
SCM env, next; SCM env, next;
SCM_ASSERT (*(SCM *)b != 0, SCM_BOOL_F, "Bug!", "closureless");
env = SCM_EXTEND_ENV (SCM_CAR (SCM_CODE (code)), env = SCM_EXTEND_ENV (SCM_CAR (SCM_CODE (code)),
scm_cons (*(SCM *) a, scm_cons (*(SCM *) a,
scm_cons (*(SCM *) b, SCM_EOL)), scm_cons (*(SCM *) b, SCM_EOL)),