From d2cbd795b083c5a047451cded7e3b51cbb06058e Mon Sep 17 00:00:00 2001 From: Stephan Bosch <stephan@rename-it.nl> Date: Tue, 25 Dec 2007 12:06:41 +0100 Subject: [PATCH] Finished encoded-character extension. --- README | 5 ++- sieve/errors/encoded-character.sieve | 5 +++ sieve/tests/encoded-character.sieve | 4 ++- src/lib-sieve/ext-encoded-character.c | 45 ++++++++++++++++++--------- src/lib-sieve/ext-envelope.c | 2 +- src/lib-sieve/ext-fileinto.c | 2 +- src/sieve-bin/mail-raw.c | 3 +- 7 files changed, 44 insertions(+), 22 deletions(-) create mode 100644 sieve/errors/encoded-character.sieve diff --git a/README b/README index 0d91854ef..4dc26a8a6 100644 --- a/README +++ b/README @@ -121,7 +121,7 @@ Extensions and their implementation status: fileinto: full reject: full envelope: full - encoded-character: skeleton + encoded-character: full Other RFCs/drafts: subaddress: full @@ -193,10 +193,9 @@ TODO ---- Current: -* Implement encoded-character extension +* Implement variables extension. Next (in order of descending priority/precedence): -* Implement variables extension. * Finish implementing all extensions supported by cmusieve, except notify. * Limit the maximum number of errors. * Verify outgoing mail addresses diff --git a/sieve/errors/encoded-character.sieve b/sieve/errors/encoded-character.sieve new file mode 100644 index 000000000..f8a7686df --- /dev/null +++ b/sieve/errors/encoded-character.sieve @@ -0,0 +1,5 @@ +require "encoded-character"; +require "fileinto"; + +fileinto "INBOX.${unicode:200000}"; +fileinto "INBOX.${Unicode:DF01}"; diff --git a/sieve/tests/encoded-character.sieve b/sieve/tests/encoded-character.sieve index d085ae8d2..f9972a505 100644 --- a/sieve/tests/encoded-character.sieve +++ b/sieve/tests/encoded-character.sieve @@ -4,6 +4,8 @@ require "reject"; if address :contains "from" "idiot.com" { reject "You are an ${hex: 69 64 69 6F 74}."; -} else { +} elsif header :contains "subject" "idiot" { fileinto "INBOX.${hex: 49 44 49 4F 54}"; +} else { + fileinto "INBOX.${unicode: 0052 00e6}vh${unicode: 00f8 006c}"; } diff --git a/src/lib-sieve/ext-encoded-character.c b/src/lib-sieve/ext-encoded-character.c index 9e0303919..a213c086b 100644 --- a/src/lib-sieve/ext-encoded-character.c +++ b/src/lib-sieve/ext-encoded-character.c @@ -3,12 +3,13 @@ * * Authors: Stephan Bosch * Specification: draft-ietf-sieve-3028bis-13.txt - * Implementation: skeleton - * Status: under development + * Implementation: full + * Status: experimental, largely untested * */ #include "lib.h" +#include "unichar.h" #include "sieve-extensions.h" #include "sieve-commands.h" @@ -100,7 +101,7 @@ static bool _parse_hexint return ( digit > 0 ); } -static bool _decode_hex +static int _decode_hex (const char **in, const char *inend, string_t *result) { int values = 0; @@ -116,11 +117,12 @@ static bool _decode_hex values++; } - return ( values > 0 ); + return ( values > 0 ? 1 : 0 ); } -static bool _decode_unicode -(const char **in, const char *inend, string_t *result) +static int _decode_unicode +(struct sieve_validator *validator, struct sieve_command_context *cmd, + const char **in, const char *inend, string_t *result) { int values = 0; @@ -130,19 +132,28 @@ static bool _decode_unicode if ( !_skip_whitespace(in, inend) ) return FALSE; if ( !_parse_hexint(in, inend, 6, &unicode_hex) ) break; - - /* FIXME: unicode is unimplemented */ - str_append(result, ">>unicode unimplemented<<"); + + if ( (unicode_hex <= 0xD7FF) || + (unicode_hex >= 0xE000 && unicode_hex <= 0x10FFFF) ) + uni_ucs4_to_utf8_c((unichar_t) unicode_hex, result); + else { + sieve_command_validate_error(validator, cmd, + "invalid unicode character 0x%08x in encoded character substitution", + unicode_hex); + return -1; + } values++; } - return ( values > 0 ); + return ( values > 0 ? 1 : 0 ); } bool arg_encoded_string_validate -(struct sieve_validator *validator ATTR_UNUSED, struct sieve_ast_argument **arg, +(struct sieve_validator *validator, struct sieve_ast_argument **arg, struct sieve_command_context *cmd) { + bool result = TRUE; + int ret; enum { ST_NONE, ST_OPEN, ST_TYPE, ST_CLOSE } state = ST_NONE; string_t *str = sieve_ast_argument_str(*arg); @@ -156,7 +167,7 @@ bool arg_encoded_string_validate p = strval; strstart = p; - while ( p < strend ) { + while ( result && p < strend ) { switch ( state ) { case ST_NONE: if ( *p == '$' ) { @@ -186,12 +197,18 @@ bool arg_encoded_string_validate str_truncate(tmpstr, 0); if ( strncasecmp(mark, "hex", p - mark) == 0 ) { p++; - if ( !_decode_hex(&p, strend, tmpstr) ) + ret = _decode_hex(&p, strend, tmpstr); + if ( ret <= 0 ) { state = ST_NONE; + if ( ret < 0 ) result = FALSE; + } } else if ( strncasecmp(mark, "unicode", p - mark) == 0 ) { p++; - if ( !_decode_unicode(&p, strend, tmpstr) ) + ret = _decode_unicode(validator, cmd, &p, strend, tmpstr); + if ( ret <= 0 ) { state = ST_NONE; + if ( ret < 0 ) result = FALSE; + } } else { p++; state = ST_NONE; diff --git a/src/lib-sieve/ext-envelope.c b/src/lib-sieve/ext-envelope.c index 6a4013bd7..b776f7c79 100644 --- a/src/lib-sieve/ext-envelope.c +++ b/src/lib-sieve/ext-envelope.c @@ -2,7 +2,7 @@ * ------------------ * * Authors: Stephan Bosch - * Specification: RFC3028 + * Specification: RFC3028, draft-ietf-sieve-3028bis-13.txt * Implementation: full * Status: experimental, largely untested * diff --git a/src/lib-sieve/ext-fileinto.c b/src/lib-sieve/ext-fileinto.c index f4ababf13..f53cae6ff 100644 --- a/src/lib-sieve/ext-fileinto.c +++ b/src/lib-sieve/ext-fileinto.c @@ -2,7 +2,7 @@ * ------------------ * * Authors: Stephan Bosch - * Specification: RFC3028 + * Specification: RFC3028, draft-ietf-sieve-3028bis-13.txt * Implementation: full * Status: experimental, largely untested * diff --git a/src/sieve-bin/mail-raw.c b/src/sieve-bin/mail-raw.c index fb314c156..19b400f2f 100644 --- a/src/sieve-bin/mail-raw.c +++ b/src/sieve-bin/mail-raw.c @@ -65,8 +65,7 @@ static struct istream *create_raw_stream(int fd) input2 = input; i_stream_ref(input2); } else { - input2 = i_stream_create_limit(input, input->v_offset, - (uoff_t)-1); + input2 = i_stream_create_limit(input, (uoff_t)-1); } i_stream_unref(&input); -- GitLab