Mercurial > dovecot > original-hg > dovecot-1.2
view src/lib-mail/message-part-serialize.c @ 321:2b2dc11ea0f6 HEAD
message_part_serialize_update_header() didn't update positions for subparts
so they got broken with mbox when headers were updated.
author | Timo Sirainen <tss@iki.fi> |
---|---|
date | Thu, 26 Sep 2002 20:06:57 +0300 |
parents | 4223b9ed0c80 |
children | e34e14d758eb |
line wrap: on
line source
/* Copyright (C) 2002 Timo Sirainen */ #include "lib.h" #include "message-parser.h" #include "message-part-serialize.h" /* Serialized a series of SerializedMessageParts: root part root's first children children's first children ... root's next children ... */ /* struct is 8 byte aligned */ typedef struct { uoff_t physical_pos; uoff_t header_physical_size; uoff_t header_virtual_size; uoff_t body_physical_size; uoff_t body_virtual_size; unsigned int header_lines; unsigned int body_lines; unsigned int children_count; unsigned int flags; } SerializedMessagePart; static void message_part_serialize_part(MessagePart *part, unsigned int *children_count, SerializedMessagePart **spart_base, size_t *pos, size_t *size) { SerializedMessagePart *spart; size_t buf_size; while (part != NULL) { /* make sure we have space */ if (*pos == *size) { *size *= 2; buf_size = sizeof(SerializedMessagePart) * (*size); *spart_base = t_buffer_reget(*spart_base, buf_size); } /* create serialized part */ spart = (*spart_base) + (*pos); memset(spart, 0, sizeof(SerializedMessagePart)); 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->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->children_count = 0; spart->flags = part->flags; if (children_count != NULL) (*children_count)++; (*pos)++; if (part->children != NULL) { message_part_serialize_part(part->children, &spart->children_count, spart_base, pos, size); } part = part->next; } } const void *message_part_serialize(MessagePart *part, size_t *size) { SerializedMessagePart *spart_base; size_t pos, buf_size; buf_size = 32; spart_base = t_buffer_get(sizeof(SerializedMessagePart) * buf_size); pos = 0; message_part_serialize_part(part, NULL, &spart_base, &pos, &buf_size); *size = sizeof(SerializedMessagePart) * pos; t_buffer_alloc(*size); return spart_base; } static MessagePart * message_part_deserialize_part(Pool pool, MessagePart *parent, const SerializedMessagePart **spart_pos, size_t *count, unsigned int child_count) { const SerializedMessagePart *spart; MessagePart *part, *first_part, **next_part; unsigned int i; first_part = NULL; next_part = NULL; for (i = 0; i < child_count && *count > 0; i++) { spart = *spart_pos; (*spart_pos)++; (*count)--; part = p_new(pool, MessagePart, 1); part->physical_pos = spart->physical_pos; part->header_size.physical_size = spart->header_physical_size; part->header_size.virtual_size = spart->header_virtual_size; part->header_size.lines = spart->header_lines; part->body_size.physical_size = spart->body_physical_size; part->body_size.virtual_size = spart->body_virtual_size; part->body_size.lines = spart->body_lines; part->flags = spart->flags; part->parent = parent; part->children = message_part_deserialize_part(pool, part, spart_pos, count, spart->children_count); if (first_part == NULL) first_part = part; if (next_part != NULL) *next_part = part; next_part = &part->next; } return first_part; } MessagePart *message_part_deserialize(Pool pool, const void *data, size_t size) { const SerializedMessagePart *spart; size_t count; /* make sure it looks valid */ if (size == 0 || (size % sizeof(SerializedMessagePart)) != 0) return NULL; spart = data; count = size / sizeof(SerializedMessagePart); if (count > UINT_MAX) return NULL; return message_part_deserialize_part(pool, NULL, &spart, &count, (unsigned int)count); } int message_part_serialize_update_header(void *data, size_t size, MessageSize *hdr_size) { SerializedMessagePart *spart = data; uoff_t first_pos; off_t pos_diff; size_t i, count; /* make sure it looks valid */ if (size == 0 || (size % sizeof(SerializedMessagePart)) != 0) return FALSE; if (hdr_size->physical_size >= OFF_T_MAX || spart->physical_pos >= OFF_T_MAX || spart->header_physical_size >= OFF_T_MAX) return FALSE; first_pos = spart->physical_pos; pos_diff = (off_t)hdr_size->physical_size - spart->header_physical_size; spart->header_physical_size = hdr_size->physical_size; spart->header_virtual_size = hdr_size->virtual_size; spart->header_lines = hdr_size->lines; if (pos_diff != 0) { /* have to update all positions */ count = size / sizeof(SerializedMessagePart); for (i = 0; i < count; i++, spart++) { if (spart->physical_pos < first_pos || spart->physical_pos >= OFF_T_MAX) { /* invalid offset, might cause overflow */ return FALSE; } spart->physical_pos += pos_diff; } } return TRUE; } int message_part_deserialize_size(const void *data, size_t size, MessageSize *hdr_size, MessageSize *body_size) { const SerializedMessagePart *spart = data; /* make sure it looks valid */ if (size == 0 || (size % sizeof(SerializedMessagePart)) != 0) return FALSE; hdr_size->physical_size = spart->header_physical_size; hdr_size->virtual_size = spart->header_virtual_size; hdr_size->lines = spart->header_lines; body_size->physical_size = spart->body_physical_size; body_size->virtual_size = spart->body_virtual_size; body_size->lines = spart->body_lines; return TRUE; }