You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by nd...@apache.org on 2004/05/18 01:36:16 UTC

cvs commit: httpd-2.0/modules/mappers mod_rewrite.c

nd          2004/05/17 16:36:16

  Modified:    .        CHANGES
               modules/mappers mod_rewrite.c
  Log:
  external map responses were cut at 2048 bytes (and possibly got out of sync that
  way). Now they are unlimited.
  
  Revision  Changes    Path
  1.1479    +3 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.1478
  retrieving revision 1.1479
  diff -u -u -r1.1478 -r1.1479
  --- CHANGES	13 May 2004 23:45:14 -0000	1.1478
  +++ CHANGES	17 May 2004 23:36:15 -0000	1.1479
  @@ -2,6 +2,9 @@
   
     [Remove entries to the current 2.0 section below, when backported]
   
  +  *) External rewrite map responses are no longer limited to 2048
  +     bytes.  [Andr� Malo]
  +
     *) Fix a potential SEGV in the 'shmcb' session cache when session data
        size is greater than the size of the cache. PR 27751
        [Geoff Thorpe <geoff geoffthorpe.net>]
  
  
  
  1.257     +84 -25    httpd-2.0/modules/mappers/mod_rewrite.c
  
  Index: mod_rewrite.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/mappers/mod_rewrite.c,v
  retrieving revision 1.256
  retrieving revision 1.257
  diff -u -u -r1.256 -r1.257
  --- mod_rewrite.c	10 Apr 2004 20:23:51 -0000	1.256
  +++ mod_rewrite.c	17 May 2004 23:36:15 -0000	1.257
  @@ -182,9 +182,9 @@
   #define REWRITE_MAX_TXT_MAP_LINE 1024
   #endif
   
  -/* max response length (incl.\n) in prg rewrite maps */
  -#ifndef REWRITE_MAX_PRG_MAP_LINE
  -#define REWRITE_MAX_PRG_MAP_LINE 2048
  +/* buffer length for prg rewrite maps */
  +#ifndef REWRITE_PRG_MAP_BUF
  +#define REWRITE_PRG_MAP_BUF 1024
   #endif
   
   /* for better readbility */
  @@ -1314,13 +1314,13 @@
   static char *lookup_map_program(request_rec *r, apr_file_t *fpin,
                                   apr_file_t *fpout, char *key)
   {
  -    char buf[REWRITE_MAX_PRG_MAP_LINE];
  +    char *buf;
       char c;
  -    apr_size_t i;
  -    apr_size_t nbytes;
  +    apr_size_t i, nbytes, combined_len = 0;
       apr_status_t rv;
       const char *eol = APR_EOL_STR;
  -    int eolc = 0;
  +    int eolc = 0, found_nl = 0;
  +    result_list *buflist = NULL, *curbuf = NULL;
   
   #ifndef NO_WRITEV
       struct iovec iova[2];
  @@ -1368,31 +1368,90 @@
       apr_file_writev(fpin, iova, niov, &nbytes);
   #endif
   
  +    buf = apr_palloc(r->pool, REWRITE_PRG_MAP_BUF + 1);
  +
       /* read in the response value */
  -    i = 0;
       nbytes = 1;
       apr_file_read(fpout, &c, &nbytes);
  -    while (nbytes == 1 && (i < REWRITE_MAX_PRG_MAP_LINE)) {
  -        if (c == eol[eolc]) {
  -            if (!eol[++eolc]) {
  -                /* remove eol from the buffer */
  -                i -= --eolc;
  +    do {
  +        i = 0;
  +        while (nbytes == 1 && (i < REWRITE_PRG_MAP_BUF)) {
  +            if (c == eol[eolc]) {
  +                if (!eol[++eolc]) {
  +                    /* remove eol from the buffer */
  +                    --eolc;
  +                    if (i < eolc) {
  +                        curbuf->len -= eolc-i;
  +                        i = 0;
  +                    }
  +                    else {
  +                        i -= eolc;
  +                    }
  +                    ++found_nl;
  +                    break;
  +                }
  +            }
  +
  +            /* only partial (invalid) eol sequence -> reset the counter */
  +            else if (eolc) {
  +                eolc = 0;
  +            }
  +
  +            /* catch binary mode, e.g. on Win32 */
  +            else if (c == '\n') {
  +                ++found_nl;
                   break;
               }
  -        }
   
  -        /* only partial (invalid) eol sequence -> reset the counter */
  -        else if (eolc) {
  -            eolc = 0;
  +            buf[i++] = c;
  +            apr_file_read(fpout, &c, &nbytes);
           }
   
  -        /* catch binary mode, e.g. on Win32 */
  -        else if (c == '\n') { 
  -            break;
  +        /* well, if there wasn't a newline yet, we need to read further */
  +        if (buflist || (nbytes == 1 && !found_nl)) {
  +            if (!buflist) {
  +                curbuf = buflist = apr_palloc(r->pool, sizeof(*buflist));
  +            }
  +            else if (i) {
  +                curbuf->next = apr_palloc(r->pool, sizeof(*buflist));
  +                curbuf = curbuf->next;
  +                
  +            }
  +            curbuf->next = NULL;
  +
  +            if (i) {
  +                curbuf->string = buf;
  +                curbuf->len = i;
  +                combined_len += i;
  +                buf = apr_palloc(r->pool, REWRITE_PRG_MAP_BUF);
  +            }
  +
  +            if (nbytes == 1 && !found_nl) {
  +                i = 0;
  +                continue;
  +            }
           }
   
  -        buf[i++] = c;
  -        apr_file_read(fpout, &c, &nbytes);
  +        break;
  +    } while (1);
  +
  +    /* concat the stuff */
  +    if (buflist) {
  +        char *p;
  +
  +        p = buf = apr_palloc(r->pool, combined_len + 1); /* \0 */
  +        while (buflist) {
  +            if (buflist->len) {
  +                memcpy(p, buflist->string, buflist->len);
  +                p += buflist->len;
  +            }
  +            buflist = buflist->next;
  +        }
  +        *p = '\0';
  +        i = combined_len;
  +    }
  +    else {
  +        buf[i] = '\0';
       }
   
       /* give the lock back */
  @@ -1406,12 +1465,12 @@
           }
       }
   
  -    /* buf is not zero terminated, so be careful! */
  -    if (i == 4 && strncasecmp(buf, "NULL", 4) == 0) {
  +    /* catch the "failed" case */
  +    if (i == 4 && !strcasecmp(buf, "NULL")) {
           return NULL;
       }
   
  -    return apr_pstrmemdup(r->pool, buf, i);
  +    return buf;
   }
   
   /*