[GRASS5] [bug #4095] (grass) SIGSEGV in Vect_cidx_find_next

this bug's URL: http://intevation.de/rt/webrt?serial_num=4095
-------------------------------------------------------------------------

Subject: SIGSEGV in Vect_cidx_find_next

Platform: GNU/Linux/x86
grass obtained from: Trento Italy site
grass binary for platform: Downloaded precompiled Binaries
GRASS Version: 6.0.1RC4

The function Vect_cidx_find_next() contains 3 critical bugs:

(1) bsearch() is called to find an element in the cat index where its cat
    value matches the given value. The implemented logic ignores the fact
    that bsearch() does _not_ return the first element but rather _any_
    element that matches. So there is the potential to loose elements with
    successive scans on the cat index.

(2) When the type mask is evaluated, the cat value is ignored. Thus, the
    returned id might refer to an element with a completely different cat
    value.

(3) The offset calculations for the second parameter passed to bsearch() are
    wrong. A single element in the "ci->cat" array already has a size of
    "3 * sizeof(int)". Multiplying the start_index with this size will
    effectively result in an invalid offset, which can lead to traps or other
    memory corruptions.

Proposed fixes:
---------------
(1) add the following piece after the bsearch() and the determination of
    "cat_index"

while (cat_index > start_index && ci->cat[cat_index-1][0] == cat) {
    cat_index--;
}

(2) fix the do-while loop at the end of the function like this:

do {
    if (ci->cat[cat_index][0] != cat) {
        return -1;
    }
    if (ci->cat[cat_index][1] & type_mask) {
        *type = ci->cat[cat_index][1];
        *id = ci->cat[cat_index][2];
        return cat_index;
    }
} while (cat_index < ci->n_cats);

(3) correct the parameters for bsearch() in the following way:

catp = bsearch(&cat, &ci->cat[start_index], ci->n_cats - start_index,
        sizeof ci->cat[0], cmp_cat);

Regards,
Knut Stolze

-------------------------------------------- Managed by Request Tracker