message-parser.c revision f854c63292b0074eb1d6396381d71696a8146e79
/* Copyright (C) 2002-2006 Timo Sirainen */
#include "lib.h"
#include "istream.h"
#include "strescape.h"
#include "message-content-parser.h"
#include "message-parser.h"
/* RFC-2046 requires boundaries are max. 70 chars + "--" prefix + "--" suffix.
We'll add a bit more just in case. */
struct message_boundary {
struct message_boundary *next;
struct message_part *part;
const char *boundary;
unsigned int epilogue_found:1;
};
struct message_parser_ctx {
const char *last_boundary;
struct message_boundary *boundaries;
char last_chr;
unsigned int want_count;
struct message_header_parser_ctx *hdr_parser_ctx;
struct message_block *block_r);
unsigned int part_seen_content_type:1;
};
struct message_block *block_r);
struct message_block *block_r);
struct message_block *block_r);
static struct message_boundary *
{
/* As MIME spec says: search from latest one to oldest one so that we
don't break if the same boundary is used in nested parts. Also the
full message line doesn't have to match the boundary, only the
beginning. */
while (boundaries != NULL) {
return boundaries;
}
return NULL;
}
struct message_block *block)
{
unsigned int missing_cr_count = 0;
size_t i;
if (data[i] <= '\n') {
if (data[i] == '\n') {
} else if (data[i] == '\0')
}
}
}
struct message_block *block_r)
{
int ret;
}
if (ret == -1)
return -1;
if (ret == 0) {
return 0;
}
}
return 1;
}
static struct message_part *
{
/* set child position */
part->physical_pos =
return part;
}
{
struct message_boundary *b;
ctx->boundaries = b;
}
{
}
static int
struct message_boundary **boundary_r)
{
size_t i;
*boundary_r = NULL;
if (size < 2) {
return -1;
return 0;
}
/* not a boundary, just skip this line */
return -1;
}
/* need to find the end of line */
for (i = 2; i < size; i++) {
if (data[i] == '\n')
break;
}
if (i == size && i < BOUNDARY_END_MAX_LEN &&
/* no LF found */
return 0;
}
data += 2;
size -= 2;
if (*boundary_r == NULL)
return -1;
(*boundary_r)->epilogue_found =
return 1;
}
struct message_block *block_r)
{
size_t i;
int ret;
return ret;
break;
}
return 1;
}
/* found the LF */
/* a new MIME part begins */
}
struct message_boundary *boundary,
{
struct message_part *part;
/* message ended unexpectedly */
return -1;
}
/* get back to parent MIME part, summing the child MIME part sizes
into parent's body sizes */
}
if (boundary->epilogue_found) {
/* this boundary isn't needed anymore */
else
}
/* forget about the boundaries we possibly skipped */
/* the boundary itself should already be in buffer. add that. */
(first_line ? 0 : 1));
/* [\n]--<boundary> */
return 1;
}
struct message_block *block_r)
{
const unsigned char *data;
size_t i, boundary_start;
int ret;
return ret;
/* handle boundary in first line of message. alternatively
it's an empty line. */
if (ret >= 0) {
if (ret == 0)
return 0;
}
}
/* skip to beginning of the next line. the first line was
handled already. */
if (data[i] == '\n') {
boundary_start = i;
i++;
break;
}
}
if (boundary_start != 0) {
/* we can skip the first lines. input buffer can't be
full anymore. */
}
&boundary);
if (ret >= 0) {
/* found / need more data */
if (ret == 0 && boundary_start == 0)
ctx->want_count += i;
break;
}
}
/* the boundary wasn't found from this data block,
we'll need more data. */
if (eof)
ret = -1;
else {
ret = 0;
}
}
if (ret >= 0) {
/* leave CR+LF + last line to buffer */
}
}
struct message_block *block_r)
{
int ret;
return ret;
return 1;
}
static void
{
const char *str;
return;
t_push();
}
t_pop();
}
static void
bool value_quoted, void *context)
{
char *boundary;
return;
if (value_quoted)
}
}
#define MUTEX_FLAGS \
struct message_block *block_r)
{
struct message_header_line *hdr;
int ret;
}
return ret;
;
/* it's MIME. Content-* headers are valid */
else {
}
}
return 1;
}
/* end of headers */
/* multipart type but no message boundary */
}
/* It's not MIME. Reset everything we found from
Content-Type. */
}
if (!ctx->part_seen_content_type ||
MESSAGE_PART_FLAG_MULTIPART_DIGEST) != 0) {
/* when there's no content-type specified and we're
content-type */
} else {
}
}
else
/* return empty block as end of headers */
return 1;
}
struct message_block *block_r)
{
TRUE);
}
struct message_parser_ctx *
{
struct message_parser_ctx *ctx;
return ctx;
}
{
return parts;
}
struct message_block *block_r)
{
int ret;
if (ret <= 0) {
if (ret == 0) {
return 0;
}
if (ret < 0) {
}
}
}
if (ret < 0) {
}
}
return ret;
}
struct message_size *hdr_size,
void *context)
{
struct message_block block;
int ret;
break;
}
if (ret < 0) {
/* well, can't return error so fake end of headers */
}
}
void *context)
{
struct message_block block;
int ret;
}
}
void *context)
{
struct message_header_parser_ctx *hdr_ctx;
struct message_header_line *hdr;
int ret;
/* note that we want to parse the header of all
the message parts, multiparts too. */
/* call after the final skipping */
}
}
}
void *context)
{
}
static void
{
if (use_crlf) {
} else {
}
}
if (!use_crlf)
}
}
{
}