changeset 1782:2f3d906d99d8 HEAD

data_stack_pool split into two: unsafe_data_stack_pool which works like before, and a new one which verifies that stack frame stays the same whenever the pool is accessed.
author Timo Sirainen <tss@iki.fi>
date Sun, 21 Sep 2003 19:21:36 +0300
parents 986d5dac10c8
children 46d2094ac470
files src/auth/auth-master-connection.c src/auth/mech-digest-md5.c src/auth/mech-plain.c src/auth/mech.c src/auth/passdb-pam.c src/imap-login/client-authenticate.c src/imap-login/client.c src/imap/cmd-append.c src/imap/cmd-sort.c src/imap/imap-fetch-body-section.c src/imap/imap-fetch.c src/imap/imap-sort.c src/imap/imap-thread.c src/lib-charset/charset-utf8.c src/lib-imap/imap-bodystructure.c src/lib-imap/imap-envelope.c src/lib-imap/imap-quote.c src/lib-index/mail-cache.c src/lib-index/mail-modifylog.c src/lib-index/mbox/mbox-index.c src/lib-index/mbox/mbox-rewrite.c src/lib-mail/message-address.c src/lib-mail/message-body-search.c src/lib-mail/message-header-decode.c src/lib-storage/index/index-mail-headers.c src/lib-storage/index/index-mail.c src/lib-storage/index/index-search.c src/lib-storage/index/maildir/maildir-save.c src/lib-storage/mail-search.c src/lib/Makefile.am src/lib/mempool-alloconly.c src/lib/mempool-datastack.c src/lib/mempool-system.c src/lib/mempool-unsafe-datastack.c src/lib/mempool.h src/lib/str.c src/lib/strfuncs.c src/pop3-login/client-authenticate.c src/pop3-login/client.c
diffstat 39 files changed, 231 insertions(+), 73 deletions(-) [+]
line wrap: on
line diff
--- a/src/auth/auth-master-connection.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/auth/auth-master-connection.c	Sun Sep 21 19:21:36 2003 +0300
@@ -42,7 +42,7 @@
 	buffer_t *buf;
 	char *p;
 
