httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bri...@apache.org
Subject cvs commit: httpd-2.0/modules/filters mod_include.h mod_include.c
Date Sun, 06 Jan 2002 06:41:30 GMT
brianp      02/01/05 22:41:30

  Modified:    modules/filters mod_include.h mod_include.c
  Log:
  Eliminated various large (8KB) string buffers from the stack in
  mod_include by adding support for a power-of-two pool-based allocator
  in ap_ssi_parse_string(). (The default operation of this function
  is backward-compatible, to support the other modules that call it.)
  This change should help reduce memory usage for servers delivering
  shtml pages.
  
  Revision  Changes    Path
  1.28      +2 -2      httpd-2.0/modules/filters/mod_include.h
  
  Index: mod_include.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/filters/mod_include.h,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -r1.27 -r1.28
  --- mod_include.h	31 Dec 2001 05:58:58 -0000	1.27
  +++ mod_include.h	6 Jan 2002 06:41:30 -0000	1.28
  @@ -220,11 +220,11 @@
                                                            char **tag,
                                                            char **tag_val,
                                                            int dodecode));
  -APR_DECLARE_OPTIONAL_FN(void, ap_ssi_parse_string, (request_rec *r,
  +APR_DECLARE_OPTIONAL_FN(char*, ap_ssi_parse_string, (request_rec *r,
                                                       include_ctx_t *ctx,
                                                       const char *in,
                                                       char *out,
  -                                                    size_t length,
  +                                                    apr_size_t length,
                                                       int leave_name));
   APR_DECLARE_OPTIONAL_FN(void, ap_register_include_handler, 
                           (char *tag, include_handler_fn_t *func));
  
  
  
  1.183     +101 -31   httpd-2.0/modules/filters/mod_include.c
  
  Index: mod_include.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/modules/filters/mod_include.c,v
  retrieving revision 1.182
  retrieving revision 1.183
  diff -u -r1.182 -r1.183
  --- mod_include.c	31 Dec 2001 06:47:28 -0000	1.182
  +++ mod_include.c	6 Jan 2002 06:41:30 -0000	1.183
  @@ -899,28 +899,63 @@
       return;
   }
   
  +/* initial buffer size for power-of-two allocator in ap_ssi_parse_string */
  +#define PARSE_STRING_INITIAL_SIZE 64
   
   /*
    * Do variable substitution on strings
  + * (Note: If out==NULL, this function allocs a buffer for the resulting
  + * string from r->pool.  The return value is the parsed string)
    */
  -static void ap_ssi_parse_string(request_rec *r, include_ctx_t *ctx, 
  -                                const char *in, char *out,
  -                                size_t length, int leave_name)
  +static char *ap_ssi_parse_string(request_rec *r, include_ctx_t *ctx, 
  +                                 const char *in, char *out,
  +                                 apr_size_t length, int leave_name)
   {
       char ch;
  -    char *next = out;
  +    char *next;
       char *end_out;
  +    apr_size_t out_size;
  +
  +    /* allocate an output buffer if needed */
  +    if (!out) {
  +        out_size = PARSE_STRING_INITIAL_SIZE;
  +        if (out_size > length) {
  +            out_size = length;
  +        }
  +        out = apr_palloc(r->pool, out_size);
  +    }
  +    else {
  +        out_size = length;
  +    }
   
       /* leave room for nul terminator */
  -    end_out = out + length - 1;
  +    end_out = out + out_size - 1;
   
  +    next = out;
       while ((ch = *in++) != '\0') {
           switch (ch) {
           case '\\':
               if (next == end_out) {
  -                /* truncated */
  -                *next = '\0';
  -                return;
  +                if (out_size < length) {
  +                    /* double the buffer size */
  +                    apr_size_t new_out_size = out_size * 2;
  +                    apr_size_t current_length = next - out;
  +                    char *new_out;
  +                    if (new_out_size > length) {
  +                        new_out_size = length;
  +                    }
  +                    new_out = apr_palloc(r->pool, new_out_size);
  +                    memcpy(new_out, out, current_length);
  +                    out = new_out;
  +                    out_size = new_out_size;
  +                    end_out = out + out_size - 1;
  +                    next = out + current_length;
  +                }
  +                else {
  +                    /* truncated */
  +                    *next = '\0';
  +                    return out;
  +                }
               }
               if (*in == '$') {
                   *next++ = *in++;
  @@ -948,7 +983,7 @@
                                         0, r, "Missing '}' on variable \"%s\"",
                                         expansion);
                           *next = '\0';
  -                        return;
  +                        return out;
                       }
                       temp_end = in;
                       end_of_var_name = (char *)temp_end;
  @@ -988,6 +1023,24 @@
                        * copied */
                       l = 1;
                   }
  +                if ((next + l > end_out) && (out_size < length)) {
  +                    /* increase the buffer size to accommodate l more chars */
  +                    apr_size_t new_out_size = out_size;
  +                    apr_size_t current_length = next - out;
  +                    char *new_out;
  +                    do {
  +                        new_out_size *= 2;
  +                    } while (new_out_size < current_length + l);
  +                    if (new_out_size > length) {
  +                        new_out_size = length;
  +                    }
  +                    new_out = apr_palloc(r->pool, new_out_size);
  +                    memcpy(new_out, out, current_length);
  +                    out = new_out;
  +                    out_size = new_out_size;
  +                    end_out = out + out_size - 1;
  +                    next = out + current_length;
  +                }
                   l = ((int)l > end_out - next) ? (end_out - next) : l;
                   memcpy(next, expansion, l);
                   next += l;
  @@ -995,16 +1048,33 @@
               }
           default:
               if (next == end_out) {
  -                /* truncated */
  -                *next = '\0';
  -                return;
  +                if (out_size < length) {
  +                    /* double the buffer size */
  +                    apr_size_t new_out_size = out_size * 2;
  +                    apr_size_t current_length = next - out;
  +                    char *new_out;
  +                    if (new_out_size > length) {
  +                        new_out_size = length;
  +                    }
  +                    new_out = apr_palloc(r->pool, new_out_size);
  +                    memcpy(new_out, out, current_length);
  +                    out = new_out;
  +                    out_size = new_out_size;
  +                    end_out = out + out_size - 1;
  +                    next = out + current_length;
  +                }
  +                else {
  +                    /* truncated */
  +                    *next = '\0';
  +                    return out;
  +                }
               }
               *next++ = ch;
               break;
           }
       }
       *next = '\0';
  -    return;
  +    return out;
   }
   
   /* --------------------------- Action handlers ---------------------------- */
  @@ -1056,7 +1126,7 @@
       char *tag     = NULL;
       char *tag_val = NULL;
       apr_bucket  *tmp_buck;
  -    char parsed_string[MAX_STRING_LEN];
  +    char *parsed_string;
       int loglevel = APLOG_ERR;
   
       *inserted_head = NULL;
  @@ -1075,8 +1145,8 @@
                   request_rec *rr = NULL;
                   char *error_fmt = NULL;
   
  -                ap_ssi_parse_string(r, ctx, tag_val, parsed_string, 
  -                                    sizeof(parsed_string), 0);
  +                parsed_string = ap_ssi_parse_string(r, ctx, tag_val, NULL, 
  +                                                    MAX_STRING_LEN, 0);
                   if (tag[0] == 'f') {
                       /* XXX: Port to apr_filepath_merge
                        * be safe; only files in this directory or below allowed 
  @@ -1283,7 +1353,7 @@
   {
       char *tag     = NULL;
       char *tag_val = NULL;
  -    char parsed_string[MAX_STRING_LEN];
  +    char *parsed_string;
       apr_table_t *env = r->subprocess_env;
   
       *inserted_head = NULL;
  @@ -1325,8 +1395,8 @@
                                  ctx->time_str, 0));
               }
               else if (!strcmp(tag, "sizefmt")) {
  -                ap_ssi_parse_string(r, ctx, tag_val, parsed_string, 
  -                                    sizeof(parsed_string), 0);
  +                parsed_string = ap_ssi_parse_string(r, ctx, tag_val, NULL, 
  +                                                    MAX_STRING_LEN, 0);
                   decodehtml(parsed_string);
                   if (!strcmp(parsed_string, "bytes")) {
                       ctx->flags |= FLAG_SIZE_IN_BYTES;
  @@ -1435,7 +1505,7 @@
       apr_finfo_t  finfo;
       apr_size_t  s_len;
       apr_bucket   *tmp_buck;
  -    char parsed_string[MAX_STRING_LEN];
  +    char *parsed_string;
   
       *inserted_head = NULL;
       if (ctx->flags & FLAG_PRINTING) {
  @@ -1450,8 +1520,8 @@
                   }
               }
               else {
  -                ap_ssi_parse_string(r, ctx, tag_val, parsed_string, 
  -                                    sizeof(parsed_string), 0);
  +                parsed_string = ap_ssi_parse_string(r, ctx, tag_val, NULL, 
  +                                                    MAX_STRING_LEN, 0);
                   if (!find_file(r, "fsize", tag, parsed_string, &finfo)) {
                       /* XXX: if we *know* we're going to have to copy the
                        * thing off of the stack anyway, why not palloc buff
  @@ -1506,7 +1576,7 @@
       apr_finfo_t  finfo;
       apr_size_t  t_len;
       apr_bucket   *tmp_buck;
  -    char parsed_string[MAX_STRING_LEN];
  +    char *parsed_string;
   
       *inserted_head = NULL;
       if (ctx->flags & FLAG_PRINTING) {
  @@ -1521,8 +1591,8 @@
                   }
               }
               else {
  -                ap_ssi_parse_string(r, ctx, tag_val, parsed_string, 
  -                                    sizeof(parsed_string), 0);
  +                parsed_string = ap_ssi_parse_string(r, ctx, tag_val, NULL, 
  +                                                    MAX_STRING_LEN, 0);
                   if (!find_file(r, "flastmod", tag, parsed_string, &finfo)) {
                       char *t_val;
   
  @@ -1760,7 +1830,7 @@
           int value, done;
       } *root, *current, *new;
       const char *parse;
  -    char buffer[MAX_STRING_LEN];
  +    char* buffer;
       apr_pool_t *expr_pool;
       int retval = 0;
       apr_size_t debug_pos = 0;
  @@ -2109,8 +2179,8 @@
                       sizeof ("     Evaluate string\n"));
               debug_pos += sizeof ("     Evaluate string\n");
   #endif
  -            ap_ssi_parse_string(r, ctx, current->token.value, buffer, 
  -                                sizeof(buffer), 0);
  +            buffer = ap_ssi_parse_string(r, ctx, current->token.value, NULL, 
  +                                         MAX_STRING_LEN, 0);
               apr_cpystrn(current->token.value, buffer, 
                           sizeof(current->token.value));
               current->value = (current->token.value[0] != '\0');
  @@ -2648,7 +2718,7 @@
       char *tag_val = NULL;
       char *var     = NULL;
       apr_bucket *tmp_buck;
  -    char parsed_string[MAX_STRING_LEN];
  +    char *parsed_string;
   
       *inserted_head = NULL;
       if (ctx->flags & FLAG_PRINTING) {
  @@ -2672,8 +2742,8 @@
                                           *inserted_head);
                       return (-1);
                   }
  -                ap_ssi_parse_string(r, ctx, tag_val, parsed_string, 
  -                                    sizeof(parsed_string), 0);
  +                parsed_string = ap_ssi_parse_string(r, ctx, tag_val, NULL, 
  +                                                    MAX_STRING_LEN, 0);
                   apr_table_setn(r->subprocess_env, apr_pstrdup(r->pool, var),
                                  apr_pstrdup(r->pool, parsed_string));
               }
  
  
  

Mime
View raw message