diff -Naurp PHPMailer-acba50393dd03da69a50226c139722af8b153b11.orig/class.phpmailer.php PHPMailer-acba50393dd03da69a50226c139722af8b153b11.new/class.phpmailer.php --- PHPMailer-acba50393dd03da69a50226c139722af8b153b11.orig/class.phpmailer.php 2020-06-20 23:41:09.301467536 +0200 +++ PHPMailer-acba50393dd03da69a50226c139722af8b153b11.new/class.phpmailer.php 2020-06-21 00:12:06.174576353 +0200 @@ -2621,9 +2621,9 @@ class PHPMailer //Only include a filename property if we have one if (!empty($name)) { $mime[] = sprintf( - 'Content-Type: %s; name="%s"%s', + 'Content-Type: %s; name=%s%s', $type, - $this->encodeHeader($this->secureHeader($name)), + self::quotedString($this->encodeHeader($this->secureHeader($name))), $this->LE ); } else { @@ -2642,34 +2642,22 @@ class PHPMailer $mime[] = sprintf('Content-ID: <%s>%s', $cid, $this->LE); } - // If a filename contains any of these chars, it should be quoted, - // but not otherwise: RFC2183 & RFC2045 5.1 - // Fixes a warning in IETF's msglint MIME checker - // Allow for bypassing the Content-Disposition header totally + // Allow for bypassing the Content-Disposition header if (!(empty($disposition))) { $encoded_name = $this->encodeHeader($this->secureHeader($name)); - if (preg_match('/[ \(\)<>@,;:\\"\/\[\]\?=]/', $encoded_name)) { + if (!empty($encoded_name)) { $mime[] = sprintf( - 'Content-Disposition: %s; filename="%s"%s', + 'Content-Disposition: %s; filename=%s%s', $disposition, - $encoded_name, + self::quotedString($encoded_name), $this->LE . $this->LE ); } else { - if (!empty($encoded_name)) { - $mime[] = sprintf( - 'Content-Disposition: %s; filename=%s%s', - $disposition, - $encoded_name, - $this->LE . $this->LE - ); - } else { - $mime[] = sprintf( - 'Content-Disposition: %s%s', - $disposition, - $this->LE . $this->LE - ); - } + $mime[] = sprintf( + 'Content-Disposition: %s%s', + $disposition, + $this->LE . $this->LE + ); } } else { $mime[] = $this->LE; @@ -3974,6 +3962,28 @@ class PHPMailer } /** + * If a string contains any "special" characters, double-quote the name, + * and escape any double quotes with a backslash. + * + * @param string $str + * + * @return string + * + * @see RFC822 3.4.1 + */ + public static function quotedString($str) + { + if (preg_match('/[ ()<>@,;:"\/\[\]?=]/', $str)) { + //If the string contains any of these chars, it must be double-quoted + //and any double quotes must be escaped with a backslash + return '"' . str_replace('"', '\\"', $str) . '"'; + } + + //Return the string untouched, it doesn't need quoting + return $str; + } + + /** * Allows for public read access to 'to' property. * @note: Before the send() call, queued addresses (i.e. with IDN) are not yet included. * @access public