dgaudet 99/01/25 10:12:43
Modified: src CHANGES
src/modules/standard mod_speling.c
Log:
Fix O(n^2) memory consumption in mod_speling. (Tested by
Renaud Bruyeron <[EMAIL PROTECTED]> and Eric Prud'hommeaux <[EMAIL
PROTECTED]>)
Revision Changes Path
1.1222 +4 -1 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.1221
retrieving revision 1.1222
diff -u -r1.1221 -r1.1222
--- CHANGES 1999/01/21 19:17:07 1.1221
+++ CHANGES 1999/01/25 18:12:36 1.1222
@@ -1,7 +1,10 @@
Changes with Apache 1.3.5
+ *) Fix O(n^2) memory consumption in mod_speling. [Dean Gaudet]
+
*) SECURITY: Avoid some buffer overflow problems when escaping
- quoted strings. [Rick Perry <[EMAIL PROTECTED]>]
+ quoted strings. (This overflow was on the heap and we believe
+ impossible to exploit.) [Rick Perry <[EMAIL PROTECTED]>]
*) Let src/Configure be aware of CFLAGS options starting with plus
signs as it's the case for the HP/UX compiler.
1.31 +48 -30 apache-1.3/src/modules/standard/mod_speling.c
Index: mod_speling.c
===================================================================
RCS file: /home/cvs/apache-1.3/src/modules/standard/mod_speling.c,v
retrieving revision 1.30
retrieving revision 1.31
diff -u -r1.30 -r1.31
--- mod_speling.c 1999/01/01 19:05:14 1.30
+++ mod_speling.c 1999/01/25 18:12:41 1.31
@@ -428,10 +428,13 @@
* returned.
*/
else {
- char *t;
pool *p;
table *notes;
+ pool *sub_pool;
+ array_header *t;
+ array_header *v;
+
if (r->main == NULL) {
p = r->pool;
notes = r->notes;
@@ -441,16 +444,22 @@
notes = r->main->notes;
}
+ sub_pool = ap_make_sub_pool(p);
+ t = ap_make_array(sub_pool, candidates->nelts * 8 + 8,
+ sizeof(char *));
+ v = ap_make_array(sub_pool, candidates->nelts * 5,
+ sizeof(char *));
+
/* Generate the response text. */
- /*
- * Since the text is expanded by repeated calls of
- * t = pstrcat(p, t, ".."), we can avoid a little waste
- * of memory by adding the header AFTER building the list.
- * XXX: FIXME: find a way to build a string concatenation
- * without repeatedly requesting new memory
- * XXX: FIXME: Limit the list to a maximum number of entries
- */
- t = "";
+
+ *(const char **)ap_push_array(t) =
+ "The document name you requested (<code>";
+ *(const char **)ap_push_array(t) = r->uri;
+ *(const char **)ap_push_array(t) =
+ "</code>) could not be found on this server.\n"
+ "However, we found documents with names similar "
+ "to the one you requested.<p>"
+ "Available documents:\n<ul>\n";
for (i = 0; i < candidates->nelts; ++i) {
char *vuri;
@@ -458,16 +467,24 @@
reason = sp_reason_str[(int) (variant[i].quality)];
/* The format isn't very neat... */
- vuri = ap_pstrcat(p, url, variant[i].name, r->path_info,
+ vuri = ap_pstrcat(sub_pool, url, variant[i].name, r->path_info,
(r->parsed_uri.query != NULL) ? "?" : "",
(r->parsed_uri.query != NULL)
? r->parsed_uri.query : "",
NULL);
- ap_table_mergen(r->subprocess_env, "VARIANTS",
- ap_pstrcat(p, "\"", vuri, "\";\"",
- reason, "\"", NULL));
- t = ap_pstrcat(p, t, "<li><a href=\"", vuri,
- "\">", vuri, "</a> (", reason, ")\n", NULL);
+ *(const char **)ap_push_array(v) = "\"";
+ *(const char **)ap_push_array(v) = vuri;
+ *(const char **)ap_push_array(v) = "\";\"";
+ *(const char **)ap_push_array(v) = reason;
+ *(const char **)ap_push_array(v) = "\"";
+
+ *(const char **)ap_push_array(t) = "<li><a href=\"";
+ *(const char **)ap_push_array(t) = vuri;
+ *(const char **)ap_push_array(t) = "\">";
+ *(const char **)ap_push_array(t) = vuri;
+ *(const char **)ap_push_array(t) = "</a> (";
+ *(const char **)ap_push_array(t) = reason;
+ *(const char **)ap_push_array(t) = ")\n";
/*
* when we have printed the "close matches" and there are
@@ -479,30 +496,31 @@
if (i > 0 && i < candidates->nelts - 1
&& variant[i].quality != SP_VERYDIFFERENT
&& variant[i + 1].quality == SP_VERYDIFFERENT) {
- t = ap_pstrcat(p, t,
+ *(const char **)ap_push_array(t) =
"</ul>\nFurthermore, the following related "
- "documents were found:\n<ul>\n", NULL);
+ "documents were found:\n<ul>\n";
}
}
- t = ap_pstrcat(p, "The document name you requested (<code>",
- r->uri,
- "</code>) could not be found on this server.\n"
- "However, we found documents with names similar "
- "to the one you requested.<p>"
- "Available documents:\n<ul>\n", t, "</ul>\n", NULL);
+ *(const char **)ap_push_array(t) = "</ul>\n";
/* If we know there was a referring page, add a note: */
if (ref != NULL) {
- t = ap_pstrcat(p, t,
+ *(const char **)ap_push_array(t) =
"Please consider informing the owner of the "
- "<a href=\"", ref,
- "\">referring page</a> "
- "about the broken link.\n",
- NULL);
+ "<a href=\"";
+ *(const char **)ap_push_array(t) = ref;
+ *(const char **)ap_push_array(t) = "\">referring page</a> "
+ "about the broken link.\n";
}
+
/* Pass our table to http_protocol.c (see mod_negotiation): */
- ap_table_setn(notes, "variant-list", t);
+ ap_table_setn(notes, "variant-list", ap_array_pstrcat(p, t, 0));
+
+ ap_table_mergen(r->subprocess_env, "VARIANTS",
+ ap_array_pstrcat(p, v, ','));
+
+ ap_destroy_pool(sub_pool);
ap_log_rerror(APLOG_MARK, APLOG_NOERRNO | APLOG_INFO, r,
ref ? "Spelling fix: %s: %d candidates from %s"