httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Dean Gaudet <dgau...@arctic.org>
Subject Re: [PATCH] Core dump with Language Negotiation?!?
Date Mon, 18 Jan 1999 18:37:39 GMT


On Mon, 18 Jan 1999, Roy T. Fielding wrote:

> +API_EXPORT(void) ap_copyover_table(table *dest, const table *source,
> +                                   unsigned flags)
> +{
> +    array_header *sarr = ap_table_elts(source);
> +    table_entry *selt = (table_entry *)sarr->elts;
> +    int i;
> +
> +    for (i = 0; i < sarr->nelts; ++i) {
> +        if (flags & AP_OVERLAP_TABLES_MERGE) {
> +            ap_table_merge(dest, selt[i].key, selt[i].val);
> +        }
> +        else {
> +            ap_table_set(dest, selt[i].key, selt[i].val);
> +        }
> +    }
> +}
> +

Another option is to add AP_OVERLAP_TABLES_COPY and tweak the overlap
tables code to strdup when necessary.  Otherwise there's a potential for
O(n^2) stuff.  Here's a completely untested patch:


Index: include/alloc.h
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/include/alloc.h,v
retrieving revision 1.66
diff -u -r1.66 alloc.h
--- alloc.h	1999/01/03 12:04:36	1.66
+++ alloc.h	1999/01/18 18:35:42
@@ -209,22 +209,33 @@
 
     for (i = 0; i < barr->nelts; ++i) {
 	if (flags & AP_OVERLAP_TABLES_MERGE) {
-	    ap_table_mergen(a, belt[i].key, belt[i].val);
+	    if (flags & AP_OVERLAP_TABLES_COPY) {
+		ap_table_merge(a, belt[i].key, belt[i].val);
+	    }
+	    else {
+		ap_table_mergen(a, belt[i].key, belt[i].val);
+	    }
 	}
 	else {
-	    ap_table_setn(a, belt[i].key, belt[i].val);
+	    if (flags & AP_OVERLAP_TABLES_COPY) {
+		ap_table_set(a, belt[i].key, belt[i].val);
+	    }
+	    else {
+		ap_table_setn(a, belt[i].key, belt[i].val);
+	    }
 	}
     }
 
     Except that it is more efficient (less space and cpu-time) especially
     when b has many elements.
 
-    Notice the assumptions on the keys and values in b -- they must be
-    in an ancestor of a's pool.  In practice b and a are usually from
-    the same pool.
+    Notice that unless AP_OVERLAP_TABLES_COPY is set, the keys and values
+    of b must be in an ancestor of a's pool.  In practice b and a are
+    usually from the same pool.
 */
 #define AP_OVERLAP_TABLES_SET	(0)
 #define AP_OVERLAP_TABLES_MERGE	(1)
+#define AP_OVERLAP_TABLES_COPY	(2)
 API_EXPORT(void) ap_overlap_tables(table *a, const table *b, unsigned flags);
 
 /* XXX: these know about the definition of struct table in alloc.c.  That
Index: main/alloc.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/main/alloc.c,v
retrieving revision 1.105
diff -u -r1.105 alloc.c
--- alloc.c	1999/01/03 12:04:37	1.105
+++ alloc.c	1999/01/18 18:35:52
@@ -1482,6 +1482,7 @@
     overlap_key *left;
     overlap_key *right;
     overlap_key *last;
+    int nkeys_a;
 
     nkeys = a->a.nelts + b->a.nelts;
     if (nkeys < AP_OVERLAP_TABLES_ON_STACK) {
@@ -1521,6 +1522,18 @@
 
     qsort(cat_keys, nkeys, sizeof(overlap_key), sort_overlap);
 
+    if (flags & AP_OVERLAP_TABLES_COPY) {
+	/* we have to copy a key/value if its order >= nkeys_a */
+	nkeys_a = a->a.nelts;
+    }
+    else {
+	/* order < nkeys for all keys, so we'll never copy... doing it
+	 * this way saves us a comparison.
+	 */
+	nkeys_a = nkeys;
+    }
+#define NEED_COPY(o)	((o)->order >= nkeys_a)
+
     /* Now iterate over the sorted list and rebuild a.
      * Start by making sure it has enough space.
      */
@@ -1548,7 +1561,9 @@
 	    right = left + 1;
 	    if (right == last
 		|| strcasecmp(left->key, right->key)) {
-		ap_table_addn(a, left->key, left->val);
+		(NEED_COPY(left)
+		    ? ap_table_add
+		    : ap_table_addn)(a, left->key, left->val);
 		left = right;
 	    }
 	    else {
@@ -1579,7 +1594,10 @@
 		    *strp++ = ' ';
 		}
 		*strp = 0;
-		ap_table_addn(a, (left-1)->key, value);
+		ap_table_addn(a,
+		    NEED_COPY(left-1) ? ap_pstrdup(a->a.pool, (left-1)->key)
+					: (left-1)->key,
+		    value);
 	    }
 	}
     }
@@ -1591,11 +1609,14 @@
 	    while (right < last && !strcasecmp(left->key, right->key)) {
 		++right;
 	    }
-	    ap_table_addn(a, (right-1)->key, (right-1)->val);
+	    (NEED_COPY(right-1)
+		? ap_table_add
+		: ap_table_addn)(a, (right-1)->key, (right-1)->val);
 	    left = right;
 	}
     }
 }
+#undef NEED_COPY
 
 /*****************************************************************
  *


Mime
View raw message