diff --git a/docs/manual/mod/core.html.en b/docs/manual/mod/core.html.en index df55e3b..2463a02 100644 --- a/docs/manual/mod/core.html.en +++ b/docs/manual/mod/core.html.en @@ -2933,12 +2933,19 @@ from the client
Limit (in bytes) on maximum size of an XML-based request
- body. A value of 0
will disable any checking.
Limit (in bytes) on the maximum size of an XML-based request
+ body. A value of 0
will apply a hard limit (depending on
+ 32bit vs 64bit system) allowing for XML escaping within the bounds of
+ the system addressable memory, but it exists for compatibility only
+ and is not recommended since it does not account for memory consumed
+ elsewhere or concurrent requests, which might result in an overall
+ system out-of-memory.
+
Example:
-LimitXMLRequestBody 0+
# Limit of 1 MiB + LimitXMLRequestBody 1073741824diff --git a/server/core.c b/server/core.c index 456336c..de2b0d2 100644 --- a/server/core.c +++ b/server/core.c @@ -70,6 +70,8 @@ /* LimitXMLRequestBody handling */ #define AP_LIMIT_UNSET ((long) -1) #define AP_DEFAULT_LIMIT_XML_BODY ((apr_size_t)1000000) +/* Hard limit for ap_escape_html2() */ +#define AP_MAX_LIMIT_XML_BODY ((apr_size_t)(APR_SIZE_MAX / 6 - 1)) #define AP_MIN_SENDFILE_BYTES (256) @@ -3686,6 +3688,11 @@ static const char *set_limit_xml_req_body(cmd_parms *cmd, void *conf_, if (conf->limit_xml_body < 0) return "LimitXMLRequestBody requires a non-negative integer."; + /* zero is AP_MAX_LIMIT_XML_BODY (implicitly) */ + if ((apr_size_t)conf->limit_xml_body > AP_MAX_LIMIT_XML_BODY) + return apr_psprintf(cmd->pool, "LimitXMLRequestBody must not exceed " + "%" APR_SIZE_T_FMT, AP_MAX_LIMIT_XML_BODY); + return NULL; } @@ -3774,6 +3781,8 @@ AP_DECLARE(apr_size_t) ap_get_limit_xml_body(const request_rec *r) conf = ap_get_core_module_config(r->per_dir_config); if (conf->limit_xml_body == AP_LIMIT_UNSET) return AP_DEFAULT_LIMIT_XML_BODY; + if (conf->limit_xml_body == 0) + return AP_MAX_LIMIT_XML_BODY; return (apr_size_t)conf->limit_xml_body; } diff --git a/server/util.c b/server/util.c index e53bdc1..263270e 100644 --- a/server/util.c +++ b/server/util.c @@ -2037,11 +2037,14 @@ AP_DECLARE(char *) ap_escape_urlencoded(apr_pool_t *p, const char *buffer) AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc) { - int i, j; + apr_size_t i, j; char *x; /* first, count the number of extra characters */ - for (i = 0, j = 0; s[i] != '\0'; i++) + for (i = 0, j = 0; s[i] != '\0'; i++) { + if (i + j > APR_SIZE_MAX - 6) { + abort(); + } if (s[i] == '<' || s[i] == '>') j += 3; else if (s[i] == '&') @@ -2050,6 +2053,7 @@ AP_DECLARE(char *) ap_escape_html2(apr_pool_t *p, const char *s, int toasc) j += 5; else if (toasc && !apr_isascii(s[i])) j += 5; + } if (j == 0) return apr_pstrmemdup(p, s, i); diff --git a/server/util_xml.c b/server/util_xml.c index 4845194..22806fa 100644 --- a/server/util_xml.c +++ b/server/util_xml.c @@ -85,7 +85,7 @@ AP_DECLARE(int) ap_xml_parse_input(request_rec * r, apr_xml_doc **pdoc) } total_read += len; - if (limit_xml_body && total_read > limit_xml_body) { + if (total_read > limit_xml_body) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(00539) "XML request body is larger than the configured " "limit of %lu", (unsigned long)limit_xml_body);