On 02/21/2008 10:33 PM, Ruediger Pluem wrote:


On 02/21/2008 10:09 PM, Niklas Edmundsson wrote:
On Wed, 20 Feb 2008, Niklas Edmundsson wrote:

In any case, I should probably try to figure out how to reproduce this thing. All coredumps I've looked at have been when serving DVD images, which of course works flawlessly when I try it...

OK, I've been able to reproduce this, and it looks really bad because:

Could you please check if backing out the following patch out of apr-util
'fixes' the problem:

http://svn.apache.org/viewvc/apr/apr-util/branches/1.2.x/buckets/apr_brigade.c?r1=232557&r2=588057

Alternatively could you give the attached patch a try. It will not work cleanly 
with apr-util 1.2.x
because APR_SIZE_MAX is not defined there. So this would need to be fixed.

Regards

Rüdiger

Index: apr_brigade.c
===================================================================
--- apr_brigade.c	(Revision 628865)
+++ apr_brigade.c	(Arbeitskopie)
@@ -97,6 +97,7 @@
     apr_bucket *e;
     const char *s;
     apr_size_t len;
+    apr_size_t pointst;
     apr_status_t rv;
 
     if (point < 0) {
@@ -108,6 +109,13 @@
         return APR_SUCCESS;
     }
 
+    /*
+     * Avoid all the following casting mess: point is > 0 and will not get < 0
+     * in the following. So cast once and forever and move on with the casted
+     * value that is now unsigned like everything else.
+     */
+    pointst = (apr_size_t)point;
+
     APR_BRIGADE_CHECK_CONSISTENCY(b);
 
     for (e = APR_BRIGADE_FIRST(b);
@@ -117,7 +125,7 @@
         /* For an unknown length bucket, while 'point' is beyond the possible
          * size contained in apr_size_t, read and continue...
          */
-        if ((e->length == (apr_size_t)(-1)) && (point > APR_SIZE_MAX)) {
+        if ((e->length == (apr_size_t)(-1)) && (pointst > APR_SIZE_MAX)) {
             /* point 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);
@@ -126,14 +134,14 @@
                 return rv;
             }
         }
-        else if (((apr_size_t)point < e->length) || (e->length == (apr_size_t)(-1))) {
+        else if ((pointst < 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 
              * 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, pointst)) 
                     != APR_ENOTIMPL) {
                 *after_point = APR_BUCKET_NEXT(e);
                 return rv;
@@ -150,17 +158,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) {
-                rv = apr_bucket_split(e, (apr_size_t)point);
+            if (pointst < e->length) {
+                rv = apr_bucket_split(e, pointst);
                 *after_point = APR_BUCKET_NEXT(e);
                 return rv;
             }
         }
-        if (point == e->length) {
+        if (pointst == e->length) {
             *after_point = APR_BUCKET_NEXT(e);
             return APR_SUCCESS;
         }
-        point -= e->length;
+        pointst -= e->length;
     }
     *after_point = APR_BRIGADE_SENTINEL(b); 
     return APR_INCOMPLETE;

Reply via email to