Author: rpluem
Date: Mon Feb 25 01:38:26 2008
New Revision: 630780
URL: http://svn.apache.org/viewvc?rev=630780&view=rev
Log:
* apr_brigade_partition:
Use a 64 bit unsigned int for all calculations of point to avoid overflows
on systems where apr_off_t > apr_size_t (e.g. 32 bit with LFS)
while still doing the correct thing on other systems where
apr_off_t = apr_size_t. We currently do not support platforms
where apr_off_t, apr_size_t > 64 bit.
Modified:
apr/aprutil/trunk/buckets/apr_brigade.c
Modified: apr/aprutil/trunk/buckets/apr_brigade.c
URL: http://svn.apache.org/viewvc/apr/aprutil/trunk/buckets/apr_brigade.c?rev=630780&r1=630779&r2=630780&view=diff
==============================================================================
 apr/aprutil/trunk/buckets/apr_brigade.c (original)
+++ apr/aprutil/trunk/buckets/apr_brigade.c Mon Feb 25 01:38:26 2008
@@ 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
 * our interest ( point > MAX_APR_SIZE_T ), above.
 * Here point falls between 0 and MAX_APR_SIZE_T
+ else if ((point64 < (apr_uint64_t)e>length)
+  (e>length == (apr_size_t)(1))) {
+ /* We already consumed buckets where point64 is beyond
+ * our interest ( point64 > MAX_APR_SIZE_T ), above.
+ * 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;