-	buf = buffer_create_dynamic(data_stack_pool,
+	buf = buffer_create_dynamic(pool_datastack_create(),
 				    sizeof(reply) + 256, (size_t)-1);
 	memset(&reply, 0, sizeof(reply));
 	buffer_append(buf, &reply, sizeof(reply));
--- a/src/auth/mech-digest-md5.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/auth/mech-digest-md5.c	Sun Sep 21 19:21:36 2003 +0300
@@ -76,7 +76,7 @@
 	random_fill(nonce, sizeof(nonce));
 
 	t_push();
-	buf = buffer_create_static(data_stack_pool,
+	buf = buffer_create_static(pool_datastack_create(),
 				   MAX_BASE64_ENCODED_SIZE(sizeof(nonce))+1);
 
 	base64_encode(nonce, sizeof(nonce), buf);
@@ -123,7 +123,7 @@
 	if (credentials == NULL || strlen(credentials) != sizeof(digest)*2)
 		return FALSE;
 
-	digest_buf = buffer_create_data(data_stack_pool,
+	digest_buf = buffer_create_data(pool_datastack_create(),
 					digest, sizeof(digest));
 	if (hex_to_binary(credentials, digest_buf) <= 0)
 		return FALSE;
--- a/src/auth/mech-plain.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/auth/mech-plain.c	Sun Sep 21 19:21:36 2003 +0300
@@ -35,7 +35,8 @@
 			else {
 				i++;
 				len = request->data_size - i;
-				pass = p_strndup(data_stack_pool, data+i, len);
+				pass = p_strndup(unsafe_data_stack_pool,
+						 data+i, len);
 				break;
 			}
 		}
--- a/src/auth/mech.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/auth/mech.c	Sun Sep 21 19:21:36 2003 +0300
@@ -147,7 +147,7 @@
 {
 	buffer_t *buf;
 
-	buf = buffer_create_dynamic(data_stack_pool, 256, (size_t)-1);
+	buf = buffer_create_dynamic(pool_datastack_create(), 256, (size_t)-1);
 
 	reply->username_idx = 0;
 	buffer_append(buf, auth_request->user, strlen(auth_request->user)+1);
--- a/src/auth/passdb-pam.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/auth/passdb-pam.c	Sun Sep 21 19:21:36 2003 +0300
@@ -243,7 +243,8 @@
 		}
 	}
 
-	buf = buffer_create_data(data_stack_pool, buf_data, sizeof(buf_data));
+	buf = buffer_create_data(pool_datastack_create(),
+				 buf_data, sizeof(buf_data));
 	buffer_append(buf, &result, sizeof(result));
 
 	if (str != NULL) {
--- a/src/imap-login/client-authenticate.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap-login/client-authenticate.c	Sun Sep 21 19:21:36 2003 +0300
@@ -108,7 +108,8 @@
 
 	t_push();
 
-	buf = buffer_create_dynamic(data_stack_pool, size*2, (size_t)-1);
+	buf = buffer_create_dynamic(pool_datastack_create(),
+				    size*2, (size_t)-1);
 	buffer_append(buf, "+ ", 2);
 	base64_encode(data, size, buf);
 	buffer_append(buf, "\r\n", 2);
@@ -261,7 +262,7 @@
 	}
 
 	linelen = strlen(line);
-	buf = buffer_create_static_hard(data_stack_pool, linelen);
+	buf = buffer_create_static_hard(pool_datastack_create(), linelen);
 
 	if (base64_decode((const unsigned char *) line, linelen,
 			  NULL, buf) <= 0) {
--- a/src/imap-login/client.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap-login/client.c	Sun Sep 21 19:21:36 2003 +0300
@@ -322,7 +322,7 @@
 	size_t i, count;
 
 	/* find the oldest clients and put them to destroy-buffer */
-	destroy_buf = buffer_create_static_hard(data_stack_pool,
+	destroy_buf = buffer_create_static_hard(pool_datastack_create(),
 						sizeof(struct imap_client *) *
 						CLIENT_DESTROY_OLDEST_COUNT);
 	hash_foreach(clients, client_hash_destroy_oldest, destroy_buf);
--- a/src/imap/cmd-append.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap/cmd-append.c	Sun Sep 21 19:21:36 2003 +0300
@@ -84,7 +84,7 @@
 		return TRUE;
 	}
 	memset(&old_flags, 0, sizeof(old_flags));
-        old_flags.pool = data_stack_pool;
+        old_flags.pool = pool_datastack_create();
 	client_save_custom_flags(&old_flags, status.custom_flags,
 				 status.custom_flags_count);
 
--- a/src/imap/cmd-sort.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap/cmd-sort.c	Sun Sep 21 19:21:36 2003 +0300
@@ -37,7 +37,7 @@
 		return NULL;
 	}
 
-	buf = buffer_create_dynamic(data_stack_pool,
+	buf = buffer_create_dynamic(pool_datastack_create(),
 				    32 * sizeof(enum mail_sort_type),
 				    (size_t)-1);
 
--- a/src/imap/imap-fetch-body-section.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap/imap-fetch-body-section.c	Sun Sep 21 19:21:36 2003 +0300
@@ -339,7 +339,7 @@
 		i_assert(hdr_ctx.dest_size <= size->virtual_size);
 	} else {
 		hdr_ctx.dest =
-			buffer_create_dynamic(data_stack_pool,
+			buffer_create_dynamic(pool_datastack_create(),
 					      I_MIN(size->virtual_size, 8192),
 					      (size_t)-1);
 		if (!fetch_header_fields(input, header_section, &hdr_ctx))
--- a/src/imap/imap-fetch.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap/imap-fetch.c	Sun Sep 21 19:21:36 2003 +0300
@@ -365,7 +365,7 @@
 	   separately rather than parsing the full header so mail storage
 	   can try to cache them. */
 	ctx.body_fetch_from_cache = TRUE;
-	buffer = buffer_create_dynamic(data_stack_pool, 64, (size_t)-1);
+	buffer = buffer_create_dynamic(pool_datastack_create(), 64, (size_t)-1);
 	for (body = bodies; body != NULL; body = body->next) {
 		if (strncmp(body->section, "HEADER.FIELDS ", 14) != 0) {
                         ctx.body_fetch_from_cache = FALSE;
--- a/src/imap/imap-sort.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap/imap-sort.c	Sun Sep 21 19:21:36 2003 +0300
@@ -203,7 +203,8 @@
 	ctx = t_new(struct sort_context, 1);
 
 	/* normalize sorting program */
-	buf = buffer_create_data(data_stack_pool, norm_prog, sizeof(norm_prog));
+	buf = buffer_create_data(pool_datastack_create(),
+				 norm_prog, sizeof(norm_prog));
 	mail_sort_normalize(sort_program, buf);
 	memcpy(ctx->sort_program, norm_prog, sizeof(ctx->sort_program));
 
@@ -284,7 +285,7 @@
 	if (str == NULL)
 		return NULL;
 
-	addr = message_address_parse(data_stack_pool,
+	addr = message_address_parse(pool_datastack_create(),
 				     (const unsigned char *) str,
 				     (size_t)-1, 1);
 	return addr != NULL ? addr->mailbox : NULL;
--- a/src/imap/imap-thread.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/imap/imap-thread.c	Sun Sep 21 19:21:36 2003 +0300
@@ -298,7 +298,8 @@
 			if (found_at) {
 				char *s;
 
-				s = p_strdup_until(data_stack_pool, msgid, p);
+				s = p_strdup_until(unsafe_data_stack_pool,
+						   msgid, p);
 				strip_lwsp(s);
 				return s;
 			}
@@ -623,7 +624,7 @@
 	if (subject == NULL)
 		return;
 
-	subject = imap_get_base_subject_cased(data_stack_pool, subject,
+	subject = imap_get_base_subject_cased(pool_datastack_create(), subject,
 					      &is_reply_or_forward);
 	if (*subject == '\0')
 		return;
--- a/src/lib-charset/charset-utf8.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-charset/charset-utf8.c	Sun Sep 21 19:21:36 2003 +0300
@@ -22,7 +22,7 @@
 {
 	buffer_t *dest;
 
-	dest = buffer_create_dynamic(data_stack_pool, size, (size_t)-1);
+	dest = buffer_create_dynamic(pool_datastack_create(), size, (size_t)-1);
 	_charset_utf8_ucase(data, size, dest, 0);
 	if (utf8_size_r != NULL)
 		*utf8_size_r = buffer_get_used_size(dest);
--- a/src/lib-imap/imap-bodystructure.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-imap/imap-bodystructure.c	Sun Sep 21 19:21:36 2003 +0300
@@ -658,7 +658,8 @@
 	len = strlen(bodystructure);
 	str = t_str_new(len);
 
-	input = i_stream_create_from_data(data_stack_pool, bodystructure, len);
+	input = i_stream_create_from_data(pool_datastack_create(),
+					  bodystructure, len);
 	(void)i_stream_read(input);
 
 	parser = imap_parser_create(input, NULL, (size_t)-1);
--- a/src/lib-imap/imap-envelope.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-imap/imap-envelope.c	Sun Sep 21 19:21:36 2003 +0300
@@ -380,7 +380,7 @@
 
 	i_assert(field < IMAP_ENVELOPE_FIELDS);
 
-	input = i_stream_create_from_data(data_stack_pool, envelope,
+	input = i_stream_create_from_data(pool_datastack_create(), envelope,
 					  strlen(envelope));
 	parser = imap_parser_create(input, NULL, (size_t)-1);
 
--- a/src/lib-imap/imap-quote.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-imap/imap-quote.c	Sun Sep 21 19:21:36 2003 +0300
@@ -91,8 +91,6 @@
 	string_t *str;
 	char *ret;
 
-	i_assert(pool != data_stack_pool);
-
 	if (value == NULL)
 		return "NIL";
 
--- a/src/lib-index/mail-cache.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-index/mail-cache.c	Sun Sep 21 19:21:36 2003 +0300
@@ -540,7 +540,8 @@
 	int i;
 
 	memset(&cache_rec, 0, sizeof(cache_rec));
-	buffer = buffer_create_dynamic(data_stack_pool, 4096, (size_t)-1);
+	buffer = buffer_create_dynamic(pool_datastack_create(),
+				       4096, (size_t)-1);
 
         orig_cached_fields = mail_cache_get_fields(cache, rec);
 	cached_fields = orig_cached_fields & ~MAIL_CACHE_HEADERS_MASK;
@@ -1283,7 +1284,8 @@
 
 	t_push();
 
-	buffer = buffer_create_dynamic(data_stack_pool, 512, (size_t)-1);
+	buffer = buffer_create_dynamic(pool_datastack_create(),
+				       512, (size_t)-1);
 	while (*headers != NULL) {
 		if (buffer_get_used_size(buffer) != 0)
 			buffer_append(buffer, "\n", 1);
--- a/src/lib-index/mail-modifylog.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-index/mail-modifylog.c	Sun Sep 21 19:21:36 2003 +0300
@@ -1109,7 +1109,8 @@
 
 	i_assert((max_records+1) <
 		 SSIZE_T_MAX / sizeof(struct modify_log_expunge));
-	buf = buffer_create_static_hard(data_stack_pool, (max_records+1) *
+	buf = buffer_create_static_hard(pool_datastack_create(),
+					(max_records+1) *
 					sizeof(struct modify_log_expunge));
 
 	before = 0;
@@ -1215,7 +1216,8 @@
 
 	i_assert((max_records+1) <
 		 SSIZE_T_MAX / sizeof(struct modify_log_expunge));
-	buf = buffer_create_static_hard(data_stack_pool, (max_records+1) *
+	buf = buffer_create_static_hard(pool_datastack_create(),
+					(max_records+1) *
 					sizeof(struct modify_log_expunge));
 
 	before = 0;
--- a/src/lib-index/mbox/mbox-index.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-index/mbox/mbox-index.c	Sun Sep 21 19:21:36 2003 +0300
@@ -219,7 +219,7 @@
 	}
 
 	/* we're at the 3rd field now, which begins the list of custom flags */
-	buf = buffer_create_dynamic(data_stack_pool,
+	buf = buffer_create_dynamic(pool_datastack_create(),
 				    MAIL_CUSTOM_FLAGS_COUNT *
 				    sizeof(const char *),
 				    MAX_CUSTOM_FLAGS * sizeof(const char *));
--- a/src/lib-index/mbox/mbox-rewrite.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-index/mbox/mbox-rewrite.c	Sun Sep 21 19:21:36 2003 +0300
@@ -506,11 +506,12 @@
 
 	t_push();
 
-	input = i_stream_create_mmap(in_fd, data_stack_pool,
+	input = i_stream_create_mmap(in_fd, pool_datastack_create(),
 				     1024*256, 0, 0, FALSE);
 	i_stream_set_read_limit(input, size);
 
-	output = o_stream_create_file(out_fd, data_stack_pool, 1024, FALSE);
+	output = o_stream_create_file(out_fd, pool_datastack_create(),
+				      1024, FALSE);
 	o_stream_set_blocking(output, 60000, NULL, NULL);
 
 	ret = o_stream_send_istream(output, input);
--- a/src/lib-mail/message-address.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-mail/message-address.c	Sun Sep 21 19:21:36 2003 +0300
@@ -66,7 +66,7 @@
 	message_tokenize_skip_comments(tok, FALSE);
         message_tokenize_dot_token(tok, FALSE);
 
-	if (pool != data_stack_pool)
+	if (!pool->datastack_pool)
 		t_push();
 	mailbox = t_str_new(128);
 	domain = t_str_new(256);
@@ -213,7 +213,7 @@
 	if (ingroup)
 		(void)new_address(pool, &next_addr);
 
-	if (pool != data_stack_pool)
+	if (!pool->datastack_pool)
 		t_pop();
 	message_tokenize_deinit(tok);
 
--- a/src/lib-mail/message-body-search.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-mail/message-body-search.c	Sun Sep 21 19:21:36 2003 +0300
@@ -107,7 +107,7 @@
 	struct message_header_line *hdr;
 	int found = FALSE;
 
-	hdr_search_ctx = message_header_search_init(data_stack_pool,
+	hdr_search_ctx = message_header_search_init(pool_datastack_create(),
 						    ctx->body_ctx->key,
 						    ctx->body_ctx->charset,
 						    NULL);
@@ -214,7 +214,8 @@
         enum charset_result result;
 	size_t block_pos, inbuf_size, inbuf_left, ret;
 
-	outbuf = buffer_create_static(data_stack_pool, DECODE_BLOCK_SIZE);
+	outbuf = buffer_create_static(pool_datastack_create(),
+				      DECODE_BLOCK_SIZE);
 	for (block_pos = 0; block_pos < buffer_get_used_size(block); ) {
 		if (buffer_get_used_size(ctx->decode_buf) == 0) {
 			/* we can use the buffer directly without copying */
@@ -272,6 +273,7 @@
 {
 	const unsigned char *data;
 	buffer_t *decodebuf;
+	pool_t pool;
 	size_t data_size, pos;
 	uoff_t old_limit;
 	ssize_t ret;
@@ -292,8 +294,8 @@
 	if (ctx->translation == NULL)
 		ctx->translation = charset_to_utf8_begin("ascii", NULL);
 
-	ctx->decode_buf = buffer_create_static(data_stack_pool, 256);
-	ctx->match_buf = buffer_create_static_hard(data_stack_pool,
+	ctx->decode_buf = buffer_create_static(pool_datastack_create(), 256);
+	ctx->match_buf = buffer_create_static_hard(pool_datastack_create(),
 						   sizeof(size_t) *
 						   ctx->body_ctx->key_len);
 
@@ -312,15 +314,14 @@
 		pos = data_size;
 
 		t_push();
+		pool = pool_datastack_create();
 		if (ctx->content_qp) {
-			decodebuf = buffer_create_static_hard(data_stack_pool,
-							      data_size);
+			decodebuf = buffer_create_static_hard(pool, data_size);
 			quoted_printable_decode(data, data_size,
 						&data_size, decodebuf);
 		} else if (ctx->content_base64) {
 			size_t size = MAX_BASE64_DECODED_SIZE(data_size);
-			decodebuf = buffer_create_static_hard(data_stack_pool,
-							      size);
+			decodebuf = buffer_create_static_hard(pool, size);
 
 			if (base64_decode(data, data_size,
 					  &data_size, decodebuf) < 0) {
@@ -330,8 +331,8 @@
 				break;
 			}
 		} else {
-			decodebuf = buffer_create_const_data(data_stack_pool,
-							     data, data_size);
+			decodebuf = buffer_create_const_data(pool, data,
+							     data_size);
 		}
 
 		ret = message_search_body_block(ctx, decodebuf);
--- a/src/lib-mail/message-header-decode.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-mail/message-header-decode.c	Sun Sep 21 19:21:36 2003 +0300
@@ -64,7 +64,8 @@
 		return TRUE;
 	}
 
-	decodebuf = buffer_create_static_hard(data_stack_pool, text_size);
+	decodebuf = buffer_create_static_hard(pool_datastack_create(),
+					      text_size);
 
 	if (*encoding == 'Q')
 		quoted_printable_decode(text, text_size, NULL, decodebuf);
--- a/src/lib-storage/index/index-mail-headers.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-storage/index/index-mail-headers.c	Sun Sep 21 19:21:36 2003 +0300
@@ -120,7 +120,8 @@
 	int i, already_sorted;
 
 	/* copy the wanted_headers array */
-	buffer = buffer_create_dynamic(data_stack_pool, 256, (size_t)-1);
+	buffer = buffer_create_dynamic(pool_datastack_create(),
+				       256, (size_t)-1);
 	already_sorted = TRUE;
 	for (i = 0; arr[i] != NULL; i++) {
 		if (i > 0 && already_sorted &&
@@ -203,7 +204,8 @@
 	data = buffer_get_modifyable_data(mail->data.headers, &size);
 	size /= sizeof(struct cached_header *);
 
-	buffer = buffer_create_dynamic(data_stack_pool, 128, (size_t)-1);
+	buffer = buffer_create_dynamic(pool_datastack_create(),
+				       128, (size_t)-1);
 	for (i = 0; i < size; i++)
 		buffer_append(buffer, &data[i]->name, sizeof(const char *));
 	buffer_append(buffer, &null, sizeof(const char *));
@@ -423,7 +425,7 @@
 	t_push();
 	if (idx < data->header_data_cached) {
 		/* it's already in header_data. */
-		istream = i_stream_create_from_data(data_stack_pool,
+		istream = i_stream_create_from_data(pool_datastack_create(),
 						    str_data(data->header_data),
 						    str_len(data->header_data));
 		/* we might be parsing a bit more.. */
@@ -440,7 +442,7 @@
 		}
 
 		data->header_data_cached_partial = TRUE;
-		istream = i_stream_create_from_data(data_stack_pool,
+		istream = i_stream_create_from_data(pool_datastack_create(),
 						    str, strlen(str));
 	}
 
--- a/src/lib-storage/index/index-mail.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-storage/index/index-mail.c	Sun Sep 21 19:21:36 2003 +0300
@@ -407,7 +407,7 @@
 
 	if (index_mail_cache_can_add(mail, MAIL_CACHE_MESSAGEPART)) {
 		t_push();
-		buffer = buffer_create_dynamic(data_stack_pool,
+		buffer = buffer_create_dynamic(pool_datastack_create(),
 					       1024, (size_t)-1);
 		message_part_serialize(mail->data.parts, buffer);
 
--- a/src/lib-storage/index/index-search.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-storage/index/index-search.c	Sun Sep 21 19:21:36 2003 +0300
@@ -423,7 +423,7 @@
 			struct message_address *addr;
 			string_t *str;
 
-			addr = message_address_parse(data_stack_pool,
+			addr = message_address_parse(pool_datastack_create(),
 						     ctx->hdr->full_value,
 						     ctx->hdr->full_value_len,
 						     0);
--- a/src/lib-storage/index/maildir/maildir-save.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-storage/index/maildir/maildir-save.c	Sun Sep 21 19:21:36 2003 +0300
@@ -46,7 +46,7 @@
 	fname++;
 
 	t_push();
-	output = o_stream_create_file(fd, data_stack_pool, 4096, FALSE);
+	output = o_stream_create_file(fd, pool_datastack_create(), 4096, FALSE);
 	o_stream_set_blocking(output, 60000, NULL, NULL);
 
 	if (!mail_storage_save(ibox->box.storage, path, input, output,
--- a/src/lib-storage/mail-search.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib-storage/mail-search.c	Sun Sep 21 19:21:36 2003 +0300
@@ -151,7 +151,8 @@
 
 	*have_headers = *have_body = have_text = FALSE;
 
-	headers = buffer_create_dynamic(data_stack_pool, 128, (size_t)-1);
+	headers = buffer_create_dynamic(pool_datastack_create(),
+					128, (size_t)-1);
 	for (; args != NULL; args = args->next) {
 		search_arg_analyze(args, headers, have_headers,
 				   have_body, &have_text);
--- a/src/lib/Makefile.am	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/Makefile.am	Sun Sep 21 19:21:36 2003 +0300
@@ -35,6 +35,7 @@
 	mempool-alloconly.c \
 	mempool-datastack.c \
 	mempool-system.c \
+	mempool-unsafe-datastack.c \
 	mkdir-parents.c \
 	mmap-anon.c \
 	mmap-util.c \
--- a/src/lib/mempool-alloconly.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/mempool-alloconly.c	Sun Sep 21 19:21:36 2003 +0300
@@ -57,7 +57,8 @@
 
 	pool_alloconly_clear,
 
-	TRUE
+	TRUE,
+	FALSE
 };
 
 pool_t pool_alloconly_create(const char *name, size_t size)
--- a/src/lib/mempool-datastack.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/mempool-datastack.c	Sun Sep 21 19:21:36 2003 +0300
@@ -27,46 +27,88 @@
 
 	pool_data_stack_clear,
 
+	TRUE,
 	TRUE
 };
 
-pool_t data_stack_pool = &static_data_stack_pool;
+struct datastack_pool {
+	struct pool pool;
+	int refcount;
+
+	unsigned int data_stack_frame;
+};
+
+pool_t pool_datastack_create(void)
+{
+	struct datastack_pool *dpool;
+
+	dpool = t_new(struct datastack_pool, 1);
+	dpool->pool = static_data_stack_pool;
+	dpool->refcount = 1;
+	dpool->data_stack_frame = data_stack_frame;
+	return &dpool->pool;
+}
 
 static const char *pool_data_stack_get_name(pool_t pool __attr_unused__)
 {
 	return "data stack";
 }
 
-static void pool_data_stack_ref(pool_t pool __attr_unused__)
+static void pool_data_stack_ref(pool_t pool)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_ref(): stack frame changed");
+
+	dpool->refcount++;
 }
 
-static void pool_data_stack_unref(pool_t pool __attr_unused__)
+static void pool_data_stack_unref(pool_t pool)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_unref(): stack frame changed");
+
+	dpool->refcount--;
+	i_assert(dpool->refcount >= 0);
 }
 
 static void *pool_data_stack_malloc(pool_t pool __attr_unused__, size_t size)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
 	if (size == 0 || size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
 
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_malloc(): stack frame changed");
+
 	return t_malloc0(size);
 }
 
-static void pool_data_stack_free(pool_t pool __attr_unused__,
-				 void *mem __attr_unused__)
+static void pool_data_stack_free(pool_t pool, void *mem __attr_unused__)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
+
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_free(): stack frame changed");
 }
 
-static void *pool_data_stack_realloc(pool_t pool __attr_unused__, void *mem,
+static void *pool_data_stack_realloc(pool_t pool, void *mem,
 				     size_t old_size, size_t new_size)
 {
+	struct datastack_pool *dpool = (struct datastack_pool *) pool;
 	void *new_mem;
 
 	/* @UNSAFE */
 	if (new_size == 0 || new_size > SSIZE_T_MAX)
 		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
 
+	if (dpool->data_stack_frame != data_stack_frame)
+		i_panic("pool_data_stack_realloc(): stack frame changed");
+
 	if (mem == NULL)
 		return pool_data_stack_malloc(pool, new_size);
 
--- a/src/lib/mempool-system.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/mempool-system.c	Sun Sep 21 19:21:36 2003 +0300
@@ -29,7 +29,8 @@
 
 	pool_system_clear,
 
-        FALSE
+	FALSE,
+	FALSE
 };
 
 pool_t system_pool = &static_system_pool;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/mempool-unsafe-datastack.c	Sun Sep 21 19:21:36 2003 +0300
@@ -0,0 +1,91 @@
+/* Copyright (c) 2002-2003 Timo Sirainen */
+
+#include "lib.h"
+#include "mempool.h"
+
+#include <stdlib.h>
+
+static const char *pool_unsafe_data_stack_get_name(pool_t pool);
+static void pool_unsafe_data_stack_ref(pool_t pool);
+static void pool_unsafe_data_stack_unref(pool_t pool);
+static void *pool_unsafe_data_stack_malloc(pool_t pool, size_t size);
+static void pool_unsafe_data_stack_free(pool_t pool, void *mem);
+static void *pool_unsafe_data_stack_realloc(pool_t pool, void *mem,
+					    size_t old_size, size_t new_size);
+static void pool_unsafe_data_stack_clear(pool_t pool);
+
+static struct pool static_unsafe_data_stack_pool = {
+	pool_unsafe_data_stack_get_name,
+
+	pool_unsafe_data_stack_ref,
+	pool_unsafe_data_stack_unref,
+
+	pool_unsafe_data_stack_malloc,
+	pool_unsafe_data_stack_free,
+
+	pool_unsafe_data_stack_realloc,
+
+	pool_unsafe_data_stack_clear,
+
+	TRUE,
+	TRUE
+};
+
+pool_t unsafe_data_stack_pool = &static_unsafe_data_stack_pool;
+
+static const char *pool_unsafe_data_stack_get_name(pool_t pool __attr_unused__)
+{
+	return "unsafe data stack";
+}
+
+static void pool_unsafe_data_stack_ref(pool_t pool __attr_unused__)
+{
+}
+
+static void pool_unsafe_data_stack_unref(pool_t pool __attr_unused__)
+{
+}
+
+static void *pool_unsafe_data_stack_malloc(pool_t pool __attr_unused__,
+					   size_t size)
+{
+	if (size == 0 || size > SSIZE_T_MAX)
+		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", size);
+
+	return t_malloc0(size);
+}
+
+static void pool_unsafe_data_stack_free(pool_t pool __attr_unused__,
+					void *mem __attr_unused__)
+{
+}
+
+static void *pool_unsafe_data_stack_realloc(pool_t pool __attr_unused__,
+					    void *mem,
+					    size_t old_size, size_t new_size)
+{
+	void *new_mem;
+
+	/* @UNSAFE */
+	if (new_size == 0 || new_size > SSIZE_T_MAX)
+		i_panic("Trying to allocate %"PRIuSIZE_T" bytes", new_size);
+
+	if (mem == NULL)
+		return pool_unsafe_data_stack_malloc(pool, new_size);
+
+	if (old_size >= new_size)
+		return mem;
+
+	if (!t_try_realloc(mem, new_size)) {
+		new_mem = t_malloc(new_size);
+		memcpy(new_mem, mem, old_size);
+		mem = new_mem;
+	}
+
+	memset((char *) mem + old_size, 0, new_size - old_size);
+	return mem;
+}
+
+static void pool_unsafe_data_stack_clear(pool_t pool __attr_unused__)
+{
+}
--- a/src/lib/mempool.h	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/mempool.h	Sun Sep 21 19:21:36 2003 +0300
@@ -29,18 +29,25 @@
 	void (*clear)(pool_t pool);
 
 	unsigned int alloconly_pool:1;
+	unsigned int datastack_pool:1;
 };
 
 /* system_pool uses calloc() + realloc() + free() */
 extern pool_t system_pool;
 
-/* memory allocated from data_stack is valid only until next t_pop() call. */
-extern pool_t data_stack_pool;
+/* memory allocated from data_stack is valid only until next t_pop() call.
+   No checks are performed. */
+extern pool_t unsafe_data_stack_pool;
 
 /* Create a new alloc-only pool. Note that `size' specifies the initial
    malloc()ed block size, part of it is used internally. */
 pool_t pool_alloconly_create(const char *name, size_t size);
 
+/* When allocating memory from returned pool, the data stack frame must be
+   the same as it was when calling this function. pool_unref() also checks
+   that the stack frame is the same. This should make it quite safe to use. */
+pool_t pool_datastack_create(void);
+
 /* Pools should be used through these macros: */
 #define pool_get_name(pool) (pool)->get_name(pool)
 #define pool_ref(pool) (pool)->ref(pool)
--- a/src/lib/str.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/str.c	Sun Sep 21 19:21:36 2003 +0300
@@ -14,7 +14,7 @@
 
 string_t *t_str_new(size_t initial_size)
 {
-	return str_new(data_stack_pool, initial_size);
+	return str_new(pool_datastack_create(), initial_size);
 }
 
 void str_free(string_t *str)
--- a/src/lib/strfuncs.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/lib/strfuncs.c	Sun Sep 21 19:21:36 2003 +0300
@@ -197,7 +197,7 @@
 
 	i_assert(format != NULL);
 
-	if (pool != data_stack_pool)
+	if (!pool->datastack_pool)
 		t_push();
 
 	VA_COPY(args2, args);
@@ -210,7 +210,7 @@
 #else
 	vsprintf(ret, format, args2);
 #endif
-	if (pool != data_stack_pool)
+	if (!pool->datastack_pool)
 		t_pop();
 	return ret;
 }
@@ -277,27 +277,27 @@
 
 const char *t_strdup(const char *str)
 {
-	return p_strdup(data_stack_pool, str);
+	return p_strdup(unsafe_data_stack_pool, str);
 }
 
 char *t_strdup_noconst(const char *str)
 {
-	return p_strdup(data_stack_pool, str);
+	return p_strdup(unsafe_data_stack_pool, str);
 }
 
 const char *t_strdup_empty(const char *str)
 {
-	return p_strdup_empty(data_stack_pool, str);
+	return p_strdup_empty(unsafe_data_stack_pool, str);
 }
 
 const char *t_strdup_until(const void *start, const void *end)
 {
-	return p_strdup_until(data_stack_pool, start, end);
+	return p_strdup_until(unsafe_data_stack_pool, start, end);
 }
 
 const char *t_strndup(const void *str, size_t max_chars)
 {
-	return p_strndup(data_stack_pool, str, max_chars);
+	return p_strndup(unsafe_data_stack_pool, str, max_chars);
 }
 
 const char *t_strdup_printf(const char *format, ...)
@@ -306,7 +306,7 @@
 	const char *ret;
 
 	va_start(args, format);
-	ret = p_strdup_vprintf(data_stack_pool, format, args);
+	ret = p_strdup_vprintf(unsafe_data_stack_pool, format, args);
 	va_end(args);
 
 	return ret;
@@ -314,7 +314,7 @@
 
 const char *t_strdup_vprintf(const char *format, va_list args)
 {
-	return p_strdup_vprintf(data_stack_pool, format, args);
+	return p_strdup_vprintf(unsafe_data_stack_pool, format, args);
 }
 
 const char *t_strconcat(const char *str1, ...)
--- a/src/pop3-login/client-authenticate.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/pop3-login/client-authenticate.c	Sun Sep 21 19:21:36 2003 +0300
@@ -111,7 +111,8 @@
 
 	t_push();
 
-	buf = buffer_create_dynamic(data_stack_pool, size*2, (size_t)-1);
+	buf = buffer_create_dynamic(pool_datastack_create(),
+				    size*2, (size_t)-1);
 	buffer_append(buf, "+ ", 2);
 	base64_encode(data, size, buf);
 	buffer_append(buf, "\r\n", 2);
@@ -250,7 +251,7 @@
 	}
 
 	linelen = strlen(line);
-	buf = buffer_create_static_hard(data_stack_pool, linelen);
+	buf = buffer_create_static_hard(pool_datastack_create(), linelen);
 
 	if (base64_decode((const unsigned char *) line, linelen,
 			  NULL, buf) <= 0) {
--- a/src/pop3-login/client.c	Sun Sep 21 19:14:38 2003 +0300
+++ b/src/pop3-login/client.c	Sun Sep 21 19:21:36 2003 +0300
@@ -217,7 +217,7 @@
 	size_t i, count;
 
 	/* find the oldest clients and put them to destroy-buffer */
-	destroy_buf = buffer_create_static_hard(data_stack_pool,
+	destroy_buf = buffer_create_static_hard(pool_datastack_create(),
 						sizeof(struct pop3_client *) *
 						CLIENT_DESTROY_OLDEST_COUNT);
 	hash_foreach(clients, client_hash_destroy_oldest, destroy_buf);