message-body-search.c revision cd56a23e21f1df3f79648cf07e2f4385e2fadebb
/* Copyright (C) 2002 Timo Sirainen */
#include "lib.h"
#include "base64.h"
#include "buffer.h"
#include "istream.h"
#include "strescape.h"
#include "charset-utf8.h"
#include "quoted-printable.h"
#include "message-parser.h"
#include "message-content-parser.h"
#include "message-header-search.h"
#include "message-body-search.h"
#define DECODE_BLOCK_SIZE 8192
struct body_search_context {
const char *key;
const char *charset;
unsigned int unknown_charset:1;
unsigned int search_header:1;
};
struct part_search_context {
struct body_search_context *body_ctx;
struct charset_translation *translation;
char *content_type;
char *content_charset;
unsigned int content_qp:1;
unsigned int content_base64:1;
unsigned int content_unknown:1;
unsigned int ignore_header:1;
};
void *context)
{
}
}
static void
bool value_quoted, void *context)
{
}
}
void *context)
{
switch (value_len) {
case 4:
break;
case 6:
break;
case 16:
else
break;
default:
break;
}
}
{
struct header_search_context *hdr_search_ctx;
struct message_header_parser_ctx *hdr_ctx;
struct message_header_line *hdr;
int ret;
"UTF-8", NULL);
/* Our key is in UTF-8. It can't be invalid. */
/* we default to text content-type */
continue;
if (!ctx->ignore_header) {
hdr_search_ctx)) {
break;
}
}
continue;
}
ctx);
"Content-Transfer-Encoding") == 0) {
continue;
}
}
}
return found;
}
{
ssize_t i;
match_count /= sizeof(size_t);
end = p + block_size;
for (; p != end; p++) {
for (i = match_count-1; i >= 0; i--) {
/* full match */
p++;
return TRUE;
}
} else {
/* non-match */
i * sizeof(size_t),
sizeof(size_t));
match_count--;
}
}
if (*p == key[0]) {
if (key_len == 1) {
/* only one character in search key */
p++;
return TRUE;
}
value = 1;
match_count++;
}
}
return FALSE;
}
/* returns 1 = found, 0 = not found, -1 = error in input data */
{
const unsigned char *inbuf;
enum charset_result result;
/* we can use the buffer directly without copying */
} else {
/* some characters already in buffer, ie. last
conversion contained partial data */
}
inbuf_left -= inbuf_size;
switch (result) {
case CHARSET_RET_OUTPUT_FULL:
/* we should have copied the incomplete sequence.. */
/* fall through */
case CHARSET_RET_OK:
block_pos -= inbuf_left;
break;
/* save the partial sequence to buffer */
break;
return -1;
}
return 1;
}
return 0;
}
const struct message_part *part)
{
const unsigned char *data;
bool found;
if (ctx->content_unknown) {
/* unknown content-encoding-type, ignore */
return FALSE;
}
if (!ctx->content_type_text) {
/* non-text content, ignore - FIXME: should be configurable? */
return FALSE;
}
sizeof(size_t) *
part->physical_pos +
i_stream_seek(input, 0);
/* limit the size of t_malloc()s */
if (data_size > DECODE_BLOCK_SIZE)
t_push();
if (ctx->content_qp) {
} else if (ctx->content_base64) {
/* corrupted base64 data, don't bother with
the rest of it */
t_pop();
break;
}
} else {
}
t_pop();
if (ret != 0) {
break;
}
}
return found;
}
static bool
bool *unknown_charset_r, bool search_header)
{
/* get the key uppercased */
(const unsigned char *) key,
return FALSE;
return TRUE;
}
const struct message_part *part)
{
struct part_search_context part_ctx;
int ret;
ret = 0;
t_push();
/* found / invalid search key */
ret = 1;
ret = 1;
} else {
/* header size changed. */
ret = -1;
ret = 1;
}
t_pop();
}
return ret;
}
enum message_body_search_error *error_r)
{
struct body_search_context ctx;
int ret;
bool unknown_charset;
search_header)) {
*error_r = unknown_charset ?
return -1;
}
return ret;
}