/* Copyright (c) 2002-2018 Dovecot authors, see the included COPYING file */
#include "lib.h"
#include "buffer.h"
#include "message-parser.h"
#include "message-part-serialize.h"
/*
root part
root's first children
children's first children
...
root's next children
...
part
unsigned int flags
(not root part)
uoff_t physical_pos
uoff_t header_physical_size
uoff_t header_virtual_size
uoff_t body_physical_size
uoff_t body_virtual_size
(flags & (MESSAGE_PART_FLAG_TEXT | MESSAGE_PART_FLAG_MESSAGE_RFC822))
unsigned int body_lines
(flags & (MESSAGE_PART_FLAG_MULTIPART | MESSAGE_PART_FLAG_MESSAGE_RFC822))
unsigned int children_count
*/
#define MINIMUM_SERIALIZED_SIZE \
(sizeof(unsigned int) + sizeof(uoff_t) * 4)
struct deserialize_context {
const char *error;
};
unsigned int *children_count_r)
{
count = 0;
/* create serialized part */
if (root)
else {
sizeof(part->physical_pos));
}
MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0) {
}
MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0) {
children_count = 0;
sizeof(children_count));
sizeof(children_count));
}
} else {
}
count++;
}
}
{
unsigned int children_count;
}
{
return FALSE;
}
return TRUE;
}
static bool ATTR_NULL(2)
struct message_part *parent,
unsigned int siblings,
struct message_part **part_r)
{
unsigned int children_count;
first_part = NULL;
while (siblings > 0) {
siblings--;
p->children_count++;
return FALSE;
if (root)
else {
sizeof(part->physical_pos)))
return FALSE;
}
return FALSE;
}
return FALSE;
return FALSE;
return FALSE;
}
return FALSE;
return FALSE;
MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0) {
return FALSE;
}
return FALSE;
}
MESSAGE_PART_FLAG_MESSAGE_RFC822)) != 0) {
sizeof(children_count)))
return FALSE;
} else {
children_count = 0;
}
/* Only one child is possible */
if (children_count == 0) {
return FALSE;
}
if (children_count != 1) {
"has multiple children";
return FALSE;
}
}
if (children_count > 0) {
/* our children must be after our physical_pos+header
and the last child must be within our size. */
return FALSE;
"child part location exceeds our size";
return FALSE;
}
}
if (first_part == NULL)
first_part = part;
}
*part_r = first_part;
return TRUE;
}
struct message_part *
const char **error_r)
{
return NULL;
}
*error_r = "Too much data";
return NULL;
}
return part;
}