]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
data_stack_pool split into two: unsafe_data_stack_pool which works like
authorTimo Sirainen <tss@iki.fi>
Sun, 21 Sep 2003 16:21:36 +0000 (19:21 +0300)
committerTimo Sirainen <tss@iki.fi>
Sun, 21 Sep 2003 16:21:36 +0000 (19:21 +0300)
before, and a new one which verifies that stack frame stays the same
whenever the pool is accessed.

--HG--
branch : HEAD

39 files changed:
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 [new file with mode: 0644]
src/lib/mempool.h
src/lib/str.c
src/lib/strfuncs.c
src/pop3-login/client-authenticate.c
src/pop3-login/client.c

index f5f99862f689eef086c2612d39dcdf2336144ad3..93359cc9fa3be115012f647daa36335de3a0dbec 100644 (file)
@@ -42,7 +42,7 @@ fill_reply(const struct user_data *user, size_t *reply_size)
        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));
index f48b01e7ee440dab5df3b7cc668924825d54ef13..002356fb9cb4ab3a9254c36d7ce70825c6c03c2a 100644 (file)
@@ -76,7 +76,7 @@ static string_t *get_digest_challenge(struct digest_auth_request *auth)
        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 @@ static int verify_credentials(struct digest_auth_request *auth,
        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;
index 1daf49fe2529381f4e24f4e85820ee9716465a87..cc38e54da2931a300d2335fa98d5251adb008a15 100644 (file)
@@ -35,7 +35,8 @@ mech_plain_auth_continue(struct auth_request *auth_request,
                        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;
                        }
                }
index 9b3d35c5af2c5ff0ff20bf8e462565b53c3dc920..5a8a485a9f90d8c6afa5266cfd18195d5cc6a49b 100644 (file)
@@ -147,7 +147,7 @@ void *mech_auth_success(struct auth_client_request_reply *reply,
 {
        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);
index 01d008b3f177160cd1f6f38f56de4027b6c0cee4..67991df072e933a0a7b7f8ee115e424f4b02d8b7 100644 (file)
@@ -243,7 +243,8 @@ pam_verify_plain_child(const char *service, const char *user,
                }
        }
 
-       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) {
index 73838736c6190ff9f5c98527291378186b444335..f285ac9acf5468c8ebc6099096649d86793e355e 100644 (file)
@@ -108,7 +108,8 @@ static void client_send_auth_data(struct imap_client *client,
 
        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 @@ static void client_auth_input(void *context)
        }
 
        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) {
index 838d30a91c9d716f9337101863f01d45a215c8a9..dc2052cb446b3b0cdad7fb7059ed4e6ff61a74ff 100644 (file)
@@ -322,7 +322,7 @@ static void client_destroy_oldest(void)
        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);
index 83990b38f68e1e6d91c216093ee8c267d59136d5..8670bfdc8b966c6dcde000d1518311404a4c8ad8 100644 (file)
@@ -84,7 +84,7 @@ int cmd_append(struct client *client)
                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);
 
index 937e6378b0a842a72d4bc2fd741b53fc0aad0990..67c9f6e6cf025076878fe691d41701ce57bfe68f 100644 (file)
@@ -37,7 +37,7 @@ get_sort_program(struct client *client, struct imap_arg *args)
                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);
 
index 4a4e0ce464f1610f34ca920af4ca20d54162e21c..dc01c544aefeb306831061c8d73dcd01e0bee529 100644 (file)
@@ -339,7 +339,7 @@ static int fetch_header_from(struct imap_fetch_context *ctx,
                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))
