]> granicus.if.org Git - apache/commitdiff
Fixed a trio of mod include bugs. The first two were
authorCliff Woolley <jwoolley@apache.org>
Mon, 21 Jul 2003 23:47:33 +0000 (23:47 +0000)
committerCliff Woolley <jwoolley@apache.org>
Mon, 21 Jul 2003 23:47:33 +0000 (23:47 +0000)
reported and investigated by Ron Park on dev@httpd in msgid
<161E04AB9955D54E826FD86360578554D27087@169.32.17.10.nat.cnet.com>;
the third was reported by Kevin Varley in PR 21095.

Bug 1:  An incorrect parameter to bndm() was causing start sequences
        that spanned buckets to drop characters.
Bug 2:  Failed conditional text spanning brigades would cause portions
        of the text that should have been removed to be present anyway.
Bug 3:  Dropped characters when the end sequence spanned an
        8000-byte boundary with MMAP off.

PR: 21095
Submitted by: Ron Park <ronald.park@cnet.com>, Andr� Malo, Cliff Woolley

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@100728 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/filters/mod_include.c

diff --git a/CHANGES b/CHANGES
index 23f115c8f118ace55cfe1edc1c521ce7a770bcdd..e21733c5b12ddead18f66fb64d9cf6e7d1d19d02 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -2,6 +2,10 @@ Changes with Apache 2.1.0-dev
 
   [Remove entries to the current 2.0 section below, when backported]
 
+  *) mod_include: Fix a trio of bugs that would cause various unusual
+     sequences of parsed bytes to omit portions of the output stream.
+     PR 21095. [Ron Park <ronald.park@cnet.com>, André Malo, Cliff Woolley]
+
   *) mod_ssl: Fix segfaults after renegotiation failure. PR 21370
      [Hartmut Keil <Hartmut.Keil@adnovum.ch>]
 
index 8a98822e0b4f01fad6cc6ee5b513160e74ad0217..067e281f22fc91e518cc7b15470b3cf34f290ed5 100644 (file)
@@ -429,7 +429,8 @@ static apr_bucket *find_start_sequence(apr_bucket *dptr, include_ctx_t *ctx,
         }
 
         if (len == 0) { /* end of pipe? */
-            break;
+            dptr = APR_BUCKET_NEXT(dptr);
+            continue;
         }
 
         /* Set our buffer to use. */
@@ -477,7 +478,7 @@ static apr_bucket *find_start_sequence(apr_bucket *dptr, include_ctx_t *ctx,
 
         if (len)
         {
-            pos = bndm(str, slen, c, len, ctx->start_seq_pat);
+            pos = bndm(str, slen, buf, len, ctx->start_seq_pat);
             if (pos != len)
             {
                 ctx->head_start_bucket = dptr;
@@ -600,7 +601,8 @@ static apr_bucket *find_end_sequence(apr_bucket *dptr, include_ctx_t *ctx,
         }
 
         if (len == 0) { /* end of pipe? */
-            break;
+            dptr = APR_BUCKET_NEXT(dptr);
+            continue;
         }
         if (dptr == ctx->tag_start_bucket) {
             c = buf + ctx->tag_start_index;
@@ -2956,14 +2958,19 @@ static apr_status_t send_parsed_content(apr_bucket_brigade **bb,
             /* If I am inside a conditional (if, elif, else) that is false
              *   then I need to throw away anything contained in it.
              */
-            if ((!(ctx->flags & FLAG_PRINTING)) && (tmp_dptr != NULL) &&
+            if ((!(ctx->flags & FLAG_PRINTING)) &&
                 (dptr != APR_BRIGADE_SENTINEL(*bb))) {
-                while ((dptr != APR_BRIGADE_SENTINEL(*bb)) &&
-                       (dptr != tmp_dptr)) {
+                apr_bucket *stop = (!tmp_dptr && ctx->state == PARSE_HEAD)
+                                   ? ctx->head_start_bucket
+                                   : tmp_dptr;
+
+                while ((dptr != APR_BRIGADE_SENTINEL(*bb)) && (dptr != stop)) {
                     apr_bucket *free_bucket = dptr;
 
-                    dptr = APR_BUCKET_NEXT (dptr);
-                    apr_bucket_delete(free_bucket);
+                    dptr = APR_BUCKET_NEXT(dptr);
+                    if (!APR_BUCKET_IS_METADATA(free_bucket)) {
+                        apr_bucket_delete(free_bucket);
+                    }
                 }
             }
 
@@ -3197,19 +3204,8 @@ static apr_status_t send_parsed_content(apr_bucket_brigade **bb,
      *   once the whole tag has been found.
      */
     if (ctx->state == PRE_HEAD) {
-        /* Inside a false conditional (if, elif, else), so toss it all... */
-        if ((dptr != APR_BRIGADE_SENTINEL(*bb)) &&
-            (!(ctx->flags & FLAG_PRINTING))) {
-            apr_bucket *free_bucket;
-            do {
-                free_bucket = dptr;
-                dptr = APR_BUCKET_NEXT (dptr);
-                apr_bucket_delete(free_bucket);
-            } while (dptr != APR_BRIGADE_SENTINEL(*bb));
-        }
-        else { 
-            /* Otherwise pass it along...
-             * No SSI tags in this brigade... */
+        if (!APR_BRIGADE_EMPTY(*bb)) {
+            /* pass it along... */
             rv = ap_pass_brigade(f->next, *bb);  
             if (rv != APR_SUCCESS) {
                 return rv;