]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
Renamed buffer_*_space() to buffer_*_space_unsafe() and added several
authorTimo Sirainen <tss@iki.fi>
Thu, 15 May 2003 19:22:21 +0000 (22:22 +0300)
committerTimo Sirainen <tss@iki.fi>
Thu, 15 May 2003 19:22:21 +0000 (22:22 +0300)
warnings about using them. Fixed their usage in a few places in sources
where they could have produced invalid results (no buffer overflows,
luckily).

--HG--
branch : HEAD

12 files changed:
src/auth/master-connection.c
src/imap/commands.c
src/imap/imap-sort.c
src/lib-charset/charset-iconv.c
src/lib-charset/charset-utf8.c
src/lib-index/mail-index-update.c
src/lib-index/mail-modifylog.c
src/lib-index/mbox/mbox-index.c
src/lib-mail/message-part-serialize.c
src/lib/buffer.c
src/lib/buffer.h
src/lib/str.c

index f0eff3d3f8695e41ce93d975e2d9691169e8bf0e..a22ef3f58397dc000def5f591ac599d4e955e9bf 100644 (file)
@@ -37,36 +37,42 @@ static size_t reply_add(buffer_t *buf, const char *str)
 static struct auth_master_reply *
 fill_reply(const struct user_data *user, size_t *reply_size)
 {
-       struct auth_master_reply *reply;
+       struct auth_master_reply reply, *reply_p;
        buffer_t *buf;
        char *p;
 
        buf = buffer_create_dynamic(data_stack_pool,
-                                   sizeof(*reply) + 256, (size_t)-1);
-       reply = buffer_append_space(buf, sizeof(*reply));
+                                   sizeof(reply) + 256, (size_t)-1);
+       memset(&reply, 0, sizeof(reply));
+       buffer_append(buf, &reply, sizeof(reply));
 
-       reply->success = TRUE;
+       reply.success = TRUE;
 
-       reply->uid = user->uid;
-       reply->gid = user->gid;
+       reply.uid = user->uid;
+       reply.gid = user->gid;
 
-       reply->system_user_idx = reply_add(buf, user->system_user);
-       reply->virtual_user_idx = reply_add(buf, user->virtual_user);
-       reply->mail_idx = reply_add(buf, user->mail);
+       reply.system_user_idx = reply_add(buf, user->system_user);
+       reply.virtual_user_idx = reply_add(buf, user->virtual_user);
+       reply.mail_idx = reply_add(buf, user->mail);
 
        p = strstr(user->home, "/./");
        if (p == NULL) {
-               reply->home_idx = reply_add(buf, user->home);
-               reply->chroot_idx = reply_add(buf, NULL);
+               reply.home_idx = reply_add(buf, user->home);
+               reply.chroot_idx = reply_add(buf, NULL);
        } else {
                /* wu-ftpd like <chroot>/./<home> */
-               reply->chroot_idx = reply_add(buf, t_strdup_until(user->home, p));
-               reply->home_idx = reply_add(buf, p + 3);
+               reply.chroot_idx =
+                       reply_add(buf, t_strdup_until(user->home, p));
+               reply.home_idx = reply_add(buf, p + 3);
        }
 
        *reply_size = buffer_get_used_size(buf);