index 4f80acb73832768611b6cb236600b1b5e6f5de2d..5d2655c3050bc5ebaf65c208bd57016c3462e88a 100644 (file)
@@ -365,7 +365,7 @@ int imap_fetch(struct client *client,
           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;
index 98ffa51fbb2dfddef20a442118fa82955f031134..9f04ba54a7ee17652a5be3232ea9fc36d8629bd0 100644 (file)
@@ -203,7 +203,8 @@ int imap_sort(struct client *client, const char *charset,
        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 @@ static const char *get_first_mailbox(struct mail *mail, const char *field)
        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;
index 8bda11602456e5a5ac93664948f0634b12a7d845..57b8a7f51f6c30b60c60cbdb3d8858d5ace40d4b 100644 (file)
@@ -298,7 +298,8 @@ static const char *get_msgid(const char **msgid_p)
                        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 @@ static void add_base_subject(struct thread_context *ctx,
        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;
index 99fdb16f48558fef631d80001e97e2a5bdcbf099..702bcd4789fc37e52b538b44a82c6a9ca93c1fdf 100644 (file)
@@ -22,7 +22,7 @@ const char *_charset_utf8_ucase_strdup(const unsigned char *data, size_t size,
 {
        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);
index 55a00ace2e42c496c1220826cb5d950388e764b9..257f90092aa3f290d03e37355246c710720f24e0 100644 (file)
@@ -658,7 +658,8 @@ const char *imap_body_parse_from_bodystructure(const char *bodystructure)
        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);
index fa7c2e9cf33ab64ec8f6bd9912c9f32cd023ff0b..80bf2d9637459a73f3b9864e294d076ddbac36a4 100644 (file)
@@ -380,7 +380,7 @@ int imap_envelope_parse(const char *envelope, enum imap_envelope_field field,
 
        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);
 
index 35a168e61203b66de5d6a19b2b650a40073a1fb7..b5626b9e568c094d07d79f8cf69c300a37585c7c 100644 (file)
@@ -91,8 +91,6 @@ char *imap_quote(pool_t pool, const unsigned char *value, size_t value_len)
        string_t *str;
        char *ret;
 
-       i_assert(pool != data_stack_pool);
-
        if (value == NULL)
                return "NIL";
 
index 41add6c32890359f7f95a09a941f5ec8f9b49f89..00c85d92e05c5c49a6e5a2a919c439c677a9479a 100644 (file)
@@ -540,7 +540,8 @@ mail_cache_compress_record(struct mail_cache *cache,
        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 @@ int mail_cache_set_header_fields(struct mail_cache_transaction_ctx *ctx,
 
        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);
index dec93093a7efa8ff7309943b935759edb9ca3990..57af13a44de55c3a362eba2087a4e9f1756218e5 100644 (file)
@@ -1109,7 +1109,8 @@ mail_modifylog_seq_get_expunges(struct mail_modify_log *log,
 
        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 @@ mail_modifylog_uid_get_expunges(struct mail_modify_log *log,
 
        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;
index 397f2280a249ca58024f84fe8551655834dde1af..016902043732a746fb7e179c97dd98b98c579c0a 100644 (file)
@@ -219,7 +219,7 @@ static void mbox_parse_imapbase(const unsigned char *value, size_t len,
        }
 
        /* 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 *));
index fc3c405dd434cf8d8ba520d728121bdd74b77424..23ec89d498208a275cec3e3313f74b13f2becb31 100644 (file)
@@ -506,11 +506,12 @@ static int fd_copy(struct mail_index *index, int in_fd, int out_fd,
 
        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);
index 6c37e295952fb6dcdda9a1f7f839ecfe3c67e768..4d9527c3412eb815a127833f07e3f8a51b190d83 100644 (file)
@@ -66,7 +66,7 @@ message_address_parse(pool_t pool, const unsigned char *data, size_t size,
        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 @@ message_address_parse(pool_t pool, const unsigned char *data, size_t size,
        if (ingroup)
                (void)new_address(pool, &next_addr);
 
-       if (pool != data_stack_pool)
+       if (!pool->datastack_pool)
                t_pop();
        message_tokenize_deinit(tok);
 
index 7c6f40bd6e9c3acd6d3c3197d6cd18ebfec344df..1e8294e0eb716dd7b3b38d1db15c8d65196a9a00 100644 (file)
@@ -107,7 +107,7 @@ static int message_search_header(struct part_search_context *ctx,
        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 @@ static int message_search_body_block(struct part_search_context *ctx,
         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 @@ static int message_search_body(struct part_search_context *ctx,
 {
        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 @@ static int message_search_body(struct part_search_context *ctx,
        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 @@ static int message_search_body(struct part_search_context *ctx,
                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 @@ static int message_search_body(struct part_search_context *ctx,
                                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);
index c7ab1a051c030c8ab82748d6a8be46b714fc1129..32fb6777a6818f7b2f5add0e7d99f7c318f83ec9 100644 (file)
@@ -64,7 +64,8 @@ message_header_decode_encoded(const unsigned char *data, size_t *size,
                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);
index 27f7f3bd9baea24f28aff88fb6c56896b38cf0a3..8f104e42de72d91ee40d7d5843e5e8c304e0cdb7 100644 (file)
@@ -120,7 +120,8 @@ static const char *const *sort_array(const char *const *arr)
        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 @@ static const char *const *cached_header_get_names(struct index_mail *mail)
        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 @@ static int parse_cached_headers(struct index_mail *mail, int idx)
        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 @@ static int parse_cached_headers(struct index_mail *mail, int idx)
                }
 
                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));
        }
 
index 38f51e196836f55bda04bfc7fac2de6c98939710..682a5f116e9896015003001d46628cd5c642cfcb 100644 (file)
@@ -407,7 +407,7 @@ static int index_mail_parse_body(struct index_mail *mail)
 
        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);
 
index d33752b6ef147d514c874392a74566a051169317..a9a012e4fa069085090e7a11c83a964adb7f73ee 100644 (file)
@@ -423,7 +423,7 @@ static void search_header_arg(struct mail_search_arg *arg, void *context)
                        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);
index 921b3548ed6f4141dda8de7f6105deb01857fed8..852fe718b0c6ebdfbf211cbc9bc0ba96e153d36e 100644 (file)
@@ -46,7 +46,7 @@ maildir_read_into_tmp(struct index_mailbox *ibox, const char *dir,
        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,
index b10e1904589b955f7de55c52ba8d95449d7f9c35..86d56d413f64c7b22556c02225223c2aecbd5edb 100644 (file)
@@ -151,7 +151,8 @@ mail_search_args_analyze(struct mail_search_arg *args,
 
        *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);
index f6307ad9a1e72970ae51a0b0922ac1d316410c38..83130539636266eecef016242c7326ccb2442418 100644 (file)
@@ -35,6 +35,7 @@ liblib_a_SOURCES = \
        mempool-alloconly.c \
        mempool-datastack.c \
        mempool-system.c \
+       mempool-unsafe-datastack.c \
        mkdir-parents.c \
        mmap-anon.c \
        mmap-util.c \
index 855eb3165265ccb19d750f2df1149f72ed734cc0..1505a3b6bb2e41dff8b2c60c1636a74d82d46f48 100644 (file)
@@ -57,7 +57,8 @@ static struct pool static_alloconly_pool = {
 
        pool_alloconly_clear,
 
-       TRUE
+       TRUE,
+       FALSE
 };
 
 pool_t pool_alloconly_create(const char *name, size_t size)
index b0ca301aaa674770171b60a586e567bee41641bd..54b1e3fd41031aec211dd904c8a17ca7bb1b1fd3 100644 (file)
@@ -27,46 +27,88 @@ static struct pool static_data_stack_pool = {
 
        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);
 
index e5284533145551598e2985439c929cead1c2a66c..3566c0a07ff716168f3047b7d68b173dfcc5c030 100644 (file)
@@ -29,7 +29,8 @@ static struct pool static_system_pool = {
 
        pool_system_clear,
 
-        FALSE
+       FALSE,
+       FALSE
 };
 
 pool_t system_pool = &static_system_pool;
diff --git a/src/lib/mempool-unsafe-datastack.c b/src/lib/mempool-unsafe-datastack.c
new file mode 100644 (file)
index 0000000..035bc6b
--- /dev/null
@@ -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__)
+{
+}
index 53c84bc33940bc5c329a9c9241bf3e91ab4fe1ad..03f0856ae88550079442705b6885d1e95d887ae7 100644 (file)
@@ -29,18 +29,25 @@ struct pool {
        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)
index a5e16ce51fb461d15d4500f70579c1d6c0eefc82..b5d6e9fb240688948651a8b425546c0114f78306 100644 (file)
@@ -14,7 +14,7 @@ string_t *str_new(pool_t pool, size_t initial_size)
 
 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)
index 357f93e01e1afb8bf09cd0c2f1931ce2805982fc..5d4140156f9831a440944c28f911ac6f16d22b33 100644 (file)
@@ -197,7 +197,7 @@ char *p_strdup_vprintf(pool_t pool, const char *format, va_list args)
 
        i_assert(format != NULL);
 
-       if (pool != data_stack_pool)
+       if (!pool->datastack_pool)
                t_push();
 
        VA_COPY(args2, args);
@@ -210,7 +210,7 @@ char *p_strdup_vprintf(pool_t pool, const char *format, va_list args)
 #else
        vsprintf(ret, format, args2);
 #endif
-       if (pool != data_stack_pool)
+       if (!pool->datastack_pool)
                t_pop();
        return ret;
 }
@@ -277,27 +277,27 @@ char *p_strconcat(pool_t pool, const char *str1, ...)
 
 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 *t_strdup_printf(const char *format, ...)
        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_printf(const char *format, ...)
 
 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, ...)
index dadebd158c5e0b185bf745b33055861726687c95..ca7f849a2e5524906301d75802693ced7ad9e44a 100644 (file)
@@ -111,7 +111,8 @@ static void client_send_auth_data(struct pop3_client *client,
 
        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 @@ static void client_auth_input(void *context)
        }
 
        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) {
index 5e7a8d8650737f81ab4faaeafe310d43b07bc79d..568babe19902b92ebc11d1e8177b1face646a74b 100644 (file)
@@ -217,7 +217,7 @@ static void client_destroy_oldest(void)
        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);