You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by sf...@apache.org on 2011/08/13 11:06:35 UTC
svn commit: r1157354 - in /httpd/httpd/trunk: CHANGES build/nw_export.inc
docs/manual/configuring.xml include/ap_mmn.h libhttpd.dsp
modules/aaa/mod_authz_groupfile.c server/config.c server/util.c
Author: sf
Date: Sat Aug 13 09:06:35 2011
New Revision: 1157354
URL: http://svn.apache.org/viewvc?rev=1157354&view=rev
Log:
Add ap_varbuf API for resizable buffers.
Increase length limit of lines in the configuration file to 16MB.
Increase length limit of lines in the group file to 16MB.
PR: 45888, 50824, 43084
Windows and Netware build changes are untested.
Modified:
httpd/httpd/trunk/CHANGES
httpd/httpd/trunk/build/nw_export.inc
httpd/httpd/trunk/docs/manual/configuring.xml
httpd/httpd/trunk/include/ap_mmn.h
httpd/httpd/trunk/libhttpd.dsp
httpd/httpd/trunk/modules/aaa/mod_authz_groupfile.c
httpd/httpd/trunk/server/config.c
httpd/httpd/trunk/server/util.c
Modified: httpd/httpd/trunk/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/CHANGES?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/CHANGES [utf-8] (original)
+++ httpd/httpd/trunk/CHANGES [utf-8] Sat Aug 13 09:06:35 2011
@@ -1,6 +1,14 @@
-*- coding: utf-8 -*-
Changes with Apache 2.3.15
+ *) mod_authz_groupfile: Increase length limit of lines in the group file to
+ 16MB. PR 43084. [Stefan Fritsch]
+
+ *) core: Increase length limit of lines in the configuration file to 16MB.
+ PR 45888. PR 50824. [Stefan Fritsch]
+
+ *) core: Add API for resizable buffers. [Stefan Fritsch]
+
*) mod_ldap: Enable LDAPConnectionTimeout for LDAP toolkits that have
LDAP_OPT_CONNECT_TIMEOUT instead of LDAP_OPT_NETWORK_TIMEOUT, such
as Tivoli Directory Server 6.3 and later. [Eric Covener]
Modified: httpd/httpd/trunk/build/nw_export.inc
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/build/nw_export.inc?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/build/nw_export.inc (original)
+++ httpd/httpd/trunk/build/nw_export.inc Sat Aug 13 09:06:35 2011
@@ -56,6 +56,7 @@
#include "util_mutex.h"
#include "util_script.h"
#include "util_time.h"
+#include "util_varbuf.h"
#include "util_xml.h"
#include "mod_core.h"
Modified: httpd/httpd/trunk/docs/manual/configuring.xml
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/docs/manual/configuring.xml?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/docs/manual/configuring.xml (original)
+++ httpd/httpd/trunk/docs/manual/configuring.xml Sat Aug 13 09:06:35 2011
@@ -96,10 +96,6 @@ Server.</p>
module="mod_env">SetEnv</directive>, take effect too late to be used for
expansions in the configuration file.</p>
- <p>The maximum length of a line in the configuration file, after
- variable substitution, joining any continued lines and removing leading
- and trailing white space, is 8192 characters.</p>
-
<p>You can check your configuration files for syntax errors
without starting the server by using <code>apachectl
configtest</code> or the <code>-t</code> command line
Modified: httpd/httpd/trunk/include/ap_mmn.h
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/include/ap_mmn.h?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/include/ap_mmn.h (original)
+++ httpd/httpd/trunk/include/ap_mmn.h Sat Aug 13 09:06:35 2011
@@ -347,6 +347,7 @@
* core_dir_config and htaccess_result
* 20110724.1 (2.3.15-dev) add NOT_IN_HTACCESS
* 20110724.2 (2.3.15-dev) retries and retry_delay in util_ldap_state_t
+ * 20110724.3 (2.3.15-dev) add util_varbuf.h / ap_varbuf API
*/
#define MODULE_MAGIC_COOKIE 0x41503234UL /* "AP24" */
@@ -354,7 +355,7 @@
#ifndef MODULE_MAGIC_NUMBER_MAJOR
#define MODULE_MAGIC_NUMBER_MAJOR 20110724
#endif
-#define MODULE_MAGIC_NUMBER_MINOR 2 /* 0...n */
+#define MODULE_MAGIC_NUMBER_MINOR 3 /* 0...n */
/**
* Determine if the server's current MODULE_MAGIC_NUMBER is at least a
Modified: httpd/httpd/trunk/libhttpd.dsp
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/libhttpd.dsp?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/libhttpd.dsp (original)
+++ httpd/httpd/trunk/libhttpd.dsp Sat Aug 13 09:06:35 2011
@@ -607,6 +607,10 @@ SOURCE=.\server\util_time.c
# End Source File
# Begin Source File
+SOURCE=.\include\util_varbuf.h
+# End Source File
+# Begin Source File
+
SOURCE=.\os\win32\util_win32.c
# End Source File
# Begin Source File
Modified: httpd/httpd/trunk/modules/aaa/mod_authz_groupfile.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/modules/aaa/mod_authz_groupfile.c?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/modules/aaa/mod_authz_groupfile.c (original)
+++ httpd/httpd/trunk/modules/aaa/mod_authz_groupfile.c Sat Aug 13 09:06:35 2011
@@ -52,6 +52,7 @@
#include "http_log.h"
#include "http_protocol.h"
#include "http_request.h"
+#include "util_varbuf.h"
#include "mod_auth.h"
@@ -90,13 +91,15 @@ static const command_rec authz_groupfile
module AP_MODULE_DECLARE_DATA authz_groupfile_module;
+#define VARBUF_INIT_LEN 512
+#define VARBUF_MAX_LEN (16*1024*1024)
static apr_status_t groups_for_user(apr_pool_t *p, char *user, char *grpfile,
apr_table_t ** out)
{
ap_configfile_t *f;
apr_table_t *grps = apr_table_make(p, 15);
apr_pool_t *sp;
- char l[MAX_STRING_LEN];
+ struct ap_varbuf vb;
const char *group_name, *ll, *w;
apr_status_t status;
apr_size_t group_len;
@@ -106,12 +109,13 @@ static apr_status_t groups_for_user(apr_
}
apr_pool_create(&sp, p);
+ ap_varbuf_init(p, &vb, VARBUF_INIT_LEN);
- while (!(ap_cfg_getline(l, MAX_STRING_LEN, f))) {
- if ((l[0] == '#') || (!l[0])) {
+ while (!(ap_varbuf_cfg_getline(&vb, f, VARBUF_MAX_LEN))) {
+ if ((vb.buf[0] == '#') || (!vb.buf[0])) {
continue;
}
- ll = l;
+ ll = vb.buf;
apr_pool_clear(sp);
group_name = ap_getword(sp, &ll, ':');
@@ -132,6 +136,7 @@ static apr_status_t groups_for_user(apr_
}
ap_cfg_closefile(f);
apr_pool_destroy(sp);
+ ap_varbuf_free(&vb);
*out = grps;
return APR_SUCCESS;
Modified: httpd/httpd/trunk/server/config.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/config.c?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/server/config.c (original)
+++ httpd/httpd/trunk/server/config.c Sat Aug 13 09:06:35 2011
@@ -49,6 +49,7 @@
#include "http_main.h"
#include "http_vhost.h"
#include "util_cfgtree.h"
+#include "util_varbuf.h"
#include "mpm_common.h"
#define APLOG_UNSET (APLOG_NO_MODULE - 1)
@@ -1186,6 +1187,9 @@ static const char *ap_build_config_sub(a
return retval;
}
+#define VARBUF_INIT_LEN 200
+#define VARBUF_MAX_LEN (16*1024*1024)
+
AP_DECLARE(const char *) ap_build_cont_config(apr_pool_t *p,
apr_pool_t *temp_pool,
cmd_parms *parms,
@@ -1193,27 +1197,23 @@ AP_DECLARE(const char *) ap_build_cont_c
ap_directive_t **curr_parent,
char *orig_directive)
{
- char *l;
char *bracket;
const char *retval;
ap_directive_t *sub_tree = NULL;
apr_status_t rc;
-
- /* Since this function can be called recursively, allocate
- * the temporary 8k string buffer from the temp_pool rather
- * than the stack to avoid over-running a fixed length stack.
- */
- l = apr_palloc(temp_pool, MAX_STRING_LEN);
+ struct ap_varbuf vb;
bracket = apr_pstrcat(temp_pool, orig_directive + 1, ">", NULL);
- while ((rc = ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))
+ ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
+
+ while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, VARBUF_MAX_LEN))
== APR_SUCCESS) {
- if (!memcmp(l, "</", 2)
- && (strcasecmp(l + 2, bracket) == 0)
+ if (!memcmp(vb.buf, "</", 2)
+ && (strcasecmp(vb.buf + 2, bracket) == 0)
&& (*curr_parent == NULL)) {
break;
}
- retval = ap_build_config_sub(p, temp_pool, l, parms, current,
+ retval = ap_build_config_sub(p, temp_pool, vb.buf, parms, current,
curr_parent, &sub_tree);
if (retval != NULL)
return retval;
@@ -1226,6 +1226,7 @@ AP_DECLARE(const char *) ap_build_cont_c
sub_tree = *current;
}
}
+ ap_varbuf_free(&vb);
if (rc != APR_EOF && rc != APR_SUCCESS)
return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
@@ -1319,10 +1320,12 @@ AP_DECLARE(const char *) ap_build_config
{
ap_directive_t *current = *conftree;
ap_directive_t *curr_parent = NULL;
- char *l = apr_palloc (temp_pool, MAX_STRING_LEN);
const char *errmsg;
ap_directive_t **last_ptr = NULL;
apr_status_t rc;
+ struct ap_varbuf vb;
+
+ ap_varbuf_init(temp_pool, &vb, VARBUF_INIT_LEN);
if (current != NULL) {
/* If we have to traverse the whole tree again for every included
@@ -1346,9 +1349,9 @@ AP_DECLARE(const char *) ap_build_config
}
}
- while ((rc = ap_cfg_getline(l, MAX_STRING_LEN, parms->config_file))
+ while ((rc = ap_varbuf_cfg_getline(&vb, parms->config_file, VARBUF_MAX_LEN))
== APR_SUCCESS) {
- errmsg = ap_build_config_sub(p, temp_pool, l, parms,
+ errmsg = ap_build_config_sub(p, temp_pool, vb.buf, parms,
¤t, &curr_parent, conftree);
if (errmsg != NULL)
return errmsg;
@@ -1361,6 +1364,7 @@ AP_DECLARE(const char *) ap_build_config
*conftree = current;
}
}
+ ap_varbuf_free(&vb);
if (rc != APR_EOF && rc != APR_SUCCESS)
return ap_pcfg_strerror(temp_pool, parms->config_file, rc);
@@ -1532,17 +1536,19 @@ AP_DECLARE(char *) ap_server_root_relati
AP_DECLARE(const char *) ap_soak_end_container(cmd_parms *cmd, char *directive)
{
- char l[MAX_STRING_LEN];
+ struct ap_varbuf vb;
const char *args;
char *cmd_name;
apr_status_t rc;
- while((rc = ap_cfg_getline(l, MAX_STRING_LEN, cmd->config_file))
+ ap_varbuf_init(cmd->temp_pool, &vb, VARBUF_INIT_LEN);
+
+ while((rc = ap_varbuf_cfg_getline(&vb, cmd->config_file, VARBUF_MAX_LEN))
== APR_SUCCESS) {
#if RESOLVE_ENV_PER_TOKEN
- args = l;
+ args = vb.buf;
#else
- args = ap_resolve_env(cmd->temp_pool, l);
+ args = ap_resolve_env(cmd->temp_pool, vb.buf);
#endif
cmd_name = ap_getword_conf(cmd->temp_pool, &args);
@@ -1556,6 +1562,7 @@ AP_DECLARE(const char *) ap_soak_end_con
cmd_name, ">", NULL);
}
+ ap_varbuf_free(&vb);
return NULL; /* found end of container */
}
else {
Modified: httpd/httpd/trunk/server/util.c
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/server/util.c?rev=1157354&r1=1157353&r2=1157354&view=diff
==============================================================================
--- httpd/httpd/trunk/server/util.c (original)
+++ httpd/httpd/trunk/server/util.c Sat Aug 13 09:06:35 2011
@@ -54,6 +54,7 @@
#include "http_config.h"
#include "http_core.h"
#include "util_ebcdic.h"
+#include "util_varbuf.h"
#ifdef HAVE_PWD_H
#include <pwd.h>
@@ -907,10 +908,10 @@ AP_DECLARE(const char *) ap_pcfg_strerro
/* 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 */
-AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, size_t bufsize, ap_configfile_t *cfp)
+static apr_status_t ap_cfg_getline_core(char *buf, size_t bufsize,
+ ap_configfile_t *cfp)
{
apr_status_t rc;
- char *src, *dst;
/* If a "get string" function is defined, use it */
if (cfp->getstr != NULL) {
char *cp;
@@ -922,12 +923,12 @@ AP_DECLARE(apr_status_t) ap_cfg_getline(
rc = cfp->getstr(cbuf, cbufsize, cfp->param);
if (rc == APR_EOF) {
if (cbuf != buf) {
- *cbuf = '\0';
+ *cbuf = '\0';
break;
- }
+ }
else {
return APR_EOF;
- }
+ }
}
if (rc != APR_SUCCESS) {
return rc;
@@ -997,27 +998,69 @@ AP_DECLARE(apr_status_t) ap_cfg_getline(
buf[i] = c;
++i;
}
- buf[i] = '\0';
+ buf[i] = '\0';
}
+ return APR_SUCCESS;
+}
+static int cfg_trim_line(char *buf)
+{
+ char *start, *end;
/*
* Leading and trailing white space is eliminated completely
*/
- src = buf;
- while (apr_isspace(*src))
- ++src;
+ start = buf;
+ while (apr_isspace(*start))
+ ++start;
/* blast trailing whitespace */
- dst = &src[strlen(src)];
- while (--dst >= src && apr_isspace(*dst))
- *dst = '\0';
+ end = &start[strlen(start)];
+ while (--end >= start && apr_isspace(*end))
+ *end = '\0';
/* Zap leading whitespace by shifting */
- if (src != buf)
- memmove(buf, src, dst - src + 2);
-
+ if (start != buf)
+ memmove(buf, start, end - start + 2);
#ifdef DEBUG_CFG_LINES
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, "Read config: '%s'", buf);
#endif
- return APR_SUCCESS;
+ return end - start + 1;
+}
+
+/* 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 */
+AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, size_t bufsize, ap_configfile_t *cfp)
+{
+ apr_status_t rc = ap_cfg_getline_core(buf, bufsize, cfp);
+ if (rc == APR_SUCCESS)
+ cfg_trim_line(buf);
+ return rc;
+}
+
+AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb,
+ ap_configfile_t *cfp,
+ apr_size_t max_len)
+{
+ apr_status_t rc;
+ vb->strlen = 0;
+ *vb->buf = '\0';
+
+ for (;;) {
+ apr_size_t new_len;
+ rc = ap_cfg_getline_core(vb->buf + vb->strlen, vb->avail - vb->strlen, cfp);
+ if (rc == APR_ENOSPC || rc == APR_SUCCESS)
+ vb->strlen += strlen(vb->buf + vb->strlen);
+ if (rc != APR_ENOSPC)
+ break;
+ if (vb->avail >= max_len)
+ return APR_ENOSPC;
+ new_len = vb->avail * 2;
+ if (new_len > max_len)
+ new_len = max_len;
+ ap_varbuf_grow(vb, new_len);
+ --cfp->line_number;
+ }
+ if (rc == APR_SUCCESS)
+ vb->strlen = cfg_trim_line(vb->buf);
+ return rc;
}
/* Size an HTTP header field list item, as separated by a comma.
@@ -2400,3 +2443,142 @@ AP_DECLARE(int) ap_parse_form_data(reque
return OK;
}
+
+#define VARBUF_SMALL_SIZE 2048
+#define VARBUF_MAX_SIZE (APR_SIZE_MAX - 1 - \
+ APR_ALIGN_DEFAULT(sizeof(struct ap_varbuf_info)))
+
+struct ap_varbuf_info {
+ struct apr_memnode_t *node;
+ apr_allocator_t *allocator;
+};
+
+static apr_status_t varbuf_cleanup(void *info_)
+{
+ struct ap_varbuf_info *info = info_;
+ info->node->next = NULL;
+ apr_allocator_free(info->allocator, info->node);
+ return APR_SUCCESS;
+}
+
+AP_DECLARE(void) ap_varbuf_init(apr_pool_t *p, struct ap_varbuf *vb,
+ apr_size_t init_size)
+{
+ vb->buf = NULL;
+ vb->avail = 0;
+ vb->strlen = AP_VARBUF_UNKNOWN;
+ vb->pool = p;
+ vb->info = NULL;
+
+ ap_varbuf_grow(vb, init_size);
+}
+
+AP_DECLARE(void) ap_varbuf_grow(struct ap_varbuf *vb, apr_size_t new_len)
+{
+ apr_memnode_t *new_node = NULL;
+ apr_allocator_t *allocator;
+ struct ap_varbuf_info *new_info;
+ char *new;
+
+ if (new_len <= vb->avail)
+ return;
+
+ if (new_len < 2 * vb->avail && vb->avail < VARBUF_MAX_SIZE/2) {
+ /* at least double the size, to avoid repeated reallocations */
+ new_len = 2 * vb->avail;
+ }
+ else if (new_len > VARBUF_MAX_SIZE) {
+ apr_abortfunc_t abort_fn = apr_pool_abort_get(vb->pool);
+ ap_assert(abort_fn != NULL);
+ abort_fn(APR_ENOMEM);
+ return;
+ }
+
+ new_len++; /* add space for trailing \0 */
+ if (new_len <= VARBUF_SMALL_SIZE) {
+ new_len = APR_ALIGN_DEFAULT(new_len);
+ new = apr_palloc(vb->pool, new_len);
+ if (vb->buf && vb->strlen > 0) {
+ AP_DEBUG_ASSERT(vb->avail > 0);
+ if (new == vb->buf + vb->avail + 1) {
+ /* We are lucky: the new memory lies directly after our old
+ * buffer, we can now use both.
+ */
+ vb->avail += new_len;
+ return;
+ }
+ else {
+ /* copy up to vb->strlen + 1 bytes */
+ memcpy(new, vb->buf, vb->strlen > vb->avail ?
+ vb->avail + 1 : vb->strlen + 1);
+ }
+ }
+ else {
+ *new = '\0';
+ }
+ vb->avail = new_len - 1;
+ vb->buf = new;
+ return;
+ }
+
+ /* The required block is rather larger. Use allocator directly so that
+ * the memory can be freed independently from the pool. */
+ allocator = apr_pool_allocator_get(vb->pool);
+ if (new_len <= VARBUF_MAX_SIZE)
+ new_node = apr_allocator_alloc(allocator,
+ new_len + APR_ALIGN_DEFAULT(sizeof(*new_info)));
+ if (!new_node) {
+ apr_abortfunc_t abort_fn = apr_pool_abort_get(vb->pool);
+ ap_assert(abort_fn != NULL);
+ abort_fn(APR_ENOMEM);
+ return;
+ }
+ new_info = (struct ap_varbuf_info *)new_node->first_avail;
+ new_node->first_avail += APR_ALIGN_DEFAULT(sizeof(*new_info));
+ new_info->node = new_node;
+ new_info->allocator = allocator;
+ new = new_node->first_avail;
+ AP_DEBUG_ASSERT(new_node->endp - new_node->first_avail >= new_len);
+ new_len = new_node->endp - new_node->first_avail;
+
+ if (vb->buf && vb->strlen > 0)
+ memcpy(new, vb->buf, vb->strlen > vb->avail ?
+ vb->avail + 1: vb->strlen + 1);
+ else
+ *new = '\0';
+ if (vb->info)
+ apr_pool_cleanup_run(vb->pool, vb->info, varbuf_cleanup);
+ apr_pool_cleanup_register(vb->pool, new_info, varbuf_cleanup,
+ apr_pool_cleanup_null);
+ vb->info = new_info;
+ vb->buf = new;
+ vb->avail = new_len - 1;
+}
+
+AP_DECLARE(void) ap_varbuf_strmemcat(struct ap_varbuf *vb, const char *str,
+ int len)
+{
+ AP_DEBUG_ASSERT(len == strlen(str));
+ if (!vb->avail) {
+ ap_varbuf_grow(vb, len);
+ memcpy(vb->buf, str, len + 1);
+ return;
+ }
+ if (vb->strlen > vb->avail) {
+ AP_DEBUG_ASSERT(vb->strlen == AP_VARBUF_UNKNOWN);
+ vb->strlen = strlen(vb->buf);
+ }
+ ap_varbuf_grow(vb, vb->strlen + len);
+ memcpy(vb->buf + vb->strlen, str, len);
+ vb->strlen += len;
+ vb->buf[vb->strlen] = '\0';
+}
+
+AP_DECLARE(void) ap_varbuf_free(struct ap_varbuf *vb)
+{
+ if (vb->info) {
+ apr_pool_cleanup_run(vb->pool, vb->info, varbuf_cleanup);
+ vb->info = NULL;
+ }
+ vb->buf = NULL;
+}