summaryrefslogtreecommitdiffstats
path: root/modules
diff options
context:
space:
mode:
authorStefan Fritsch <sf@apache.org>2011-11-08 03:10:57 +0100
committerStefan Fritsch <sf@apache.org>2011-11-08 03:10:57 +0100
commit0697ff3e6a8c09f9fa7e4ae0142a20afbce8b1a8 (patch)
treeafbf1cc35f28508696b9fc2ff29ba300e9241f94 /modules
parentmod_lua: Expose SSL variables via r:ssl_var_lookup() (diff)
downloadapache2-0697ff3e6a8c09f9fa7e4ae0142a20afbce8b1a8.tar.xz
apache2-0697ff3e6a8c09f9fa7e4ae0142a20afbce8b1a8.zip
Add some comments and another line length check
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1199060 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules')
-rw-r--r--modules/filters/mod_substitute.c56
1 files changed, 42 insertions, 14 deletions
diff --git a/modules/filters/mod_substitute.c b/modules/filters/mod_substitute.c
index 67f5ccfda0..a6004474e0 100644
--- a/modules/filters/mod_substitute.c
+++ b/modules/filters/mod_substitute.c
@@ -80,6 +80,10 @@ static void *merge_substitute_dcfg(apr_pool_t *p, void *basev, void *overv)
}
#define AP_MAX_BUCKETS 1000
+/*
+ * We want to limit the memory usage in a way that is predictable. Therefore
+ * we limit the resulting length of the line to this value.
+ */
#define AP_SUBST_MAX_LINE_LENGTH (128*MAX_STRING_LEN)
#define SEDRMPATBCKT(b, offset, tmp_b, patlen) do { \
@@ -137,6 +141,10 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
vb.strlen = 0;
if (script->pattern) {
const char *repl;
+ /*
+ * space_left counts how many bytes we have left until the
+ * line length reaches AP_SUBST_MAX_LINE_LENGTH.
+ */
apr_size_t space_left = AP_SUBST_MAX_LINE_LENGTH;
apr_size_t repl_len = strlen(script->replacement);
while ((repl = apr_strmatch(script->pattern, buff, bytes)))
@@ -160,13 +168,19 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
}
else {
/*
- * We now split off the stuff before the regex
- * as its own bucket, then isolate the pattern
- * and delete it.
+ * The string before the match but after the
+ * previous match (if any) has length 'len'.
+ * Check if we still have space for this string and
+ * the replacement string.
*/
if (space_left < len + repl_len)
return APR_ENOMEM;
space_left -= len + repl_len;
+ /*
+ * We now split off the string before the match
+ * as its own bucket, then isolate the matched
+ * string and delete it.
+ */
SEDRMPATBCKT(b, len, tmp_b, script->patlen);
/*
* Finally, we create a bucket that contains the
@@ -183,17 +197,31 @@ static apr_status_t do_pattmatch(ap_filter_t *f, apr_bucket *inb,
bytes -= len;
buff += len;
}
- if (have_match && script->flatten && !force_quick) {
- /* XXX: we should check for AP_MAX_BUCKETS here and
- * XXX: call ap_pass_brigade accordingly
- */
- char *copy = ap_varbuf_pdup(pool, &vb, NULL, 0,
- buff, bytes, &len);
- tmp_b = apr_bucket_pool_create(copy, len, pool,
- f->r->connection->bucket_alloc);
- APR_BUCKET_INSERT_BEFORE(b, tmp_b);
- apr_bucket_delete(b);
- b = tmp_b;
+ if (have_match) {
+ if (script->flatten && !force_quick) {
+ /* XXX: we should check for AP_MAX_BUCKETS here and
+ * XXX: call ap_pass_brigade accordingly
+ */
+ char *copy = ap_varbuf_pdup(pool, &vb, NULL, 0,
+ buff, bytes, &len);
+ tmp_b = apr_bucket_pool_create(copy, len, pool,
+ f->r->connection->bucket_alloc);
+ APR_BUCKET_INSERT_BEFORE(b, tmp_b);
+ apr_bucket_delete(b);
+ b = tmp_b;
+ }
+ else {
+ /*
+ * We want the behaviour to be predictable.
+ * Therefore we try to always error out if the
+ * line length is larger than the limit,
+ * regardless of the content of the line. So,
+ * let's check if the remaining non-matching
+ * string does not exceed the limit.
+ */
+ if (space_left < b->length)
+ return APR_ENOMEM;
+ }
}
}
else if (script->regexp) {