summaryrefslogtreecommitdiffstats
path: root/maildrop/search.C
diff options
context:
space:
mode:
authorSam Varshavchik2013-08-26 19:41:57 -0400
committerSam Varshavchik2013-08-28 21:07:40 -0400
commite0a0a6eba9f31aea09624b3ea21fb75107c96780 (patch)
tree4abeeb6b18ddbde710c292c3fc6a170f53492797 /maildrop/search.C
parent88fcede4132f42e2297d11832cf6c7e047c71ce8 (diff)
downloadcourier-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.C122
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);
}