Mail - Reorganize and use same cleaning function when saving mail as infolog as for saving to VFS

This commit is contained in:
nathangray 2018-01-22 09:12:44 -07:00
parent 4f75e7068a
commit 2febc0a46e
3 changed files with 16 additions and 42 deletions

View File

@ -166,7 +166,7 @@ class mail_integration {
// instead of fetching only the attachments attached files (as we did previously) // instead of fetching only the attachments attached files (as we did previously)
$message = $mo->getMessageRawBody($attachment['uid'],$attachment['partID'],($attachment['folder']?$attachment['folder']:$mailbox)); $message = $mo->getMessageRawBody($attachment['uid'],$attachment['partID'],($attachment['folder']?$attachment['folder']:$mailbox));
$headers = $mo->getMessageHeader($attachment['uid'],$attachment['partID'],true,false,($attachment['folder']?$attachment['folder']:$mailbox)); $headers = $mo->getMessageHeader($attachment['uid'],$attachment['partID'],true,false,($attachment['folder']?$attachment['folder']:$mailbox));
$subject = mail_bo::adaptSubjectForImport($headers['SUBJECT']); $subject = mail_bo::clean_subject_for_filename($headers['SUBJECT']);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_"); $attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."_");
$tmpfile = fopen($attachment_file,'w'); $tmpfile = fopen($attachment_file,'w');
fwrite($tmpfile,$message); fwrite($tmpfile,$message);
@ -238,7 +238,7 @@ class mail_integration {
if ($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw' && if ($GLOBALS['egw_info']['user']['preferences'][$sessionLocation]['saveAsOptions']==='add_raw' &&
$_rawMail && file_exists($_rawMail)) $_rawMail && file_exists($_rawMail))
{ {
$subject = mail_bo::adaptSubjectForImport($_subject); $subject = mail_bo::clean_subject_for_filename($_subject);
$attachments[] = array( $attachments[] = array(
'name' => trim($subject).'.eml', 'name' => trim($subject).'.eml',
'mimeType' => 'message/rfc822', 'mimeType' => 'message/rfc822',
@ -300,14 +300,13 @@ class mail_integration {
{ {
$message = $mo->getMessageRawBody($uid, '',$mailbox); $message = $mo->getMessageRawBody($uid, '',$mailbox);
$headers = $mo->getMessageHeader($uid, '',true,false,$mailbox); $headers = $mo->getMessageHeader($uid, '',true,false,$mailbox);
$subject = mail_bo::adaptSubjectForImport($headers['SUBJECT']);
$attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."mail_integrate"); $attachment_file =tempnam($GLOBALS['egw_info']['server']['temp_dir'],$GLOBALS['egw_info']['flags']['currentapp']."mail_integrate");
$tmpfile = fopen($attachment_file,'w'); $tmpfile = fopen($attachment_file,'w');
fwrite($tmpfile,$message); fwrite($tmpfile,$message);
fclose($tmpfile); fclose($tmpfile);
$size = filesize($attachment_file); $size = filesize($attachment_file);
$mailcontent['attachments'][] = array( $mailcontent['attachments'][] = array(
'name' => Api\Vfs::encodePathComponent(trim($subject)).'.eml', 'name' => mail_bo::clean_subject_for_filename($headers['SUBJECT']).'.eml',
'mimeType' => 'message/rfc822', 'mimeType' => 'message/rfc822',
'type' => 'message/rfc822', 'type' => 'message/rfc822',
'tmp_name' => $attachment_file, 'tmp_name' => $attachment_file,

View File

@ -2761,13 +2761,13 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
{ {
$headers = Horde_Mime_Headers::parseHeaders($message); $headers = Horde_Mime_Headers::parseHeaders($message);
$subject = str_replace('$$','__',Mail::decode_header($headers['SUBJECT'])); $subject = str_replace('$$','__',Mail::decode_header($headers['SUBJECT']));
$subject = $this->clean_subject_for_filename($subject); $subject = mail_bo::clean_subject_for_filename($subject);
Api\Header\Content::safe($message, $subject.".eml", $mime='message/rfc822', $size=0, true, true); Api\Header\Content::safe($message, $subject.".eml", $mime='message/rfc822', $size=0, true, true);
echo $message; echo $message;
} }
else else
{ {
$subject = $this->clean_subject_for_filename($subject); $subject = mail_bo::clean_subject_for_filename($subject);
Api\Header\Content::safe($message, $subject.".eml", $mime='text/html', $size=0, true, false); Api\Header\Content::safe($message, $subject.".eml", $mime='text/html', $size=0, true, false);
print '<pre>'. htmlspecialchars($message, ENT_NOQUOTES|ENT_SUBSTITUTE, 'utf-8') .'</pre>'; print '<pre>'. htmlspecialchars($message, ENT_NOQUOTES|ENT_SUBSTITUTE, 'utf-8') .'</pre>';
} }
@ -2846,11 +2846,11 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
if (Vfs::is_dir($path)) if (Vfs::is_dir($path))
{ {
$headers = $this->mail_bo->getMessageHeader($uid,$partID,true,false,$mailbox); $headers = $this->mail_bo->getMessageHeader($uid,$partID,true,false,$mailbox);
$file = $dir . '/'.$this->clean_subject_for_filename($headers['SUBJECT']).'.eml'; $file = $dir . '/'.mail_bo::clean_subject_for_filename($headers['SUBJECT']).'.eml';
} }
else else
{ {
$file = $dir . '/' . $this->clean_subject_for_filename(str_replace($dir.'/', '', $path)); $file = $dir . '/' . mail_bo::clean_subject_for_filename(str_replace($dir.'/', '', $path));
} }
// Check if file already exists, then try to assign a none existance filename // Check if file already exists, then try to assign a none existance filename
@ -2918,7 +2918,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
{ {
$dir = Vfs::dirname($path); $dir = Vfs::dirname($path);
// Need to deal with any ? here, or basename will truncate // Need to deal with any ? here, or basename will truncate
$filename = $this->clean_subject_for_filename(str_replace('?','_',Vfs::basename($path))); $filename = mail_bo::clean_subject_for_filename(str_replace('?','_',Vfs::basename($path)));
} }
if (!Vfs::is_writable($dir)) if (!Vfs::is_writable($dir))
@ -2999,7 +2999,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
$attachment = $this->mail_bo->getAttachment($params['uid'],$params['part'],$params['is_winmail'],false); $attachment = $this->mail_bo->getAttachment($params['uid'],$params['part'],$params['is_winmail'],false);
} }
$file = $dir. '/' . ($filename ? $filename : $this->clean_subject_for_filename($attachment['filename'])); $file = $dir. '/' . ($filename ? $filename : mail_bo::clean_subject_for_filename($attachment['filename']));
$counter = 1; $counter = 1;
$tmp_file = $file; $tmp_file = $file;
@ -3034,25 +3034,6 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
return $res; return $res;
} }
/**
* Make the provided filename safe to store in the VFS
*
* Some characters found in subjects that cause problems if we try to put
* them as filenames (Windows) so we remove any characters that might result
* in additional directories, or issues on Windows.
*
* Under Windows the characters < > ? " : | \ / * are not allowed.
* % causes problems with VFS UI
*
* @param string $filename
* @return Cleaned filename, with problematic characters replaced with '_'.
*/
protected function clean_subject_for_filename($filename)
{
static $filter_pattern = '$[\f\n\t\v\\:*#?<>%"\|/\\\?]$';
return preg_replace($filter_pattern, "_", $filename);
}
/** /**
* Zip all attachments and send to user * Zip all attachments and send to user
* @param string $message_id = null * @param string $message_id = null
@ -3092,7 +3073,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
// Add subject to path, so it gets used as the file name, replacing ':' // Add subject to path, so it gets used as the file name, replacing ':'
// as it seems to cause an error // as it seems to cause an error
$path = $temp_path . '/' . ($header['SUBJECT'] ? Vfs::encodePathComponent($this->clean_subject_for_filename(str_replace(':','-', $header['SUBJECT']))) : lang('mail')) .'/'; $path = $temp_path . '/' . ($header['SUBJECT'] ? Vfs::encodePathComponent(mail_bo::clean_subject_for_filename(str_replace(':','-', $header['SUBJECT']))) : lang('mail')) .'/';
if(!Vfs::mkdir($path, 0700, true)) if(!Vfs::mkdir($path, 0700, true))
{ {
echo "Unable to open temp directory $path"; echo "Unable to open temp directory $path";
@ -3131,7 +3112,7 @@ $filter['before']= date("d-M-Y", $cutoffdate2);
pathinfo($file['filename'], PATHINFO_EXTENSION); pathinfo($file['filename'], PATHINFO_EXTENSION);
} }
// Strip special characters to make sure the files are visible for all OS (windows has issues) // Strip special characters to make sure the files are visible for all OS (windows has issues)
$target_name = $this->clean_subject_for_filename(iconv($file['charset'] ? $file['charset'] : $GLOBALS['egw_info']['server']['system_charset'], 'ASCII//IGNORE', $file['filename'])); $target_name = mail_bo::clean_subject_for_filename(iconv($file['charset'] ? $file['charset'] : $GLOBALS['egw_info']['server']['system_charset'], 'ASCII//IGNORE', $file['filename']));
if (!($fp = Vfs::fopen($path.$target_name,'wb')) || if (!($fp = Vfs::fopen($path.$target_name,'wb')) ||
!(!fseek($attachment['attachment'], 0, SEEK_SET) && stream_copy_to_stream($attachment['attachment'], $fp))) !(!fseek($attachment['attachment'], 0, SEEK_SET) && stream_copy_to_stream($attachment['attachment'], $fp)))

View File

@ -19,10 +19,6 @@ use Egroupware\Api;
class SaveToVfsTest extends \EGroupware\Api\AppTest class SaveToVfsTest extends \EGroupware\Api\AppTest
{ {
// Mail object under test
protected $ui = null;
/** /**
* Create a custom status we can use to test * Create a custom status we can use to test
*/ */
@ -40,12 +36,10 @@ class SaveToVfsTest extends \EGroupware\Api\AppTest
public function setUp() public function setUp()
{ {
$this->ui = new VfsTestMailUi(false);
} }
public function tearDown() public function tearDown()
{ {
$this->ui = null;
} }
/** /**
@ -59,7 +53,7 @@ class SaveToVfsTest extends \EGroupware\Api\AppTest
*/ */
public function testVfsFilename($filename, $replacements) public function testVfsFilename($filename, $replacements)
{ {
$cleaned = $this->ui->clean_subject_for_filename($filename); $cleaned = VfsTestMail::clean_subject_for_filename($filename);
$this->assertNotContains('<', $cleaned); $this->assertNotContains('<', $cleaned);
$this->assertNotContains('>', $cleaned); $this->assertNotContains('>', $cleaned);
@ -73,7 +67,7 @@ class SaveToVfsTest extends \EGroupware\Api\AppTest
$this->assertNotContains('?', $cleaned); $this->assertNotContains('?', $cleaned);
// Length should stay the same // Length should stay the same
$this->assertEquals(strlen($filename), strlen($cleaned)); $this->assertEquals(strlen($filename), strlen($cleaned), 'Length changed');
if(!$replacements) if(!$replacements)
{ {
@ -95,7 +89,7 @@ class SaveToVfsTest extends \EGroupware\Api\AppTest
array('Contains a #', true), array('Contains a #', true),
array('Contains a :', true), array('Contains a :', true),
array('Contains a |', true), array('Contains a |', true),
array('Contains a \ ', true), array('Contains a \\', true),
array('Contains a *', true), array('Contains a *', true),
array('Contains a /', true), array('Contains a /', true),
array('Contains a ?', true), array('Contains a ?', true),
@ -106,10 +100,10 @@ class SaveToVfsTest extends \EGroupware\Api\AppTest
} }
class VfsTestMailUi extends \mail_ui class VfsTestMail extends \mail_bo
{ {
// Expose for testing // Expose for testing
public function clean_subject_for_filename($filename) public static function clean_subject_for_filename($filename)
{ {
return parent::clean_subject_for_filename($filename); return parent::clean_subject_for_filename($filename);
} }