Fix over-long line in DSN
authorJeremy Harris <jgh146exb@wizmail.org>
Tue, 12 May 2020 23:58:32 +0000 (00:58 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Tue, 12 May 2020 23:58:32 +0000 (00:58 +0100)
doc/doc-txt/ChangeLog
src/src/deliver.c

index 3cd92b8168bfe78680c71ad3408e0832038bc1d4..1682a78b743f847b5184c648f48efa1db88d4aa4 100644 (file)
@@ -199,6 +199,10 @@ JH/42 Internationalisation: change the default for downconversion in the smtp
       transport.  The change does mean that addresses needing conversion will
       be converted when previously a delivery failure would occur.
 
       transport.  The change does mean that addresses needing conversion will
       be converted when previously a delivery failure would occur.
 
+JH/43 Fix possible long line in DSN.  Previously when a very long SMTP error
+      response was received it would be used unchecked in a fail-DSN, violating
+      standards on line-length limits.  Truncate if needed.
+
 
 Exim version 4.93
 -----------------
 
 Exim version 4.93
 -----------------
index 85b061b303559810500a27e6927e9b41ca49b99b..40db50084485400dd04f50e3f7303519d05ec7bc 100644 (file)
@@ -5380,7 +5380,8 @@ Returns:       nothing
 static void
 print_dsn_diagnostic_code(const address_item *addr, FILE *f)
 {
 static void
 print_dsn_diagnostic_code(const address_item *addr, FILE *f)
 {
-uschar *s = testflag(addr, af_pass_message) ? addr->message : NULL;
+uschar * s = testflag(addr, af_pass_message) ? addr->message : NULL;
+unsigned cnt;
 
 /* af_pass_message and addr->message set ? print remote host answer */
 if (s)
 
 /* af_pass_message and addr->message set ? print remote host answer */
 if (s)
@@ -5392,19 +5393,32 @@ if (s)
   if (!(s = Ustrstr(addr->message, ": ")))
     return;                            /* not found, bail out */
   s += 2;  /* skip ": " */
   if (!(s = Ustrstr(addr->message, ": ")))
     return;                            /* not found, bail out */
   s += 2;  /* skip ": " */
-  fprintf(f, "Diagnostic-Code: smtp; ");
+  cnt = fprintf(f, "Diagnostic-Code: smtp; ");
   }
 /* no message available. do nothing */
 else return;
 
 while (*s)
   }
 /* no message available. do nothing */
 else return;
 
 while (*s)
+  {
+  if (cnt > 950)       /* RFC line length limit: 998 */
+    {
+    DEBUG(D_deliver) debug_printf("print_dsn_diagnostic_code() truncated line\n");
+    fputs("[truncated]", f);
+    break;
+    }
+
   if (*s == '\\' && s[1] == 'n')
     {
     fputs("\n ", f);    /* as defined in RFC 3461 */
     s += 2;
   if (*s == '\\' && s[1] == 'n')
     {
     fputs("\n ", f);    /* as defined in RFC 3461 */
     s += 2;
+    cnt += 2;
     }
   else
     }
   else
+    {
     fputc(*s++, f);
     fputc(*s++, f);
+    cnt++;
+    }
+  }
 
 fputc('\n', f);
 }
 
 fputc('\n', f);
 }
@@ -7831,11 +7845,11 @@ wording. */
            fprintf(fp, "Remote-MTA: X-ip; [%s]%s\n", hu->address, p);
            }
          if ((s = addr->smtp_greeting) && *s)
            fprintf(fp, "Remote-MTA: X-ip; [%s]%s\n", hu->address, p);
            }
          if ((s = addr->smtp_greeting) && *s)
-           fprintf(fp, "X-Remote-MTA-smtp-greeting: X-str; %s\n", s);
+           fprintf(fp, "X-Remote-MTA-smtp-greeting: X-str; %.900s\n", s);
          if ((s = addr->helo_response) && *s)
          if ((s = addr->helo_response) && *s)
-           fprintf(fp, "X-Remote-MTA-helo-response: X-str; %s\n", s);
+           fprintf(fp, "X-Remote-MTA-helo-response: X-str; %.900s\n", s);
          if ((s = addr->message) && *s)
          if ((s = addr->message) && *s)
-           fprintf(fp, "X-Exim-Diagnostic: X-str; %s\n", s);
+           fprintf(fp, "X-Exim-Diagnostic: X-str; %.900s\n", s);
          }
 #endif
          print_dsn_diagnostic_code(addr, fp);
          }
 #endif
          print_dsn_diagnostic_code(addr, fp);