-       reply->data_size = *reply_size - sizeof(*reply);
-       return reply;
+       reply.data_size = *reply_size - sizeof(reply);
+
+       reply_p = buffer_get_space_unsafe(buf, 0, sizeof(reply));
+       *reply_p = reply;
+
+       return reply_p;
 }
 
 static void send_reply(struct auth_master_reply *reply, size_t reply_size,
index 31df3dc936f3c3d348784fad7fafc7fbb1a280b6..164e99df31bd088b63d5cf57e62ee80da3e925d4 100644 (file)
@@ -57,11 +57,11 @@ static int cmdbuf_unsorted;
 
 void command_register(const char *name, command_func_t *func)
 {
-       struct command *cmd;
+       struct command cmd;
 
-       cmd = buffer_append_space(cmdbuf, sizeof(*cmd));
-       cmd->name = name;
-       cmd->func = func;
+       cmd.name = name;
+       cmd.func = func;
+       buffer_append(cmdbuf, &cmd, sizeof(cmd));
 
        cmdbuf_unsorted = TRUE;
 }
index 3942d2deb9632b2f6aa35fffe9eadb5965a0621e..74b3b5d9f99e564824eba3d6da5beca4743e0c96 100644 (file)
@@ -374,7 +374,8 @@ static void mail_sort_input(struct sort_context *ctx, struct mail *mail)
        if (ctx->common_mask != 0)
                mail_sort_check_flush(ctx, mail);
 
-       buf = buffer_append_space(ctx->sort_buffer, ctx->sort_element_size);
+       buf = buffer_append_space_unsafe(ctx->sort_buffer,
+                                        ctx->sort_element_size);
        id = ctx->id_is_uid ? mail->uid : mail->seq;
        memcpy(buf, &id, sizeof(id)); pos = sizeof(id);
 
index dab7c8b1603d34277a30838d20b63cf2cb8ce793..ed2c039ee0456072d232b8dbaa41308c04199129 100644 (file)
@@ -85,7 +85,7 @@ charset_to_ucase_utf8(struct charset_translation *t,
        size = destleft;
        srcleft = *src_size;
        ic_srcbuf = (ICONV_CONST char *) src;
-       ic_destbuf = buffer_append_space(dest, destleft);
+       ic_destbuf = buffer_append_space_unsafe(dest, destleft);
 
        if (iconv(t->cd, &ic_srcbuf, &srcleft,
                  &ic_destbuf, &destleft) != (size_t)-1)
index 3dd6ed929808b14eef2eda065dc93b58168fe39f..99fdb16f48558fef631d80001e97e2a5bdcbf099 100644 (file)
@@ -12,7 +12,7 @@ void _charset_utf8_ucase(const unsigned char *src, size_t src_size,
        char *destbuf;
        size_t i;
 
-       destbuf = buffer_get_space(dest, destpos, src_size);
+       destbuf = buffer_get_space_unsafe(dest, destpos, src_size);
        for (i = 0; i < src_size; i++)
                destbuf[i] = i_toupper(src[i]); /* FIXME: utf8 */
 }
index 5fd4af2f2d02a376cf940eefa19ebcf8bfbc271b..0f493c66953b098f5473c7478ed70c0581b18d49 100644 (file)
@@ -130,13 +130,11 @@ static size_t get_max_align_size(size_t base, size_t extra, size_t *max_extra)
 static void *create_data_block(struct mail_index_update *update,
                               size_t data_size, size_t extra_size)
 {
-        struct mail_index_data_record_header *dest_hdr;
-        struct mail_index_data_record *rec, *destrec;
+        struct mail_index_data_record *rec, destrec;
        enum mail_data_field field;
        buffer_t *buf;
        const void *src;
-       size_t src_size;
-       size_t full_field_size;
+       size_t src_size, filler_size;
        int i;
 
        i_assert(data_size <= UINT_MAX);
@@ -144,16 +142,15 @@ static void *create_data_block(struct mail_index_update *update,
        buf = buffer_create_static_hard(update->pool, data_size);
 
        /* set header */
-       dest_hdr = buffer_append_space(buf, sizeof(*dest_hdr));
-       memcpy(dest_hdr, &update->data_hdr, sizeof(*dest_hdr));
-       dest_hdr->data_size = data_size;
+       update->data_hdr.data_size = data_size;
+       buffer_append(buf, &update->data_hdr, sizeof(update->data_hdr));
 
        /* set fields */
        rec = mail_index_data_lookup(update->index->data, update->rec, 0);
        for (i = 0, field = 1; field != DATA_FIELD_LAST; i++, field <<= 1) {
                if (update->fields[i] != NULL) {
                        /* value was modified - use it */
-                       full_field_size =
+                       destrec.full_field_size =
                                get_max_align_size(update->field_sizes[i],
                                                   update->field_extra_sizes[i],
                                                   &extra_size);
@@ -161,20 +158,24 @@ static void *create_data_block(struct mail_index_update *update,
                        src_size = update->field_sizes[i];
                } else if (rec != NULL && rec->field == field) {
                        /* use the old value */
-                       full_field_size = rec->full_field_size;
+                       destrec.full_field_size = rec->full_field_size;
                        src = rec->data;
                        src_size = rec->full_field_size;
                } else {
                        /* the field doesn't exist, jump to next */
                        continue;
                }
-               i_assert((full_field_size % INDEX_ALIGN_SIZE) == 0);
+               i_assert((destrec.full_field_size % INDEX_ALIGN_SIZE) == 0);
 
-               destrec = buffer_append_space(buf, SIZEOF_MAIL_INDEX_DATA +
-                                             full_field_size);
-               destrec->field = field;
-               destrec->full_field_size = full_field_size;
-               memcpy(destrec->data, src, src_size);
+               destrec.field = field;
+               buffer_append(buf, &destrec, SIZEOF_MAIL_INDEX_DATA);
+               buffer_append(buf, src, src_size);
+
+               filler_size = destrec.full_field_size - src_size;
+               if (filler_size != 0) {
+                       buffer_set_used_size(buf, buffer_get_used_size(buf) +
+                                            filler_size);
+               }
 
                if (rec != NULL && rec->field == field) {
                        rec = mail_index_data_next(update->index->data,
index 812764c99779257458a43f3ff23203925b8ac18f..b29aeee9f73fe2dc099b7aeb3864d0a95782cf78 100644 (file)
@@ -1061,7 +1061,7 @@ mail_modifylog_seq_get_expunges(struct mail_modify_log *log,
                                unsigned int *expunges_before)
 {
        struct modify_log_record *rec;
-       struct modify_log_expunge *expunge;
+       struct modify_log_expunge expunge, *expunges;
        buffer_t *buf;
        size_t count;
        unsigned int before, max_records;
@@ -1118,19 +1118,18 @@ mail_modifylog_seq_get_expunges(struct mail_modify_log *log,
                                return NULL;
                        }
 
-                       expunge = buffer_append_space(buf, sizeof(*expunge));
-
                        if (rec->seq1 < first_seq) {
                                /* partial initial match, update
                                   before-counter */
                                before += first_seq - rec->seq1;
-                               expunge->seq_count = rec->seq2 - first_seq + 1;
+                               expunge.seq_count = rec->seq2 - first_seq + 1;
                        } else {
-                               expunge->seq_count = rec->seq2 - rec->seq1 + 1;
+                               expunge.seq_count = rec->seq2 - rec->seq1 + 1;
                        }
 
-                       expunge->uid1 = rec->uid1;
-                       expunge->uid2 = rec->uid2;
+                       expunge.uid1 = rec->uid1;
+                       expunge.uid2 = rec->uid2;
+                       buffer_append(buf, &expunge, sizeof(expunge));
                }
 
                if (rec->seq1 <= last_seq) {
@@ -1146,19 +1145,17 @@ mail_modifylog_seq_get_expunges(struct mail_modify_log *log,
        }
 
        /* terminate the array */
-       expunge = buffer_append_space(buf, sizeof(*expunge));
-       memset(expunge, 0, sizeof(*expunge));
+       buffer_set_used_size(buf, buffer_get_used_size(buf) + sizeof(expunge));
 
        /* extract the array from buffer */
-       count = buffer_get_used_size(buf)/sizeof(struct modify_log_expunge);
-       expunge = buffer_free_without_data(buf);
+       count = buffer_get_used_size(buf) / sizeof(expunge);
+       expunges = buffer_free_without_data(buf);
 
        /* sort the UID array, not including the terminating 0 */
-       qsort(expunge, count-1, sizeof(struct modify_log_expunge),
-             compare_expunge);
+       qsort(expunges, count-1, sizeof(expunge), compare_expunge);
 
        *expunges_before = before;
-       return expunge;
+       return expunges;
 }
 
 const struct modify_log_expunge *
@@ -1170,7 +1167,7 @@ mail_modifylog_uid_get_expunges(struct mail_modify_log *log,
        /* pretty much copy&pasted from sequence code above ..
           kind of annoying */
        struct modify_log_record *rec;
-       struct modify_log_expunge *expunge;
+       struct modify_log_expunge expunge, *expunges;
        buffer_t *buf;
        size_t count;
        unsigned int before, max_records;
@@ -1227,28 +1224,25 @@ mail_modifylog_uid_get_expunges(struct mail_modify_log *log,
                                return NULL;
                        }
 
-                       expunge = buffer_append_space(buf, sizeof(*expunge));
-
-                       expunge->uid1 = rec->uid1;
-                       expunge->uid2 = rec->uid2;
-                       expunge->seq_count = rec->seq2 -rec->seq1 + 1;
+                       expunge.uid1 = rec->uid1;
+                       expunge.uid2 = rec->uid2;
+                       expunge.seq_count = rec->seq2 -rec->seq1 + 1;
+                       buffer_append(buf, &expunge, sizeof(expunge));
                }
        }
 
        /* terminate the array */
-       expunge = buffer_append_space(buf, sizeof(*expunge));
-       memset(expunge, 0, sizeof(*expunge));
+       buffer_set_used_size(buf, buffer_get_used_size(buf) + sizeof(expunge));
 
        /* extract the array from buffer */
-       count = buffer_get_used_size(buf) / sizeof(struct modify_log_expunge);
-       expunge = buffer_free_without_data(buf);
+       count = buffer_get_used_size(buf) / sizeof(expunge);
+       expunges = buffer_free_without_data(buf);
 
        /* sort the UID array, not including the terminating 0 */
-       qsort(expunge, count-1, sizeof(struct modify_log_expunge),
-             compare_expunge);
+       qsort(expunges, count-1, sizeof(expunge), compare_expunge);
 
        *expunges_before = before;
-       return expunge;
+       return expunges;
 }
 
 static unsigned int
index 9ca6db9eacce4be0b373306bebf00c155ab497d7..0184a68eee62e46e73631b5218cff092c4d5451e 100644 (file)
@@ -197,7 +197,7 @@ mbox_get_keyword_flags(const unsigned char *value, size_t len,
 static void mbox_parse_imapbase(const unsigned char *value, size_t len,
                                struct mbox_header_context *ctx)
 {
-       const char **flag, *str;
+       const char *flag, *str;
        char *end;
        buffer_t *buf;
        size_t pos, start;
@@ -223,15 +223,15 @@ 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,
-                                   MAIL_CUSTOM_FLAGS_COUNT, MAX_CUSTOM_FLAGS);
+                                   MAIL_CUSTOM_FLAGS_COUNT *
+                                   sizeof(const char *),
+                                   MAX_CUSTOM_FLAGS * sizeof(const char *));
        for (start = pos; ; pos++) {
                if (pos == len || value[pos] == ' ' || value[pos] == '\t') {
                        if (start != pos) {
-                               flag = buffer_append_space(buf, sizeof(*flag));
-                               if (flag == NULL)
+                               flag = t_strdup_until(value+start, value+pos);
+                               if (buffer_append(buf, flag, sizeof(flag)) == 0)
                                        break;
-
-                               *flag = t_strdup_until(value+start, value+pos);
                        }
                        start = pos+1;
 
@@ -242,9 +242,8 @@ static void mbox_parse_imapbase(const unsigned char *value, size_t len,
 
        flags = MAIL_CUSTOM_FLAGS_MASK;
        count = buffer_get_used_size(buf) / sizeof(const char *);
-       flag = buffer_free_without_data(buf);
        ret = mail_custom_flags_fix_list(ctx->index->custom_flags, &flags,
-                                        flag, count);
+                                        buffer_free_without_data(buf), count);
 
        t_pop();
 }
index 17e01da66762d21bef3cf2bbab389cfcba269044..31be7982056d8e85fa959c1a874aa0a7f1a06e43 100644 (file)
@@ -46,29 +46,39 @@ struct deserialize_context {
 static unsigned int
 _message_part_serialize(struct message_part *part, buffer_t *dest)
 {
-       struct serialized_message_part *spart;
-       unsigned int count = 0;
+       struct serialized_message_part spart, *spart_p;
+       unsigned int count, children_count;
+       size_t pos;
 
+       count = 0;
        while (part != NULL) {
                /* create serialized part */
-               spart = buffer_append_space(dest, sizeof(*spart));
-               memset(spart, 0, sizeof(*spart));
+               memset(&spart, 0, sizeof(spart));
 
-               spart->physical_pos = part->physical_pos;
+               spart.physical_pos = part->physical_pos;
 
-               spart->header_physical_size = part->header_size.physical_size;
-               spart->header_virtual_size = part->header_size.virtual_size;
-               spart->header_lines = part->header_size.lines;
+               spart.header_physical_size = part->header_size.physical_size;
+               spart.header_virtual_size = part->header_size.virtual_size;
+               spart.header_lines = part->header_size.lines;
 
-               spart->body_physical_size = part->body_size.physical_size;
-               spart->body_virtual_size = part->body_size.virtual_size;
-               spart->body_lines = part->body_size.lines;
+               spart.body_physical_size = part->body_size.physical_size;
+               spart.body_virtual_size = part->body_size.virtual_size;
+               spart.body_lines = part->body_size.lines;
 
-               spart->flags = part->flags;
+               spart.flags = part->flags;
 
+               buffer_append(dest, &spart, sizeof(spart));
                if (part->children != NULL) {
-                       spart->children_count =
+                       pos = buffer_get_used_size(dest) - sizeof(spart);
+                       children_count =
                                _message_part_serialize(part->children, dest);
+
+                       /* note that we can't just save the pointer to
+                          our appended spart since it may change after
+                          child-appends have realloc()ed buffer memory. */
+                       spart_p = buffer_get_space_unsafe(dest, pos,
+                                                         sizeof(spart));
+                       spart_p->children_count = children_count;
                }
 
                count++;
index 2f3b8c48c48131538870446dae583c8f7a371a11..0e21384374b4f606021c051af3481b0fe4900503 100644 (file)
@@ -311,7 +311,7 @@ size_t buffer_append_buf(buffer_t *dest, const buffer_t *src,
                           src, src_pos, copy_size);
 }
 
-void *buffer_get_space(buffer_t *buf, size_t pos, size_t size)
+void *buffer_get_space_unsafe(buffer_t *buf, size_t pos, size_t size)
 {
        if (!buffer_check_write(buf, &pos, &size, FALSE))
                return NULL;
@@ -319,9 +319,9 @@ void *buffer_get_space(buffer_t *buf, size_t pos, size_t size)
        return buf->w_buffer + pos;
 }
 
-void *buffer_append_space(buffer_t *buf, size_t size)
+void *buffer_append_space_unsafe(buffer_t *buf, size_t size)
 {
-       return buffer_get_space(buf, buf->used - buf->start_pos, size);
+       return buffer_get_space_unsafe(buf, buf->used - buf->start_pos, size);
 }
 
 const void *buffer_get_data(const buffer_t *buf, size_t *used_size)
index 4a9437af9ec62472084d3b85999745c363785228..72b3f0d23c2ae30feac7ed308a94aab703bf0325 100644 (file)
@@ -1,6 +1,11 @@
 #ifndef __BUFFER_H
 #define __BUFFER_H
 
+/* WARNING: Be careful with functions that return pointers to data.
+   With dynamic buffers they are valid only as long as buffer is not
+   realloc()ed. You shouldn't rely on it being valid if you have modified
+   buffer in any way. */
+
 /* Create a static sized buffer. Writes past this size will simply not
    succeed. */
 buffer_t *buffer_create_static(pool_t pool, size_t size);
@@ -47,17 +52,19 @@ size_t buffer_append_buf(buffer_t *dest, const buffer_t *src,
                         size_t src_pos, size_t copy_size);
 
 /* Returns pointer to specified position in buffer, or NULL if there's not
-   enough space. */
-void *buffer_get_space(buffer_t *buf, size_t pos, size_t size);
+   enough space. WARNING: The returned address may become invalid if you add
+   more data to buffer. */
+void *buffer_get_space_unsafe(buffer_t *buf, size_t pos, size_t size);
 /* Increase the buffer usage by given size, and return a pointer to beginning
    of it, or NULL if there's not enough space in buffer. */
-void *buffer_append_space(buffer_t *buf, size_t size);
+void *buffer_append_space_unsafe(buffer_t *buf, size_t size);
 
 /* Returns pointer to beginning of buffer data. Current used size of buffer is
    stored in used_size if it's non-NULL. */
 const void *buffer_get_data(const buffer_t *buf, size_t *used_size);
 /* Like buffer_get_data(), but don't return it as const. Returns NULL if the
-   buffer is non-modifyable. */
+   buffer is non-modifyable. WARNING: The returned address may become invalid
+   if you add more data to buffer. */
 void *buffer_get_modifyable_data(const buffer_t *buf, size_t *used_size);
 
 /* Set the "used size" of buffer, ie. 0 would set the buffer empty.
index 89ac0967bae9e852cfeb1f2d5198418f4a8ce049..9853cfe7175c706e75d1b1f8ca4452029d1a88fc 100644 (file)
@@ -143,7 +143,7 @@ void str_vprintfa(string_t *str, const char *fmt, va_list args)
        fmt = printf_string_fix_format(fmt);
        append_len = printf_string_upper_bound(fmt, args);
 
-       buf = buffer_append_space(str, append_len);
+       buf = buffer_append_space_unsafe(str, append_len);
 
 #ifdef HAVE_VSNPRINTF
        ret = vsnprintf(buf, append_len, fmt, args2);