From 91ce790cd3bda7b225671340c6637d345b688e74 Mon Sep 17 00:00:00 2001
From: Stefan Fritsch
The maximum length of a line in normal configuration files, after + variable substitution and joining any continued lines, is approximately + 16 MiB. In .htaccess files, the + maximum length is 8190 characters.
+You can check your configuration files for syntax errors
without starting the server by using apachectl
configtest
or the -t
command line
diff --git a/include/http_config.h b/include/http_config.h
index 649f4f6baf..40f0721443 100644
--- a/include/http_config.h
+++ b/include/http_config.h
@@ -818,6 +818,8 @@ AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp,
* @param cmd The cmd_parms to pass to the directives inside the container
* @param directive The directive name to read until
* @return Error string on failure, NULL on success
+ * @note If cmd->pool == cmd->temp_pool, ap_soak_end_container() will assume
+ * .htaccess context and use a lower maximum line length.
*/
AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive);
@@ -831,6 +833,8 @@ AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive);
* @param curr_parent The current parent node
* @param orig_directive The directive to read until hit.
* @return Error string on failure, NULL on success
+ * @note If p == temp_pool, ap_build_cont_config() will assume .htaccess
+ * context and use a lower maximum line length.
*/
AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
apr_pool_t *temp_pool,
@@ -846,6 +850,8 @@ AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
* @param temp_pool The temporary pool
* @param conftree Place to store the root node of the config tree
* @return Error string on erro, NULL otherwise
+ * @note If conf_pool == temp_pool, ap_build_config() will assume .htaccess
+ * context and use a lower maximum line length.
*/
AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
apr_pool_t *conf_pool,
diff --git a/include/util_varbuf.h b/include/util_varbuf.h
index 24aa088ef0..cb5346f954 100644
--- a/include/util_varbuf.h
+++ b/include/util_varbuf.h
@@ -151,10 +151,8 @@ AP_DECLARE(apr_status_t) ap_varbuf_regsub(struct ap_varbuf *vb,
/** Read a line from an ap_configfile_t into an ap_varbuf.
* @param vb pointer to the ap_varbuf struct
* @param cfg pointer to the ap_configfile_t
- * @param max_len (soft) limit for the size of the buffer
+ * @param max_len maximum line length, including leading/trailing whitespace
* @return see ap_cfg_getline()
- * @note The buffer will not be grown once it has reached at least max_len
- * bytes. This means that the returned line can be longer than max_len.
* @note vb->strlen will be set to the length of the line
*/
AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
diff --git a/server/config.c b/server/config.c
index 543129164c..8c56308b9a 100644
--- a/server/config.c
+++ b/server/config.c
@@ -1202,11 +1202,14 @@ AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
ap_directive_t *sub_tree = NULL;
apr_status_t rc;
struct ap_varbuf vb;
+ apr_size_t max_len = VARBUF_MAX_LEN;
+ if (p == temp_pool)
+ max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
bracket = apr_pstrcat(temp_pool, orig_directive + 1, ">", NULL);
ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
- while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, VARBUF_MAX_LEN))
+ while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
== APR_SUCCESS) {
if (!memcmp(vb.buf, "", 2)
&& (strcasecmp(vb.buf + 2, bracket) == 0)
@@ -1324,6 +1327,9 @@ AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
ap_directive_t **last_ptr = NULL;
apr_status_t rc;
struct ap_varbuf vb;
+ apr_size_t max_len = VARBUF_MAX_LEN;
+ if (p == temp_pool)
+ max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
@@ -1349,7 +1355,7 @@ AP_DECLARE(const char *) ap_build_config(cmd_parms *parms,
}
}
- while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, VARBUF_MAX_LEN))
+ while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, max_len))
== APR_SUCCESS) {
errmsg = ap_build_config_sub(p, temp_pool, vb.buf, parms,
¤t, &curr_parent, conftree);
@@ -1540,10 +1546,13 @@ AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive)
const char *args;
char *cmd_name;
apr_status_t rc;
+ apr_size_t max_len = VARBUF_MAX_LEN;
+ if (cmd->pool == cmd->temp_pool)
+ max_len = HUGE_STRING_LEN; /* lower limit for .htaccess */
ap_varbuf_init(cmd->temp_pool, &vb, VARBUF_INIT_LEN);
- while((rc = ap_varbuf_cfg_getline(&vb, cmd->config_file, VARBUF_MAX_LEN))
+ while((rc = ap_varbuf_cfg_getline(&vb, cmd->config_file, max_len))
== APR_SUCCESS) {
#if RESOLVE_ENV_PER_TOKEN
args = vb.buf;
diff --git a/server/util.c b/server/util.c
index b16aeadb4c..9ff8e39487 100644
--- a/server/util.c
+++ b/server/util.c
@@ -1112,6 +1112,8 @@ AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
ap_varbuf_grow(vb, new_len);
--cfp->line_number;
}
+ if (vb->strlen > max_len)
+ return APR_ENOSPC;
if (rc == APR_SUCCESS)
vb->strlen = cfg_trim_line(vb->buf);
return rc;
--
2.40.0