> -----Ursprüngliche Nachricht----- > Von: Niklas Edmundsson > Gesendet: Freitag, 22. Februar 2008 13:45 > An: dev@httpd.apache.org > Betreff: Re: httpd 2.2.8 segfaults > > On Fri, 22 Feb 2008, Plüm, Rüdiger, VF-Group wrote: > > >> In general, that patch looks truly suspicious since it seems to me > >> it's typecasting wildly and not even using its newly invented > >> MAX_APR_SIZE_T in all places, because (apr_size_t)(-1) > really is the > >> same thing, right? > > > > No, MAX_APR_SIZE_T and (apr_size_t)(-1) might be different > depending on the > > platform. MAX_APR_SIZE_T is ~(apr_size_t)(0). > > Won't both be 0xff...ff as long as apr_size_t is unsigned (which it > should be)? If not, the code makes even less sense.. I thought the same so far. But there seem to be platforms that we support where this is not the case. Don't ask which platforms these are. Somebody? > > Both casting signed -1 to unsigned and flipping the bits of 0 are > standard methods to get the max-value possible to store in a > variable... > > > As I have overcome my confusion regarding apr_off_t / apr_size_t I > > hope to have a look into the problem and find a solution how to do > > all the casting stuff correctly. > > My tip would be: less casts. If they're needed they're usually a sign > of bad design or a thinko somewhere. Meanwhile I tried to clean this up in trunk. Can you please try the attached patch? Keep in mind that MAX_APR_SIZE_T is not present in apr-util 1.2.x and that you need to adjust this manually. Remote eyes welcome as well. Index: apr_brigade.c =================================================================== --- apr_brigade.c (revision 630122) +++ apr_brigade.c (working copy) @@ -97,6 +97,7 @@ apr_bucket *e; const char *s; apr_size_t len; + apr_uint64_t point64; apr_status_t rv; if (point < 0) { @@ -108,17 +109,25 @@ return APR_SUCCESS; } + /* + * Try to reduce the following casting mess: We know that point will be + * larger equal 0 now and forever and thus that point (apr_off_t) and + * apr_size_t will fit into apr_uint64_t in any case. + */ + point64 = (apr_uint64_t)point; + APR_BRIGADE_CHECK_CONSISTENCY(b); for (e = APR_BRIGADE_FIRST(b); e != APR_BRIGADE_SENTINEL(b); e = APR_BUCKET_NEXT(e)) { - /* For an unknown length bucket, while 'point' is beyond the possible + /* For an unknown length bucket, while 'point64' is beyond the possible * size contained in apr_size_t, read and continue... */ - if ((e->length == (apr_size_t)(-1)) && (point > APR_SIZE_MAX)) { - /* point is too far out to simply split this bucket, + if ((e->length == (apr_size_t)(-1)) + && (point64 > (apr_uint64_t)APR_SIZE_MAX)) { + /* point64 is too far out to simply split this bucket, * we must fix this bucket's size and keep going... */ rv = apr_bucket_read(e, &s, &len, APR_BLOCK_READ); if (rv != APR_SUCCESS) { @@ -126,14 +135,15 @@ return rv; } } - else if (((apr_size_t)point < e->length) || (e->length == (apr_size_t)(-1))) { - /* We already consumed buckets where point is beyond + else if ((point64 < (apr_uint64_t)e->length) + || (e->length == (apr_size_t)(-1))) { + /* We already consumed buckets where point64 is beyond * our interest ( point > MAX_APR_SIZE_T ), above. - * Here point falls between 0 and MAX_APR_SIZE_T + * Here point falls between 0 and MAX_APR_SIZE_T * and is within this bucket, or this bucket's len * is undefined, so now we are ready to split it. * First try to split the bucket natively... */ - if ((rv = apr_bucket_split(e, (apr_size_t)point)) + if ((rv = apr_bucket_split(e, (apr_size_t)point64)) != APR_ENOTIMPL) { *after_point = APR_BUCKET_NEXT(e); return rv; @@ -150,17 +160,17 @@ /* this assumes that len == e->length, which is okay because e * might have been morphed by the apr_bucket_read() above, but * if it was, the length would have been adjusted appropriately */ - if ((apr_size_t)point < e->length) { + if (point64 < (apr_uint64_t)e->length) { rv = apr_bucket_split(e, (apr_size_t)point); *after_point = APR_BUCKET_NEXT(e); return rv; } } - if (point == e->length) { + if (point64 == (apr_uint64_t)e->length) { *after_point = APR_BUCKET_NEXT(e); return APR_SUCCESS; } - point -= e->length; + point64 -= (apr_uint64_t)e->length; } *after_point = APR_BRIGADE_SENTINEL(b); return APR_INCOMPLETE; Regards Rüdiger