diff options
| author | Sam Varshavchik | 2013-08-26 19:41:57 -0400 |
|---|---|---|
| committer | Sam Varshavchik | 2013-08-28 21:07:40 -0400 |
| commit | e0a0a6eba9f31aea09624b3ea21fb75107c96780 (patch) | |
| tree | 4abeeb6b18ddbde710c292c3fc6a170f53492797 /maildrop/search.C | |
| parent | 88fcede4132f42e2297d11832cf6c7e047c71ce8 (diff) | |
| download | courier-libs-e0a0a6eba9f31aea09624b3ea21fb75107c96780.tar.bz2 | |
maildrop: handle MIME encoding when searching messages.
Use rfc2045_decodmsgtoutf8() to decode entire message into UTF-8, before
searching it.
Diffstat (limited to 'maildrop/search.C')
| -rw-r--r-- | maildrop/search.C | 122 |
1 files changed, 45 insertions, 77 deletions
diff --git a/maildrop/search.C b/maildrop/search.C index d2756bb..a51c446 100644 --- a/maildrop/search.C +++ b/maildrop/search.C @@ -54,7 +54,7 @@ int Search::init(const char *expr, const char *opts) int errindex; pcre_regexp=pcre_compile(expr, - strchr(opts, 'D') ? 0:PCRE_CASELESS, + PCRE_UTF8 | (strchr(opts, 'D') ? 0:PCRE_CASELESS), &errptr, &errindex, 0); @@ -90,6 +90,7 @@ int Search::init(const char *expr, const char *opts) return -1; } + search_expr=expr; int cnt=0; pcre_fullinfo(pcre_regexp, pcre_regexp_extra, @@ -198,40 +199,46 @@ int Search::find(const char *str, const char *expr, const char *opts, int Search::findinline(Message &msg, const char *expr, Buffer *foreachp) { - current_line.reset(); - if (msg.appendline(current_line)) return (0); // Empty msg + struct rfc2045_decodemsgtoutf8_cb decode_cb; -int eof; + memset(&decode_cb, 0, sizeof(decode_cb)); - for (;;) - { - int c='\n'; + if (!match_header) + decode_cb.flags |= RFC2045_DECODEMSG_NOHEADERS; - next_line.reset(); - if ((eof=msg.appendline(next_line)) == 0) - { - c=(unsigned char)*(const char *)next_line; + if (!match_body) + decode_cb.flags |= RFC2045_DECODEMSG_NOBODY; - if ( isspace( c ) && c != '\n') - // Continued header - { - current_line.pop(); - current_line += next_line; - continue; - } - } - current_line.pop(); + current_line.reset(); + decode_cb.output_func=&Search::search_cb; + decode_cb.arg=this; + foreachp_arg=foreachp; + rfc2045_decodemsgtoutf8(&msg.rfc2045src_parser, + msg.rfc2045p, &decode_cb); + return 0; +} + +int Search::search_cb(const char *ptr, size_t cnt, void *arg) +{ + return ((Search *)arg)->search_cb(ptr, cnt); +} - current_line += '\0'; +int Search::search_cb(const char *ptr, size_t cnt) +{ + while (cnt) + { + size_t i; - if (match_header) + if (*ptr == '\n') { + current_line += '\0'; + if (VerboseLevel() > 2) { Buffer msg; msg="Matching /"; - msg.append(expr); + msg.append(search_expr); msg.append("/ against "); msg += current_line; msg.pop(); // Trailing null byte. @@ -257,73 +264,34 @@ int eof; score += weight1; weight1 *= weight2; - if (!scoring_match || foreachp) + if (!scoring_match || foreachp_arg) { init_match_vars(orig_str, match_count, pcre_vectors, - foreachp); - if (!foreachp) - return (0); + foreachp_arg); + if (!foreachp_arg) + // Stop searching now + return (-1); } } else if (VerboseLevel() > 2) merr.write("Not matched.\n"); - } - if ( c == '\n') break; - current_line=next_line; - } - if (!match_body || eof) return (0); - while (current_line.reset(), msg.appendline(current_line) == 0) - { - current_line.pop(); - current_line += '\0'; + current_line.reset(); - if (VerboseLevel() > 2) - { - Buffer msg; - - msg="Matching /"; - msg.append(expr); - msg.append("/ against "); - msg += current_line; - msg.pop(); // Trailing null byte. - msg += '\n'; - msg += '\0'; - merr.write(msg); + ++ptr; + --cnt; + continue; } - const char *orig_str=current_line; - int match_count; - - match_count=pcre_exec(pcre_regexp, - pcre_regexp_extra, - orig_str, - strlen(orig_str), - 0, - 0, - pcre_vectors, - pcre_vector_count); - - if (match_count > 0) - { - score += weight1; - weight1 *= weight2; - - if (!scoring_match || foreachp) - { - init_match_vars(orig_str, - match_count, - pcre_vectors, - foreachp); - if (!foreachp) - return (0); - } - } - else if (VerboseLevel() > 2) - merr.write("Not matched.\n"); + for (i=0; i<cnt; ++i) + if (ptr[i] == '\n') + break; + current_line.append(ptr, i); + ptr += i; + cnt -= i; } return (0); } |
