summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSam Varshavchik2018-02-16 20:54:41 -0500
committerSam Varshavchik2018-02-16 21:19:05 -0500
commitc6c18e6142360a30cc11bfe29ac8b762e99a2104 (patch)
treeee18c5fcb707c5d230950dd57e4ae619e3bd38b0
parent8b4fcc3895ca8243e200c15cd089323a482cad13 (diff)
downloadcourier-libs-c6c18e6142360a30cc11bfe29ac8b762e99a2104.tar.bz2
maildrop: Add :H pattern modifier to maildrop.
rfc2045: RFC2045_DECODEMSG_NOATTACHHEADERS flag, do not decode attachment headers. maildrop: The ":H" pattern modifier searches main headers only, does not search attachments' headers.
-rw-r--r--maildrop/maildropfilter.sgml31
-rw-r--r--maildrop/search.C16
-rw-r--r--maildrop/search.h2
-rw-r--r--maildrop/testsuite260
-rw-r--r--rfc2045/rfc2045.h7
-rw-r--r--rfc2045/rfc2045decodemsgtoutf8.c7
6 files changed, 109 insertions, 14 deletions
diff --git a/maildrop/maildropfilter.sgml b/maildrop/maildropfilter.sgml
index c97aeec..7609eef 100644
--- a/maildrop/maildropfilter.sgml
+++ b/maildrop/maildropfilter.sgml
@@ -711,10 +711,24 @@ DIR=`ls`
more options. The following options may be specified in any order:</para>
<variablelist>
- <varlistentry><term><literal>h</literal></term>
+ <varlistentry>
+ <term><literal>h</literal></term>
<listitem>
- <para>Match this pattern against the message header.</para>
- </listitem></varlistentry>
+ <para>
+ Match this pattern in the message's header, and the
+ header of any attachments in the message.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term><literal>H</literal></term>
+ <listitem>
+ <para>
+ Match this pattern in the message's main header. Do not match
+ this pattern in the headers of the message's attachments.
+ </para>
+ </listitem>
+ </varlistentry>
<varlistentry><term><literal>b</literal></term>
<listitem>
<para>Match this pattern against the message body.</para>
@@ -730,10 +744,13 @@ DIR=`ls`
</variablelist>
<para>
- If neither 'h' or 'b' is specified, the pattern is matched against the
- header only. Specifying the 'b' option causes the pattern to be matched
- against the message body. Specifying both causes the pattern to be matched
- against the entire message.</para>
+ If neither 'h', 'H', or 'b' is specified, 'h' is the default,
+ matching the pattern in the message's header, and all attachments'
+ headers. Specifying the 'b' option causes the pattern to be matched
+ against the message body.
+ Specifying 'b' and 'h' causes the pattern to be matched
+ against the entire message.
+ </para>
<para>
Normally, each line in the message gets matched against the pattern
diff --git a/maildrop/search.C b/maildrop/search.C
index c7fa007..9add6ee 100644
--- a/maildrop/search.C
+++ b/maildrop/search.C
@@ -32,18 +32,22 @@ void Search::cleanup()
int Search::init(const char *expr, const char *opts)
{
- match_header=0;
+ match_top_header=0;
+ match_other_headers=0;
match_body=0;
weight1=1;
weight2=1;
scoring_match=0;
score=0;
- if (strchr(opts, 'h')) match_header=1;
+ if (strchr(opts, 'h')) match_top_header=match_other_headers=1;
+ if (strchr(opts, 'H')) match_top_header=1;
+
if (strchr(opts, 'b')) match_body=1;
- if (!match_header && !match_body)
+ if (!match_top_header && !match_other_headers && !match_body)
{
- match_header=1;
+ match_top_header=1;
+ match_other_headers=1;
if (strchr(opts, 'w')) match_body=1;
}
@@ -203,8 +207,10 @@ int Search::findinline(Message &msg, const char *expr, Buffer *foreachp)
memset(&decode_cb, 0, sizeof(decode_cb));
- if (!match_header)
+ if (!match_top_header && !match_other_headers)
decode_cb.flags |= RFC2045_DECODEMSG_NOHEADERS;
+ else if (match_top_header && !match_other_headers)
+ decode_cb.flags |= RFC2045_DECODEMSG_NOATTACHHEADERS;
if (!match_body)
decode_cb.flags |= RFC2045_DECODEMSG_NOBODY;
diff --git a/maildrop/search.h b/maildrop/search.h
index 5f97125..681c082 100644
--- a/maildrop/search.h
+++ b/maildrop/search.h
@@ -50,7 +50,7 @@ class Search {
Buffer current_line;
Buffer next_line;
- int match_header, match_body;
+ int match_top_header, match_other_headers, match_body;
double weight1, weight2;
int scoring_match;
diff --git a/maildrop/testsuite2 b/maildrop/testsuite2
index 1a87854..ae5bbf1 100644
--- a/maildrop/testsuite2
+++ b/maildrop/testsuite2
@@ -261,4 +261,64 @@ then
exit 1
fi
+cat >testsuite.msg <<EOF
+Subject: mainpart
+Mime-Version: 1.0
+Content-Type: multipart/mixed; boundary="zz"
+
+--zzz
+Subject: attachmentpart
+
+body
+
+--zzz--
+EOF
+
+cat >testsuite1.filter <<EOF
+if (/body/)
+{
+ echo "Should not have found the body"
+ EXITCODE=1
+}
+
+if (!/body/:b)
+{
+ echo "Should have found the body"
+ EXITCODE=1
+}
+
+if (!(/^Subject: mainpart/ && /^Subject: mainpart/))
+{
+ echo "all header search 1 failed"
+ EXITCODE=1
+}
+
+if (!(/^Subject: mainpart/:h && /^Subject: mainpart/:h))
+{
+ echo "all header search 2 failed"
+ EXITCODE=1
+}
+
+if (!/^Subject: mainpart/:H)
+{
+ echo "mainpart search failed"
+ EXITCODE=1
+}
+
+if (/^Subject: attachmentpart/:H)
+{
+ echo "attachment search should have failed"
+ EXITCODE=1
+}
+exit
+EOF
+
+if ./maildrop ./testsuite1.filter <testsuite.msg
+then
+ :
+else
+ echo "header/body test failed"
+ exit 1
+fi
+
rm -f testsuite?.filter testsuite.msg
diff --git a/rfc2045/rfc2045.h b/rfc2045/rfc2045.h
index c7e2a62..90c2b56 100644
--- a/rfc2045/rfc2045.h
+++ b/rfc2045/rfc2045.h
@@ -559,6 +559,13 @@ struct rfc2045_decodemsgtoutf8_cb {
** Do not prepend name: to converted header content.
*/
+
+#define RFC2045_DECODEMSG_NOATTACHHEADERS 0x08
+/*
+** Do not decode MIME headers of attachments. Decode only the message's
+** main headers.
+*/
+
/*
** Convert a message into a utf8 bytestream. The output produced by this
** function is a catentation of decoded header and text content data, converted
diff --git a/rfc2045/rfc2045decodemsgtoutf8.c b/rfc2045/rfc2045decodemsgtoutf8.c
index fb58c3e..45ce2ea 100644
--- a/rfc2045/rfc2045decodemsgtoutf8.c
+++ b/rfc2045/rfc2045decodemsgtoutf8.c
@@ -79,7 +79,7 @@ static int doconvtoutf8_rfc822hdr(const char *header,
doconvtoutf8_write(header, strlen(header), &info);
doconvtoutf8_write(": ", 2, &info);
}
- rfc822_display_hdrvalue(header, value, "utf-8",
+ rfc822_display_hdrvalue(header, value, "utf-8",
doconvtoutf8_write_noeol,
doconvtoutf8_error,
&info);
@@ -129,6 +129,11 @@ int rfc2045_decodemsgtoutf8(struct rfc2045src *src,
if (callback->flags & RFC2045_DECODEMSG_NOHEADERS)
continue;
+ if ((callback->flags &
+ RFC2045_DECODEMSG_NOATTACHHEADERS)
+ && p->parent)
+ continue;
+
if (doconvtoutf8_rfc822hdr(header, value,
callback) < 0)
return -1;