From 3e5046a370a4eb0d1f2a578f4be7e985ba472de9 Mon Sep 17 00:00:00 2001 From: Eric Covener Date: Mon, 29 Dec 2014 17:27:46 +0000 Subject: [PATCH] Configuration files with long lines and continuation characters are not read properly. PR 55910. Submitted By: Manuel Mausz Committed By: covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1648394 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES | 3 +++ server/util.c | 30 +++++++++++++++--------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/CHANGES b/CHANGES index aa18620e41d..2049ac8564a 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ -*- coding: utf-8 -*- Changes with Apache 2.5.0 + *) core: Configuration files with long lines and continuation characters + are not read properly. PR 55910. [Manuel Mausz ] + *) mod_proxy_fcgi: Provide some basic alternate options for specifying how PATH_INFO is passed to FastCGI backends by adding significance to the value of proxy-fcgi-pathinfo. PR 55329. [Eric Covener] diff --git a/server/util.c b/server/util.c index c960248f7e0..c8932a2e772 100644 --- a/server/util.c +++ b/server/util.c @@ -971,20 +971,20 @@ AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp, /* Read one line from open ap_configfile_t, strip LF, increase line number */ /* If custom handler does not define a getstr() function, read char by char */ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, - ap_configfile_t *cfp) + apr_size_t offset, ap_configfile_t *cfp) { apr_status_t rc; /* If a "get string" function is defined, use it */ if (cfp->getstr != NULL) { char *cp; - char *cbuf = buf; - apr_size_t cbufsize = bufsize; + char *cbuf = buf + offset; + apr_size_t cbufsize = bufsize - offset; while (1) { ++cfp->line_number; rc = cfp->getstr(cbuf, cbufsize, cfp->param); if (rc == APR_EOF) { - if (cbuf != buf) { + if (cbuf != buf + offset) { *cbuf = '\0'; break; } @@ -1002,11 +1002,11 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, */ cp = cbuf; cp += strlen(cp); - if (cp > cbuf && cp[-1] == LF) { + if (cp > buf && cp[-1] == LF) { cp--; - if (cp > cbuf && cp[-1] == CR) + if (cp > buf && cp[-1] == CR) cp--; - if (cp > cbuf && cp[-1] == '\\') { + if (cp > buf && cp[-1] == '\\') { cp--; /* * line continuation requested - @@ -1024,19 +1024,19 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, } } else { /* No "get string" function defined; read character by character */ - apr_size_t i = 0; + apr_size_t i = offset; if (bufsize < 2) { /* too small, assume caller is crazy */ return APR_EINVAL; } - buf[0] = '\0'; + buf[offset] = '\0'; while (1) { char c; rc = cfp->getch(&c, cfp->param); if (rc == APR_EOF) { - if (i > 0) + if (i > offset) break; else return APR_EOF; @@ -1054,11 +1054,11 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, break; } } - else if (i >= bufsize - 2) { - return APR_ENOSPC; - } buf[i] = c; ++i; + if (i >= bufsize - 1) { + return APR_ENOSPC; + } } buf[i] = '\0'; } @@ -1092,7 +1092,7 @@ static int cfg_trim_line(char *buf) AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp) { - apr_status_t rc = ap_cfg_getline_core(buf, bufsize, cfp); + apr_status_t rc = ap_cfg_getline_core(buf, bufsize, 0, cfp); if (rc == APR_SUCCESS) cfg_trim_line(buf); return rc; @@ -1119,7 +1119,7 @@ AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb, } for (;;) { - rc = ap_cfg_getline_core(vb->buf + vb->strlen, vb->avail - vb->strlen, cfp); + rc = ap_cfg_getline_core(vb->buf, vb->avail, vb->strlen, cfp); if (rc == APR_ENOSPC || rc == APR_SUCCESS) vb->strlen += strlen(vb->buf + vb->strlen); if (rc != APR_ENOSPC) -- 2.47.3