From 57b26fc75fe1748e54c8f6d51c16e8d8f8ee10bf Mon Sep 17 00:00:00 2001 From: Bron Gondwana Date: Mon, 23 Mar 2009 14:29:29 +1100 Subject: [PATCH] Use UTF-8 decoding for searches and notify messages Fixes Bug #1721, Bug #1722 --- bc_eval.c | 82 ++++++++++++++++++---------------------------------- script.c | 75 +++++++++++++----------------------------------- sieve_interface.h | 4 +-- 3 files changed, 51 insertions(+), 110 deletions(-) diff --git a/bc_eval.c b/bc_eval.c index d57eb88..af9c002 100644 --- a/bc_eval.c +++ b/bc_eval.c @@ -362,8 +362,7 @@ static int shouldRespond(void * m, sieve_interp_t *interp, } /* Evaluate a bytecode test */ -static int eval_bc_test(sieve_interp_t *interp, - struct hash_table *body_cache, void* m, +static int eval_bc_test(sieve_interp_t *interp, void* m, bytecode_input_t * bc, int * ip) { int res=0; @@ -386,7 +385,7 @@ static int eval_bc_test(sieve_interp_t *interp, case BC_NOT:/*2*/ i+=1; - res = eval_bc_test(interp, body_cache, m, bc, &i); + res = eval_bc_test(interp, m, bc, &i); if(res >= 0) res = !res; /* Only invert in non-error case */ break; @@ -445,7 +444,7 @@ static int eval_bc_test(sieve_interp_t *interp, * in the right place */ for (x=0; xgetbody(m, content_types, &val) != SIEVE_OK) { @@ -827,47 +838,12 @@ static int eval_bc_test(sieve_interp_t *interp, /* bodypart(s) exist, now to test them */ - for (y=0; val && val[y]!=NULL && !res; y++) { + for (y = 0; val && val[y] && !res; y++) { if (match == B_COUNT) { count++; - } else { - const char *content = val[y]->content; - int size = val[y]->size; - - if (transform != B_RAW) { - int encoding; - - /* XXX currently unknown encodings are processed as raw */ - if (!val[y]->encoding) - encoding = ENCODING_NONE; - else if (!strcmp(val[y]->encoding, "BASE64")) - encoding = ENCODING_BASE64; - else if (!strcmp(val[y]->encoding, "QUOTED-PRINTABLE")) - encoding = ENCODING_QP; - else - encoding = ENCODING_NONE; - - if (encoding != ENCODING_NONE) { - content = hash_lookup(val[y]->section, body_cache); - if (content) { - /* already decoded this part */ - size = strlen(content); - } - else { - /* decode this part and add it to the cache */ - char *decbuf = NULL; - content = charset_decode_mimebody(val[y]->content, - val[y]->size, - encoding, &decbuf, - 0, &size); - hash_insert(val[y]->section, (void *) content, - body_cache); - } - } - - /* XXX convert charset */ - } + } else if (val[y]->decoded_body) { + const char *content = val[y]->decoded_body; /* search through all the data */ currd=datai+2; @@ -886,10 +862,10 @@ static int eval_bc_test(sieve_interp_t *interp, goto alldone; } - res |= comp(content, size, (const char *)reg, comprock); + res |= comp(content, strlen(content), (const char *)reg, comprock); free(reg); } else { - res |= comp(content, size, data_val, comprock); + res |= comp(content, strlen(content), data_val, comprock); } } /* For each data */ } @@ -939,7 +915,7 @@ static int eval_bc_test(sieve_interp_t *interp, /* The entrypoint for bytecode evaluation */ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i, - struct hash_table *body_cache, void *sc, void *m, + void *sc, void *m, sieve_imapflags_t * imapflags, action_list_t *actions, notify_list_t *notify_list, const char **errmsg) { @@ -1069,7 +1045,7 @@ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i, int result; ip+=2; - result=eval_bc_test(i, body_cache, m, bc, &ip); + result=eval_bc_test(i, m, bc, &ip); if (result<0) { *errmsg = "Invalid test"; @@ -1404,7 +1380,7 @@ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i, } if (!res) - res = sieve_eval_bc(exe, 1, i, body_cache, + res = sieve_eval_bc(exe, 1, i, sc, m, imapflags, actions, notify_list, errmsg); diff --git a/script.c b/script.c index 1843dd4..c294d59 100644 --- a/script.c +++ b/script.c @@ -232,6 +232,7 @@ static void add_header(sieve_interp_t *i, int isenv, char *header, int *outlen, int *outalloc) { const char **h; + char *decoded_header; int addlen; /* get header value */ if (isenv) @@ -242,7 +243,9 @@ static void add_header(sieve_interp_t *i, int isenv, char *header, if (!h || !h[0]) return; - addlen = strlen(h[0]) + 1; + decoded_header = charset_parse_mimeheader(h[0]); + + addlen = strlen(decoded_header) + 1; /* realloc if necessary */ if ( (*outlen) + addlen >= *outalloc) @@ -252,13 +255,14 @@ static void add_header(sieve_interp_t *i, int isenv, char *header, } /* add header value */ - strcat(*out,h[0]); + strcat(*out, decoded_header); + + free(decoded_header); *outlen += addlen; } static int build_notify_message(sieve_interp_t *i, - struct hash_table *body_cache, const char *msg, void *message_context, char **out, int *outlen) { @@ -303,38 +307,9 @@ static int build_notify_message(sieve_interp_t *i, i->getbody(message_context, content_types, &parts); /* we only use the first text part */ - if (parts && parts[0]) { - const char *content = parts[0]->content; - int size = parts[0]->size; - int encoding; - - /* XXX currently unknown encodings are processed as raw */ - if (!parts[0]->encoding) - encoding = ENCODING_NONE; - else if (!strcmp(parts[0]->encoding, "BASE64")) - encoding = ENCODING_BASE64; - else if (!strcmp(parts[0]->encoding, "QUOTED-PRINTABLE")) - encoding = ENCODING_QP; - else - encoding = ENCODING_NONE; - - if (encoding != ENCODING_NONE) { - content = hash_lookup(parts[0]->section, body_cache); - if (content) { - /* already decoded this part */ - size = strlen(content); - } - else { - /* decode this part and add it to the cache */ - char *decbuf = NULL; - content = charset_decode_mimebody(parts[0]->content, - parts[0]->size, - encoding, &decbuf, - 0, &size); - hash_insert(parts[0]->section, (void *) content, - body_cache); - } - } + if (parts && parts[0] && parts[0]->decoded_body) { + const char *content = parts[0]->decoded_body; + int size = strlen(content); if (n == 0 || n > (size_t)size) n = size; @@ -428,7 +403,6 @@ static int sieve_removeflag(sieve_imapflags_t *imapflags, const char *flag) } static int send_notify_callback(sieve_interp_t *interp, - struct hash_table *body_cache, void *message_context, void * script_context, notify_list_t *notify, char *actions_string, const char **errmsg) @@ -453,7 +427,7 @@ static int send_notify_callback(sieve_interp_t *interp, if(!strcmp("$env-from$",*nc.options)) interp->getenvelope(message_context, "From", &nc.options); - build_notify_message(interp, body_cache, notify->message, message_context, + build_notify_message(interp, notify->message, message_context, &out_msg, &out_msglen); build_msg = xmalloc(out_msglen + /*strlen(actions_string)*/ + 30); @@ -609,7 +583,6 @@ int sieve_script_unload(sieve_execute_t **s) static int do_sieve_error(int ret, sieve_interp_t *interp, - struct hash_table *body_cache, void *script_context, void *message_context, sieve_imapflags_t * imapflags, @@ -648,7 +621,7 @@ static int do_sieve_error(int ret, if (n->isactive) { lastaction = ACTION_NOTIFY; - notify_ret = send_notify_callback(interp, body_cache, + notify_ret = send_notify_callback(interp, message_context, script_context,n, actions_string, &errmsg); @@ -662,7 +635,7 @@ static int do_sieve_error(int ret, if (notify_ret != SIEVE_OK) - return do_sieve_error(ret, interp, body_cache, + return do_sieve_error(ret, interp, script_context, message_context, imapflags, actions, notify_list, lastaction, implicit_keep, actions_string, errmsg); @@ -696,7 +669,7 @@ static int do_sieve_error(int ret, "Kept\n"); else { implicit_keep = 0; /* don't try an implicit keep again */ - return do_sieve_error(ret, interp, body_cache, + return do_sieve_error(ret, interp, script_context, message_context, imapflags, actions, notify_list, lastaction, implicit_keep, actions_string, errmsg); @@ -711,7 +684,6 @@ static int do_sieve_error(int ret, static int do_action_list(sieve_interp_t *interp, - struct hash_table *body_cache, void *script_context, void *message_context, sieve_imapflags_t *imapflags, @@ -887,7 +859,7 @@ static int do_action_list(sieve_interp_t *interp, } } - return do_sieve_error(ret, interp, body_cache, + return do_sieve_error(ret, interp, script_context, message_context, imapflags, actions, notify_list, lastaction, implicit_keep, actions_string, errmsg); @@ -896,7 +868,7 @@ static int do_action_list(sieve_interp_t *interp, /* execute some bytecode */ int sieve_eval_bc(sieve_execute_t *exe, int is_incl, sieve_interp_t *i, - struct hash_table *body_cache, void *sc, void *m, + void *sc, void *m, sieve_imapflags_t * imapflags, action_list_t *actions, notify_list_t *notify_list, const char **errmsg); @@ -911,7 +883,6 @@ int sieve_execute_bytecode(sieve_execute_t *exe, sieve_interp_t *interp, char actions_string[ACTIONS_STRING_LEN] = ""; const char *errmsg = NULL; sieve_imapflags_t imapflags; - struct hash_table body_cache; if (!interp) return SIEVE_FAIL; @@ -921,42 +892,38 @@ int sieve_execute_bytecode(sieve_execute_t *exe, sieve_interp_t *interp, if (interp->notify) { notify_list = new_notify_list(); if (notify_list == NULL) { - return do_sieve_error(SIEVE_NOMEM, interp, NULL, + return do_sieve_error(SIEVE_NOMEM, interp, script_context, message_context, &imapflags, actions, notify_list, lastaction, 0, actions_string, errmsg); } } - /* build a hash table to cache decoded body parts */ - construct_hash_table(&body_cache, 10, 1); - actions = new_action_list(); if (actions == NULL) { - ret = do_sieve_error(SIEVE_NOMEM, interp, &body_cache, + ret = do_sieve_error(SIEVE_NOMEM, interp, script_context, message_context, &imapflags, actions, notify_list, lastaction, 0, actions_string, errmsg); } else { - ret = sieve_eval_bc(exe, 0, interp, &body_cache, + ret = sieve_eval_bc(exe, 0, interp, script_context, message_context, &imapflags, actions, notify_list, &errmsg); if (ret < 0) { - ret = do_sieve_error(SIEVE_RUN_ERROR, interp, &body_cache, + ret = do_sieve_error(SIEVE_RUN_ERROR, interp, script_context, message_context, &imapflags, actions, notify_list, lastaction, 0, actions_string, errmsg); } else { - ret = do_action_list(interp, &body_cache, + ret = do_action_list(interp, script_context, message_context, &imapflags, actions, notify_list, actions_string, errmsg); } } - free_hash_table(&body_cache, free); return ret; } diff --git a/sieve_interface.h b/sieve_interface.h index a3fe008..2cba690 100644 --- a/sieve_interface.h +++ b/sieve_interface.h @@ -76,9 +76,7 @@ typedef int sieve_get_include(void *script_context, const char *script, /* MUST keep this struct sync'd with bodypart in imap/message.h */ typedef struct sieve_bodypart { char section[128]; - const char *content; - const char *encoding; - unsigned long size; + const char *decoded_body; } sieve_bodypart_t; typedef int sieve_get_body(void *message_context, const char **content_types, -- 1.5.6.5