diff --git a/CHANGELOG b/CHANGELOG index 374d16bc9..012e94857 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -38,6 +38,7 @@ CHANGELOG Roundcube Webmail - Fix bug where Message-ID domain part was tied to username instead of current identity (#5385) - Fix bug where blocked.gif couldn't be attached to reply/forward with insecure content - Fix E_DEPRECATED warning when using Auth_SASL::factory() (#5401) +- Fix bug where names of downloaded files could be mailformed when derived from the message subject (#5404) RELEASE 1.2.1 ------------- diff --git a/plugins/zipdownload/zipdownload.php b/plugins/zipdownload/zipdownload.php index 67c257988..8f7139db1 100644 --- a/plugins/zipdownload/zipdownload.php +++ b/plugins/zipdownload/zipdownload.php @@ -160,7 +160,8 @@ class zipdownload extends rcube_plugin $zip->close(); - $filename = ($message->subject ?: 'roundcube') . '.zip'; + $filename = ($this->_filename_from_subject($message->subject) ?: 'attachments') . '.zip'; + $this->_deliver_zipfile($tmpfname, $filename); // delete temporary files from disk @@ -247,12 +248,11 @@ class zipdownload extends rcube_plugin fwrite($tmpfp, "\r\n"); } else { // maildir - $subject = rcube_mime::decode_mime_string((string)$headers->subject); + $subject = rcube_mime::decode_header($headers->subject, $headers->charset); + $subject = $this->_filename_from_subject(mb_substr($subject, 0, 16)); $subject = $this->_convert_filename($subject); - $subject = substr($subject, 0, 16); - $disp_name = ($subject ?: 'message_rfc822') . ".eml"; - $disp_name = $path . $uid . "_" . $disp_name; + $disp_name = $path . $uid . ($subject ? " $subject" : '') . '.eml'; $tmpfn = tempnam($temp_dir, 'zipmessage'); $tmpfp = fopen($tmpfn, 'w'); @@ -317,9 +317,19 @@ class zipdownload extends rcube_plugin */ private function _convert_filename($str) { - $str = rcube_charset::convert($str, RCUBE_CHARSET, $this->charset); + $str = strtr($str, array(':' => '', '/' => '-')); + + return rcube_charset::convert($str, RCUBE_CHARSET, $this->charset); + } + + /** + * Helper function to convert message subject into filename + */ + private function _filename_from_subject($str) + { + $str = preg_replace('/[\t\n\r\0\x0B]+\s*/', ' ', $str); - return strtr($str, array(':' => '', '/' => '-')); + return trim($str, " ./_"); } } diff --git a/program/steps/mail/viewsource.inc b/program/steps/mail/viewsource.inc index 6dab45c6f..aa84bc2a0 100644 --- a/program/steps/mail/viewsource.inc +++ b/program/steps/mail/viewsource.inc @@ -41,14 +41,11 @@ if ($uid = rcube_utils::get_input_value('_uid', rcube_utils::INPUT_GET)) { header("Content-Type: text/plain; charset={$charset}"); if (!empty($_GET['_save'])) { - $subject = rcube_mime::decode_header($headers->subject, $headers->charset); - $filename = ($subject ?: $RCMAIL->config->get('product_name', 'email')) . '.eml'; $browser = $RCMAIL->output->browser; - - if ($browser->ie) - $filename = rawurlencode($filename); - else - $filename = addcslashes($filename, '"'); + $subject = rcube_mime::decode_header($headers->subject, $headers->charset); + $filename = rcmail_filename_from_subject(mb_substr($subject, 0, 128)); + $filename = ($filename ?: $uid) . '.eml'; + $filename = $browser->ie ? rawurlencode($filename) : addcslashes($filename, '"'); header("Content-Length: {$headers->size}"); header("Content-Disposition: attachment; filename=\"$filename\""); @@ -73,3 +70,14 @@ else { } exit; + + +/** + * Helper function to convert message subject into filename + */ +function rcmail_filename_from_subject($str) +{ + $str = preg_replace('/[:\t\n\r\0\x0B\/]+\s*/', ' ', $str); + + return trim($str, " \t\n\r\0\x0B./_"); +}