Skip to content
Permalink
Browse files

Avoiding circular object reference in SmptTransport

This fixes a memory leak while sending multiple emails.

Fixes: #9198
  • Loading branch information...
Linnk committed Aug 1, 2016
1 parent 774af90 commit 93db51cf1063452004fe2c518aefc069f38d1828
Showing with 23 additions and 46 deletions.
  1. +19 −28 lib/Cake/Network/Email/SmtpTransport.php
  2. +4 −18 lib/Cake/Test/Case/Network/Email/SmtpTransportTest.php
@@ -32,13 +32,6 @@ class SmtpTransport extends AbstractTransport {
*/
protected $_socket;
/**
* CakeEmail
*
* @var CakeEmail
*/
protected $_cakeEmail;
/**
* Content of email to return
*
@@ -90,12 +83,10 @@ public function getLastResponse() {
* @throws SocketException
*/
public function send(CakeEmail $email) {
$this->_cakeEmail = $email;
$this->_connect();
$this->_auth();
$this->_sendRcpt();
$this->_sendData();
$this->_sendRcpt($email);
$this->_sendData($email);
$this->_disconnect();
return $this->_content;
@@ -237,10 +228,10 @@ protected function _prepareRcptCmd($email) {
*
* @return array
*/
protected function _prepareFromAddress() {
$from = $this->_cakeEmail->returnPath();
protected function _prepareFromAddress($email) {
$from = $email->returnPath();
if (empty($from)) {
$from = $this->_cakeEmail->from();
$from = $email->from();
}
return $from;
}
@@ -250,10 +241,10 @@ protected function _prepareFromAddress() {
*
* @return array
*/
protected function _prepareRecipientAddresses() {
$to = $this->_cakeEmail->to();
$cc = $this->_cakeEmail->cc();
$bcc = $this->_cakeEmail->bcc();
protected function _prepareRecipientAddresses($email) {
$to = $email->to();
$cc = $email->cc();
$bcc = $email->bcc();
return array_merge(array_keys($to), array_keys($cc), array_keys($bcc));
}
@@ -262,17 +253,17 @@ protected function _prepareRecipientAddresses() {
*
* @return array
*/
protected function _prepareMessageHeaders() {
return $this->_cakeEmail->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'to', 'cc', 'subject'));
protected function _prepareMessageHeaders($email) {
return $email->getHeaders(array('from', 'sender', 'replyTo', 'readReceipt', 'to', 'cc', 'subject'));
}
/**
* Prepares the message body.
*
* @return string
*/
protected function _prepareMessage() {
$lines = $this->_cakeEmail->message();
protected function _prepareMessage($email) {
$lines = $email->message();
$messages = array();
foreach ($lines as $line) {
if ((!empty($line)) && ($line[0] === '.')) {
@@ -290,11 +281,11 @@ protected function _prepareMessage() {
* @return void
* @throws SocketException
*/
protected function _sendRcpt() {
$from = $this->_prepareFromAddress();
protected function _sendRcpt($email) {
$from = $this->_prepareFromAddress($email);
$this->_smtpSend($this->_prepareFromCmd(key($from)));
$emails = $this->_prepareRecipientAddresses();
$emails = $this->_prepareRecipientAddresses($email);
foreach ($emails as $email) {
$this->_smtpSend($this->_prepareRcptCmd($email));
}
@@ -306,11 +297,11 @@ protected function _sendRcpt() {
* @return void
* @throws SocketException
*/
protected function _sendData() {
protected function _sendData($email) {
$this->_smtpSend('DATA', '354');
$headers = $this->_headersToString($this->_prepareMessageHeaders());
$message = $this->_prepareMessage();
$headers = $this->_headersToString($this->_prepareMessageHeaders($email));
$message = $this->_prepareMessage($email);
$this->_smtpSend($headers . "\r\n\r\n" . $message . "\r\n\r\n\r\n.");
$this->_content = array('headers' => $headers, 'message' => $message);
@@ -35,16 +35,6 @@ public function setSocket(CakeSocket $socket) {
$this->_socket = $socket;
}
/**
* Helper to change the CakeEmail
*
* @param object $cakeEmail An email object.
* @return void
*/
public function setCakeEmail($cakeEmail) {
$this->_cakeEmail = $cakeEmail;
}
/**
* Disabled the socket change
*
@@ -348,8 +338,7 @@ public function testRcpt() {
$this->socket->expects($this->at(13))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(14))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->setCakeEmail($email);
$this->SmtpTransport->sendRcpt();
$this->SmtpTransport->sendRcpt($email);
}
/**
@@ -370,8 +359,7 @@ public function testRcptWithReturnPath() {
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->setCakeEmail($email);
$this->SmtpTransport->sendRcpt();
$this->SmtpTransport->sendRcpt($email);
}
/**
@@ -416,8 +404,7 @@ public function testSendData() {
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->setCakeEmail($email);
$this->SmtpTransport->sendData();
$this->SmtpTransport->sendData($email);
}
/**
@@ -498,8 +485,7 @@ public function testGetLastResponse() {
$this->socket->expects($this->at(4))->method('read')->will($this->returnValue(false));
$this->socket->expects($this->at(5))->method('read')->will($this->returnValue("250 OK\r\n"));
$this->SmtpTransport->setCakeEmail($email);
$this->SmtpTransport->sendRcpt();
$this->SmtpTransport->sendRcpt($email);
$expected = array(
array('code' => '250', 'message' => 'OK'),

0 comments on commit 93db51c

Please sign in to comment.
You can’t perform that action at this time.