]> granicus.if.org Git - apache/blobdiff - modules/filters/mod_substitute.c
Merge r1601624 from trunk:
[apache] / modules / filters / mod_substitute.c
index 9cebb916305708756e3b303b524e7cdc660c7ec3..99e82933ba40877f4b55c47b6121a47d8bb33264 100644 (file)
@@ -38,7 +38,7 @@
  * Therefore we limit the resulting length of the line.
  * This is the default value.
  */
-#define AP_SUBST_MAX_LINE_LENGTH (128*MAX_STRING_LEN)
+#define AP_SUBST_MAX_LINE_LENGTH (1024*1024)
 
 static const char substitute_filter_name[] = "SUBSTITUTE";
 
@@ -57,6 +57,7 @@ typedef struct {
     apr_array_header_t *patterns;
     apr_size_t max_line_length;
     int max_line_length_set;
+    int inherit_before;
 } subst_dir_conf;
 
 typedef struct {
@@ -70,26 +71,43 @@ typedef struct {
 static void *create_substitute_dcfg(apr_pool_t *p, char *d)
 {
     subst_dir_conf *dcfg =
-    (subst_dir_conf *) apr_pcalloc(p, sizeof(subst_dir_conf));
+        (subst_dir_conf *) apr_palloc(p, sizeof(subst_dir_conf));
 
     dcfg->patterns = apr_array_make(p, 10, sizeof(subst_pattern_t));
     dcfg->max_line_length = AP_SUBST_MAX_LINE_LENGTH;
+    dcfg->max_line_length_set = 0;
+    dcfg->inherit_before = -1;
     return dcfg;
 }
 
 static void *merge_substitute_dcfg(apr_pool_t *p, void *basev, void *overv)
 {
     subst_dir_conf *a =
-    (subst_dir_conf *) apr_pcalloc(p, sizeof(subst_dir_conf));
+        (subst_dir_conf *) apr_palloc(p, sizeof(subst_dir_conf));
     subst_dir_conf *base = (subst_dir_conf *) basev;
     subst_dir_conf *over = (subst_dir_conf *) overv;
 
-    a->patterns = apr_array_append(p, over->patterns,
-                                                  base->patterns);
+    a->inherit_before = (over->inherit_before != -1)
+                            ? over->inherit_before
+                            : base->inherit_before;
+    /* SubstituteInheritBefore wasn't the default behavior until 2.5.x,
+     * and may be re-disabled as desired; the original default behavior
+     * was to apply inherited subst patterns after locally scoped patterns.
+     * In later 2.2 and 2.4 versions, SubstituteInheritBefore may be toggled
+     * 'on' to follow the corrected/expected behavior, without violating POLS.
+     */
+    if (a->inherit_before == 1) {
+        a->patterns = apr_array_append(p, base->patterns,
+                                          over->patterns);
+    }
+    else {
+        a->patterns = apr_array_append(p, over->patterns,
+                                          base->patterns);
+    }
     a->max_line_length = over->max_line_length_set ?
-                         over->max_line_length : base->max_line_length;
-    a->max_line_length_set = over->max_line_length_set ?
-                             over->max_line_length_set : base->max_line_length_set;
+                             over->max_line_length : base->max_line_length;
+    a->max_line_length_set = over->max_line_length_set
+                           | base->max_line_length_set;
     return a;
 }
 
@@ -243,9 +261,13 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
                         apr_status_t rv;
                         have_match = 1;
                         if (script->flatten && !force_quick) {
-                            /* copy bytes before the match */
+                            /* check remaining buffer size */
+                            /* Note that the last param in ap_varbuf_regsub below
+                             * must stay positive. If it gets 0, it would mean
+                             * unlimited space available. */
                             if (vb.strlen + regm[0].rm_so >= cfg->max_line_length)
                                 return APR_ENOMEM;
+                            /* copy bytes before the match */
                             if (regm[0].rm_so > 0)
                                 ap_varbuf_strmemcat(&vb, pos, regm[0].rm_so);
                             /* add replacement string, last argument is unsigned! */
@@ -405,8 +427,8 @@ static apr_status_t substitute_filter(ap_filter_t *f, apr_bucket_brigade *bb)
                 if (rv != APR_SUCCESS)
                     goto err;
                 APR_BRIGADE_CONCAT(ctx->passbb, ctx->pattbb);
+                apr_brigade_cleanup(ctx->linebb);
             }
-            apr_brigade_cleanup(ctx->linebb);
             APR_BUCKET_REMOVE(b);
             APR_BRIGADE_INSERT_TAIL(ctx->passbb, b);
         }
@@ -672,7 +694,7 @@ static const char *set_max_line_length(cmd_parms *cmd, void *cfg, const char *ar
     if (rv != APR_SUCCESS || max < 0)
     {
         return "SubstituteMaxLineLength must be a non-negative integer optionally "
-               "suffixed with 'k', 'm' or 'g'.";
+               "suffixed with 'b', 'k', 'm' or 'g'.";
     }
     dcfg->max_line_length = (apr_size_t)max;
     dcfg->max_line_length_set = 1;
@@ -687,10 +709,13 @@ static void register_hooks(apr_pool_t *pool)
 }
 
 static const command_rec substitute_cmds[] = {
-    AP_INIT_TAKE1("Substitute", set_pattern, NULL, OR_ALL,
+    AP_INIT_TAKE1("Substitute", set_pattern, NULL, OR_FILEINFO,
                   "Pattern to filter the response content (s/foo/bar/[inf])"),
-    AP_INIT_TAKE1("SubstituteMaxLineLength", set_max_line_length, NULL, OR_ALL,
+    AP_INIT_TAKE1("SubstituteMaxLineLength", set_max_line_length, NULL, OR_FILEINFO,
                   "Maximum line length"),
+    AP_INIT_FLAG("SubstituteInheritBefore", ap_set_flag_slot,
+                 (void *)APR_OFFSETOF(subst_dir_conf, inherit_before), OR_FILEINFO,
+                 "Apply inherited patterns before those of the current context"),
     {NULL}
 };