From 300e3f04404e771de89351e410699e447759175a Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 11:49:11 +0100 Subject: Added Email::attach_cid() returning CID --- system/libraries/Email.php | 87 +++++++++++++++++++++++++++++----------------- 1 file changed, 55 insertions(+), 32 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index efdbfd7c1..b84518bbd 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -718,14 +718,63 @@ class CI_Email { */ public function attach($filename, $disposition = '', $newname = NULL, $mime = '') { + if ($mime === '') + { + if ( ! file_exists($filename)) + { + $this->_set_error_message('lang:email_attachment_missing', $filename); + return FALSE; + } + + if ( ! $fp = fopen($filename, FOPEN_READ)) + { + $this->_set_error_message('lang:email_attachment_unreadable', $filename); + return FALSE; + } + $file_content = stream_get_contents($fp); + $mime = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); + } + else + { + $file_content =& $filename; // buffered file + } + $this->_attachments[] = array( 'name' => array($filename, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters - 'type' => $mime + 'type' => $mime, + 'content' => chunk_split(base64_encode($file_content)) ); - + + fclose($fp); + return $this; } + + // -------------------------------------------------------------------- + + /** + * Sets and return id of attachment (useful for attached inline pictures) + * + * @param string + * @return string + */ + public function attach_cid($filename) + { + if($this->multipart != 'related') + { + $this->multipart = 'related'; // Thunderbird need this for inline images + } + foreach($this->_attachments as $ind => $attach) + { + if($attach['name'][0] == $filename) + { + $this->_attachments[$ind]['cid'] = uniqid(basename($this->_attachments[$ind]['name'][0]) . "@"); + return $this->_attachments[$ind]['cid']; + } + } + return FALSE; + } // -------------------------------------------------------------------- @@ -1361,41 +1410,15 @@ class CI_Email { $filename = $this->_attachments[$i]['name'][0]; $basename = ($this->_attachments[$i]['name'][1] === NULL) ? basename($filename) : $this->_attachments[$i]['name'][1]; - $ctype = $this->_attachments[$i]['type']; - $file_content = ''; - - if ($ctype === '') - { - if ( ! file_exists($filename)) - { - $this->_set_error_message('lang:email_attachment_missing', $filename); - return FALSE; - } - - $file = filesize($filename) +1; - - if ( ! $fp = fopen($filename, FOPEN_READ)) - { - $this->_set_error_message('lang:email_attachment_unreadable', $filename); - return FALSE; - } - - $ctype = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); - $file_content = fread($fp, $file); - fclose($fp); - } - else - { - $file_content =& $this->_attachments[$i]['name'][0]; - } $attachment[$z++] = '--'.$this->_atc_boundary.$this->newline - .'Content-type: '.$ctype.'; ' + .'Content-type: '.$this->_attachments[$i]['type'].'; ' .'name="'.$basename.'"'.$this->newline .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline - .'Content-Transfer-Encoding: base64'.$this->newline; + .'Content-Transfer-Encoding: base64'.$this->newline + .(!empty($this->_attachments[$i]['cid']) ? "Content-ID: <".$this->_attachments[$i]['cid'].">".$this->newline : ''); - $attachment[$z++] = chunk_split(base64_encode($file_content)); + $attachment[$z++] = $this->_attachments[$i]['content']; } $body .= implode($this->newline, $attachment).$this->newline.'--'.$this->_atc_boundary.'--'; -- cgit v1.2.3-24-g4f1b From de88615b7245f00d086d97a9fb5ea8b307d34c4f Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 12:52:56 +0100 Subject: styleguided --- system/libraries/Email.php | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index b84518bbd..20eac72fc 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -731,8 +731,10 @@ class CI_Email { $this->_set_error_message('lang:email_attachment_unreadable', $filename); return FALSE; } + $file_content = stream_get_contents($fp); $mime = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); + fclose($fp); } else { @@ -746,7 +748,7 @@ class CI_Email { 'content' => chunk_split(base64_encode($file_content)) ); - fclose($fp); + return $this; } @@ -754,25 +756,29 @@ class CI_Email { // -------------------------------------------------------------------- /** - * Sets and return id of attachment (useful for attached inline pictures) + * Set and return id of attachment + * + * useful for attached inline pictures * - * @param string - * @return string + * @param string $filename + * @return string */ public function attach_cid($filename) { - if($this->multipart != 'related') + if ($this->multipart !== 'related') { $this->multipart = 'related'; // Thunderbird need this for inline images } - foreach($this->_attachments as $ind => $attach) + + for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { - if($attach['name'][0] == $filename) + if ($attach['name'][0] === $filename) { - $this->_attachments[$ind]['cid'] = uniqid(basename($this->_attachments[$ind]['name'][0]) . "@"); - return $this->_attachments[$ind]['cid']; + $this->_attachments[$ind]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); + return $this->_attachments[$i]['cid']; } } + return FALSE; } @@ -1416,7 +1422,7 @@ class CI_Email { .'name="'.$basename.'"'.$this->newline .'Content-Disposition: '.$this->_attachments[$i]['disposition'].';'.$this->newline .'Content-Transfer-Encoding: base64'.$this->newline - .(!empty($this->_attachments[$i]['cid']) ? "Content-ID: <".$this->_attachments[$i]['cid'].">".$this->newline : ''); + .(empty($this->_attachments[$i]['cid']) ? '' : 'Content-ID: <'.$this->_attachments[$i]['cid'].'>'.$this->newline); $attachment[$z++] = $this->_attachments[$i]['content']; } -- cgit v1.2.3-24-g4f1b From 230fca38f3f7481686d9d9c2989ad7d0a1a4874f Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 12:55:57 +0100 Subject: styleguided 2 --- system/libraries/Email.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 20eac72fc..01dbfbe19 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -748,8 +748,6 @@ class CI_Email { 'content' => chunk_split(base64_encode($file_content)) ); - - return $this; } @@ -774,7 +772,7 @@ class CI_Email { { if ($attach['name'][0] === $filename) { - $this->_attachments[$ind]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); + $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); return $this->_attachments[$i]['cid']; } } -- cgit v1.2.3-24-g4f1b From 9ad2fff4492e1e216aad0b03714ddfcb7a06d697 Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 13:25:34 +0100 Subject: variable repair --- system/libraries/Email.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 01dbfbe19..a41884f7d 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -747,7 +747,7 @@ class CI_Email { 'type' => $mime, 'content' => chunk_split(base64_encode($file_content)) ); - + return $this; } @@ -770,7 +770,7 @@ class CI_Email { for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { - if ($attach['name'][0] === $filename) + if ($this->_attachments[$i]['name'][0] === $filename) { $this->_attachments[$i]['cid'] = uniqid(basename($this->_attachments[$i]['name'][0]).'@'); return $this->_attachments[$i]['cid']; -- cgit v1.2.3-24-g4f1b From c809726558cc5364713e49c7404e43989203c4af Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Fri, 10 Jan 2014 14:45:31 +0200 Subject: Further changes related to PR #2807 --- system/libraries/Email.php | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index a41884f7d..739b76ccb 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -725,13 +725,13 @@ class CI_Email { $this->_set_error_message('lang:email_attachment_missing', $filename); return FALSE; } - + if ( ! $fp = fopen($filename, FOPEN_READ)) { $this->_set_error_message('lang:email_attachment_unreadable', $filename); return FALSE; } - + $file_content = stream_get_contents($fp); $mime = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); fclose($fp); @@ -740,7 +740,7 @@ class CI_Email { { $file_content =& $filename; // buffered file } - + $this->_attachments[] = array( 'name' => array($filename, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters @@ -750,24 +750,24 @@ class CI_Email { return $this; } - + // -------------------------------------------------------------------- - + /** - * Set and return id of attachment - * - * useful for attached inline pictures + * Set and return attachment Content-ID + * + * Useful for attached inline pictures * * @param string $filename * @return string */ - public function attach_cid($filename) + public function attachment_cid($filename) { if ($this->multipart !== 'related') { $this->multipart = 'related'; // Thunderbird need this for inline images } - + for ($i = 0, $c = count($this->_attachments); $i < $c; $i++) { if ($this->_attachments[$i]['name'][0] === $filename) @@ -776,7 +776,7 @@ class CI_Email { return $this->_attachments[$i]['cid']; } } - + return FALSE; } @@ -1429,6 +1429,7 @@ class CI_Email { $this->_finalbody = ($this->_get_protocol() === 'mail') ? $body : $hdr.$this->newline.$this->newline.$body; + return TRUE; } -- cgit v1.2.3-24-g4f1b From 232ea658e1f31d6c82a9ed9dae1bb3b292b6eb24 Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 15:21:18 +0100 Subject: attach files by absolute url --- system/libraries/Email.php | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 739b76ccb..71edc3b41 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -710,39 +710,39 @@ class CI_Email { /** * Assign file attachments * - * @param string $filename + * @param string $src can be path, url or buffered content * @param string $disposition = 'attachment' * @param string $newname = NULL * @param string $mime = '' * @return CI_Email */ - public function attach($filename, $disposition = '', $newname = NULL, $mime = '') + public function attach($src, $disposition = '', $newname = NULL, $mime = '') { if ($mime === '') { - if ( ! file_exists($filename)) + if (strpos($src,'http://')!==0 && ! file_exists($src) ) { - $this->_set_error_message('lang:email_attachment_missing', $filename); + $this->_set_error_message('lang:email_attachment_missing', $src); return FALSE; } - if ( ! $fp = fopen($filename, FOPEN_READ)) + if ( ! $fp = @fopen($src, FOPEN_READ)) { - $this->_set_error_message('lang:email_attachment_unreadable', $filename); + $this->_set_error_message('lang:email_attachment_unreadable', $src); return FALSE; } - + $file_content = stream_get_contents($fp); - $mime = $this->_mime_types(pathinfo($filename, PATHINFO_EXTENSION)); + $mime = $this->_mime_types(pathinfo($src, PATHINFO_EXTENSION)); fclose($fp); } else { - $file_content =& $filename; // buffered file + $file_content =& $src; // buffered file } $this->_attachments[] = array( - 'name' => array($filename, $newname), + 'name' => array($src, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters 'type' => $mime, 'content' => chunk_split(base64_encode($file_content)) -- cgit v1.2.3-24-g4f1b From ceb03af631c145d0694ef6f72e84517e18b7b092 Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 16:40:54 +0100 Subject: rename src to file --- system/libraries/Email.php | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 71edc3b41..37a628259 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -710,39 +710,39 @@ class CI_Email { /** * Assign file attachments * - * @param string $src can be path, url or buffered content + * @param string $file can be path, url or buffered content * @param string $disposition = 'attachment' * @param string $newname = NULL * @param string $mime = '' * @return CI_Email */ - public function attach($src, $disposition = '', $newname = NULL, $mime = '') + public function attach($file, $disposition = '', $newname = NULL, $mime = '') { if ($mime === '') { - if (strpos($src,'http://')!==0 && ! file_exists($src) ) + if (strpos($file,'http://')!==0 && ! file_exists($file) ) { - $this->_set_error_message('lang:email_attachment_missing', $src); + $this->_set_error_message('lang:email_attachment_missing', $file); return FALSE; } - if ( ! $fp = @fopen($src, FOPEN_READ)) + if ( ! $fp = @fopen($file, FOPEN_READ)) { - $this->_set_error_message('lang:email_attachment_unreadable', $src); + $this->_set_error_message('lang:email_attachment_unreadable', $file); return FALSE; } $file_content = stream_get_contents($fp); - $mime = $this->_mime_types(pathinfo($src, PATHINFO_EXTENSION)); + $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION)); fclose($fp); } else { - $file_content =& $src; // buffered file + $file_content =& $file; // buffered file } $this->_attachments[] = array( - 'name' => array($src, $newname), + 'name' => array($file, $newname), 'disposition' => empty($disposition) ? 'attachment' : $disposition, // Can also be 'inline' Not sure if it matters 'type' => $mime, 'content' => chunk_split(base64_encode($file_content)) -- cgit v1.2.3-24-g4f1b From 1dbdf72c555d0ea4d7c526e56e79472331eedc2a Mon Sep 17 00:00:00 2001 From: Petr Heralecky Date: Fri, 10 Jan 2014 16:54:51 +0100 Subject: condition repair and comments --- system/libraries/Email.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 37a628259..7e80ffbca 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -710,7 +710,7 @@ class CI_Email { /** * Assign file attachments * - * @param string $file can be path, url or buffered content + * @param string $file Can be local path, URL or buffered content * @param string $disposition = 'attachment' * @param string $newname = NULL * @param string $mime = '' @@ -720,7 +720,7 @@ class CI_Email { { if ($mime === '') { - if (strpos($file,'http://')!==0 && ! file_exists($file) ) + if (strpos($file, '://') === FALSE && ! file_exists($file)) { $this->_set_error_message('lang:email_attachment_missing', $file); return FALSE; @@ -731,7 +731,7 @@ class CI_Email { $this->_set_error_message('lang:email_attachment_unreadable', $file); return FALSE; } - + $file_content = stream_get_contents($fp); $mime = $this->_mime_types(pathinfo($file, PATHINFO_EXTENSION)); fclose($fp); -- cgit v1.2.3-24-g4f1b From 3d215207ceff44193e3c1888b868fc3f691718c0 Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 15 Jan 2014 11:08:47 +0200 Subject: Fix incorrect checks for the fwrite() return value ! fwrite() could trigger false-positives as it is possible for it to return 0 instead of boolean FALSE. (issue #2822) Also removed an unnecessary log level check that caused an extra space to be inserted for the INFO level. (proposed in PR #2821) --- system/libraries/Email.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 7e80ffbca..9487ad486 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -2097,7 +2097,7 @@ class CI_Email { */ protected function _send_data($data) { - if ( ! fwrite($this->_smtp_connect, $data.$this->newline)) + if (fwrite($this->_smtp_connect, $data.$this->newline) === FALSE) { $this->_set_error_message('lang:email_smtp_data_failure', $data); return FALSE; -- cgit v1.2.3-24-g4f1b From d8b1ad31cf7ee205ddf3cf396b1d1bfa45af49fa Mon Sep 17 00:00:00 2001 From: Andrey Andreev Date: Wed, 15 Jan 2014 17:42:52 +0200 Subject: Fix #2822: Incorrect usage of fwrite() We only used to check (and not always) if the return value of fwrite() is boolean FALSE, while it is possible that the otherwise returned bytecount is less than the length of data that we're trying to write. This allowed incomplete writes over network streams and possibly a few other edge cases. --- system/libraries/Email.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'system/libraries/Email.php') diff --git a/system/libraries/Email.php b/system/libraries/Email.php index 9487ad486..f4efff882 100644 --- a/system/libraries/Email.php +++ b/system/libraries/Email.php @@ -2097,7 +2097,16 @@ class CI_Email { */ protected function _send_data($data) { - if (fwrite($this->_smtp_connect, $data.$this->newline) === FALSE) + $data .= $this->newline; + for ($written = 0, $length = strlen($data); $written < $length; $written += $result) + { + if (($result = fwrite($this->_smtp_connect, substr($data, $written))) === FALSE) + { + break; + } + } + + if ($result === FALSE) { $this->_set_error_message('lang:email_smtp_data_failure', $data); return FALSE; -- cgit v1.2.3-24-g4f1b