[Exim] [PATCH] New feature: remove ASCII NUL from message da…

Top Page
Delete this message
Reply to this message
Author: Phil Brutsche
Date:  
To: exim-users
Subject: [Exim] [PATCH] New feature: remove ASCII NUL from message data
This is a multi-part message in MIME format.
--
Background:

Some email clients are quite persistent in putting binary "junk" in
message bodies; this junk manifests itself as the ASCII NUL character.
It is seen (for me anyway) immediately following base64 data; the email
client is almost always Microsoft Outlook in either Corporate mode or
Internet mode, although some other email clients have been seen to cause
this problem.

Cyrus, which we use for POP3 and IMAP (Exim is the MTA), isn't very
tolerant of this binary data and refuses to deliver the message, causing
it to bounce.

The people I derive my income from tell me bouncing the messages isn't
an option.

The fix:

I have created a patch, against 4.14 (no idea if it'll work with older
versions), that adds a main configuration option called
"strip_nul_char". This option defaults to off, and provides the same
behavior as an unpatched Exim.

Setting "strip_nul_char" to true causes Exim to remove NULs from SMTP
and non-SMTP message bodies as they are received.

At a later date I intend to make this an option for the lmtp and smtp
transports.

The patch has received some testing here and seems to work fine (with
and without exiscan), but more testing is welcome.

Comments and constructive criticism welcome, flames to /dev/null.

--

Phil Brutsche
phil@???
--
diff -u -r exim-4.14/src/globals.c exim-4.14-modified/src/globals.c
--- exim-4.14/src/globals.c    Tue Mar 11 06:20:20 2003
+++ exim-4.14-modified/src/globals.c    Tue Apr  8 17:22:27 2003
@@ -846,6 +846,7 @@
                "\0<--------------Space to patch spool_directory->";
 int     string_datestamp_offset= -1;
 BOOL    strip_excess_angle_brackets = FALSE;
+BOOL    strip_nul_char         = FALSE;
 BOOL    strip_trailing_dot     = FALSE;
 BOOL    synchronous_delivery   = FALSE;
 BOOL    syslog_timestamp       = TRUE;
diff -u -r exim-4.14/src/globals.h exim-4.14-modified/src/globals.h
--- exim-4.14/src/globals.h    Tue Mar 11 06:20:20 2003
+++ exim-4.14-modified/src/globals.h    Tue Apr  8 12:40:16 2003
@@ -511,6 +511,7 @@
 extern uschar *spool_directory;        /* Name of spool directory */
 extern int     string_datestamp_offset;/* After insertion by string_format */
 extern BOOL    strip_excess_angle_brackets; /* Surrounding route-addrs */
+extern BOOL    strip_nul_char;         /* Remove ASCII NUL from messages */
 extern BOOL    strip_trailing_dot;     /* Remove dots at ends of domains */
 extern BOOL    synchronous_delivery;   /* TRUE if -odi is set */
 extern BOOL    syslog_timestamp;       /* TRUE if time on syslogs */
diff -u -r exim-4.14/src/readconf.c exim-4.14-modified/src/readconf.c
--- exim-4.14/src/readconf.c    Tue Mar 11 06:20:22 2003
+++ exim-4.14-modified/src/readconf.c    Mon Apr  7 16:35:39 2003
@@ -270,6 +270,7 @@
   { "split_spool_directory",    opt_bool,        &split_spool_directory },
   { "spool_directory",          opt_stringptr,   &spool_directory },
   { "strip_excess_angle_brackets", opt_bool,     &strip_excess_angle_brackets },
+  { "strip_nul_char",           opt_bool,        &strip_nul_char },
   { "strip_trailing_dot",       opt_bool,        &strip_trailing_dot },
   { "syslog_timestamp",         opt_bool,        &syslog_timestamp },
   { "system_filter",            opt_stringptr,   &system_filter },
diff -u -r exim-4.14/src/receive.c exim-4.14-modified/src/receive.c
--- exim-4.14/src/receive.c    Tue Mar 11 06:20:22 2003
+++ exim-4.14-modified/src/receive.c    Tue Apr  8 15:05:13 2003
@@ -441,6 +441,8 @@


   for (; (ch = (receive_getc)()) != EOF; last_ch = ch)
     {
+    if (strip_nul_char && (ch == 0))
+      continue;
     if (drop_cr)
       {
       if (last_ch == '\r' && ch != '\n')
@@ -476,6 +478,8 @@


 while ((ch = (receive_getc)()) != EOF)
   {
+  if (strip_nul_char && (ch == 0))
+    continue;
   switch (ch_state)
     {
     case 0:                         /* Normal state */
@@ -572,6 +576,8 @@


 while ((ch = (receive_getc)()) != EOF)
   {
+  if (strip_nul_char && (ch == 0))
+    continue;
   switch (ch_state)
     {
     case 0:                             /* After LF or CRLF */
--