[Replying to my onw post, for the sake of anyone who might ever need the
answer...]
In my code (see way below), I was testing for EOS and FLUSH buckets, but
neglected to check for the brigade SENTINEL bucket.
So, the code hit a segfault when I tried to do a
b = APR_BUCKET_PREV(b);
from the brigade SENTINEL.
wrong:
if ( ( ! done ) &&
( ! APR_BUCKET_IS_EOS(APR_BUCKET_NEXT(b)) ) &&
( ! APR_BUCKET_IS_FLUSH(APR_BUCKET_NEXT(b)) ) )
{
. . .
}
correct:
if ( ( ! done ) &&
( ! APR_BUCKET_IS_EOS(APR_BUCKET_NEXT(b)) ) &&
( ! APR_BUCKET_IS_FLUSH(APR_BUCKET_NEXT(b)) ) &&
( APR_BUCKET_NEXT(b) != APR_BRIGADE_SENTINEL(bb) ) )
{
. . .
}
--
Drew
Drew Bertola wrote:
> Happy Monday,
>
> I'm getting a segfault whenever I try to read the next bucket. I'm
> trying to do this without losing the current bucket.
>
> If I do:
>
> b = APR_BUCKET_NEXT(b);
> apr_bucket_read(b, &str, &len, APR_NONBLOCK_READ);
> b = APR_BUCKET_PREV(b);
>
> I get a segfault.
>
> I'm not sure what the correct way to go about this is, but what it
> amounts to is trying to test for a strmatch spanning across adjacent
> buckets.
>
> My code looks like this (with the irrelevant bits removed):
>
> /*
> * We're finished finding full matches in the current bucket,
> * but we need to consider the case of matches that would span
> * the current bucket and the next bucket.
> *
> * Actually, we don't need to do this if we're not inserting
> * globally (flag "done" is set) or if the next bucket is an EOS
> * or FLUSH bucket.
> *
> * First we'll grab the largest possible partial match from
> * the tail of our current bucket. That will be the last
> * "(strlen(match_str) - 1)" characters.
> *
> * Then, we'll prefetch and read the next bucket, then
> * concat the tail piece we grabbed to the head of the
> * next bucket. We'll search for a match within the len of
> * the current tail piece.
> *
> * If we don't find a match, that means we had no partial
> * match and can go on to cycling through the buckets in a
> * normal fasion. To flag for this case, we'll set our
> * tail_str to NULL.
> *
> * Otherwise:
> *
> * - If we're inserting before a match, we should process it now.
> *
> * - If we're replacing the match, we should split our
> * current bucket at the match point and disregard the split
> * off tail. We'll then ...
> *
> * - If we're inserting after a match, we should ...
> */
> if ( ( ! done ) &&
> ( ! APR_BUCKET_IS_EOS(APR_BUCKET_NEXT(b)) ) &&
> ( ! APR_BUCKET_IS_FLUSH(APR_BUCKET_NEXT(b)) ) )
> {
> char *tmp_str = NULL;
>
> tail_str = apr_pstrdup(f->r->pool, str);
>
> if ( len < strlen(cfg->match_str) )
> {
> tail_str[len] = '\0';
> }
> else
> {
> tail_str += (len - strlen(cfg->match_str)) + 1;
> tail_str[strlen(cfg->match_str)] = '\0';
> }
>
> len_tail = strlen(tail_str);
>
> b = APR_BUCKET_NEXT(b);
>
> apr_bucket_read(b,
> &str,
> &len,
> APR_NONBLOCK_READ);
>
> b = APR_BUCKET_PREV(b);
>
> . . .
>
>
> Any ideas?
>
> --
> Drew
>
>
>