PageRenderTime 1149ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/api/vendor/phpmailer/phpmailer/test/phpmailerTest.php

https://gitlab.com/x33n/respond
PHP | 1374 lines | 1038 code | 101 blank | 235 comment | 60 complexity | 52ccd0e72558cc8d9e8f6a10e5d01e52 MD5 | raw file
  1. <?php
  2. /**
  3. * PHPMailer - PHP email transport unit tests
  4. * Requires PHPUnit 3.3 or later.
  5. *
  6. * PHP version 5.0.0
  7. *
  8. * @package PHPMailer
  9. * @author Andy Prevost
  10. * @author Marcus Bointon <phpmailer@synchromedia.co.uk>
  11. * @copyright 2004 - 2009 Andy Prevost
  12. * @copyright 2010 Marcus Bointon
  13. * @license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
  14. */
  15. require_once '../PHPMailerAutoload.php';
  16. /**
  17. * PHPMailer - PHP email transport unit test class
  18. * Performs authentication tests
  19. */
  20. class PHPMailerTest extends PHPUnit_Framework_TestCase
  21. {
  22. /**
  23. * Holds the default phpmailer instance.
  24. * @private
  25. * @type PHPMailer
  26. */
  27. public $Mail;
  28. /**
  29. * Holds the SMTP mail host.
  30. * @public
  31. * @type string
  32. */
  33. public $Host = '';
  34. /**
  35. * Holds the change log.
  36. * @private
  37. * @type string[]
  38. */
  39. public $ChangeLog = array();
  40. /**
  41. * Holds the note log.
  42. * @private
  43. * @type string[]
  44. */
  45. public $NoteLog = array();
  46. /**
  47. * Default include path
  48. * @type string
  49. */
  50. public $INCLUDE_DIR = '../';
  51. /**
  52. * PIDs of any processes we need to kill
  53. * @type array
  54. * @access private
  55. */
  56. private $pids = array();
  57. /**
  58. * Run before each test is started.
  59. */
  60. public function setUp()
  61. {
  62. if (file_exists('./testbootstrap.php')) {
  63. include './testbootstrap.php'; //Overrides go in here
  64. }
  65. $this->Mail = new PHPMailer;
  66. $this->Mail->SMTPDebug = 4; //Full debug output
  67. $this->Mail->Priority = 3;
  68. $this->Mail->Encoding = '8bit';
  69. $this->Mail->CharSet = 'iso-8859-1';
  70. if (array_key_exists('mail_from', $_REQUEST)) {
  71. $this->Mail->From = $_REQUEST['mail_from'];
  72. } else {
  73. $this->Mail->From = 'unit_test@phpmailer.example.com';
  74. }
  75. $this->Mail->FromName = 'Unit Tester';
  76. $this->Mail->Sender = '';
  77. $this->Mail->Subject = 'Unit Test';
  78. $this->Mail->Body = '';
  79. $this->Mail->AltBody = '';
  80. $this->Mail->WordWrap = 0;
  81. if (array_key_exists('mail_host', $_REQUEST)) {
  82. $this->Mail->Host = $_REQUEST['mail_host'];
  83. } else {
  84. $this->Mail->Host = 'mail.example.com';
  85. }
  86. if (array_key_exists('mail_port', $_REQUEST)) {
  87. $this->Mail->Port = $_REQUEST['mail_port'];
  88. } else {
  89. $this->Mail->Port = 25;
  90. }
  91. $this->Mail->Helo = 'localhost.localdomain';
  92. $this->Mail->SMTPAuth = false;
  93. $this->Mail->Username = '';
  94. $this->Mail->Password = '';
  95. $this->Mail->PluginDir = $this->INCLUDE_DIR;
  96. $this->Mail->addReplyTo('no_reply@phpmailer.example.com', 'Reply Guy');
  97. $this->Mail->Sender = 'unit_test@phpmailer.example.com';
  98. if (strlen($this->Mail->Host) > 0) {
  99. $this->Mail->Mailer = 'smtp';
  100. } else {
  101. $this->Mail->Mailer = 'mail';
  102. $this->Mail->Sender = 'unit_test@phpmailer.example.com';
  103. }
  104. if (array_key_exists('mail_to', $_REQUEST)) {
  105. $this->setAddress($_REQUEST['mail_to'], 'Test User', 'to');
  106. }
  107. if (array_key_exists('mail_cc', $_REQUEST) and strlen($_REQUEST['mail_cc']) > 0) {
  108. $this->setAddress($_REQUEST['mail_cc'], 'Carbon User', 'cc');
  109. }
  110. }
  111. /**
  112. * Run after each test is completed.
  113. */
  114. public function tearDown()
  115. {
  116. // Clean global variables
  117. $this->Mail = null;
  118. $this->ChangeLog = array();
  119. $this->NoteLog = array();
  120. foreach ($this->pids as $pid) {
  121. $p = escapeshellarg($pid);
  122. shell_exec("ps $p && kill -TERM $p");
  123. }
  124. }
  125. /**
  126. * Build the body of the message in the appropriate format.
  127. *
  128. * @private
  129. * @return void
  130. */
  131. public function buildBody()
  132. {
  133. $this->checkChanges();
  134. // Determine line endings for message
  135. if ($this->Mail->ContentType == 'text/html' || strlen($this->Mail->AltBody) > 0) {
  136. $eol = '<br/>';
  137. $bullet = '<li>';
  138. $bullet_start = '<ul>';
  139. $bullet_end = '</ul>';
  140. } else {
  141. $eol = "\n";
  142. $bullet = ' - ';
  143. $bullet_start = '';
  144. $bullet_end = '';
  145. }
  146. $ReportBody = '';
  147. $ReportBody .= '---------------------' . $eol;
  148. $ReportBody .= 'Unit Test Information' . $eol;
  149. $ReportBody .= '---------------------' . $eol;
  150. $ReportBody .= 'phpmailer version: ' . $this->Mail->Version . $eol;
  151. $ReportBody .= 'Content Type: ' . $this->Mail->ContentType . $eol;
  152. if (strlen($this->Mail->Host) > 0) {
  153. $ReportBody .= 'Host: ' . $this->Mail->Host . $eol;
  154. }
  155. // If attachments then create an attachment list
  156. $attachments = $this->Mail->getAttachments();
  157. if (count($attachments) > 0) {
  158. $ReportBody .= 'Attachments:' . $eol;
  159. $ReportBody .= $bullet_start;
  160. foreach ($attachments as $attachment) {
  161. $ReportBody .= $bullet . 'Name: ' . $attachment[1] . ', ';
  162. $ReportBody .= 'Encoding: ' . $attachment[3] . ', ';
  163. $ReportBody .= 'Type: ' . $attachment[4] . $eol;
  164. }
  165. $ReportBody .= $bullet_end . $eol;
  166. }
  167. // If there are changes then list them
  168. if (count($this->ChangeLog) > 0) {
  169. $ReportBody .= 'Changes' . $eol;
  170. $ReportBody .= '-------' . $eol;
  171. $ReportBody .= $bullet_start;
  172. for ($i = 0; $i < count($this->ChangeLog); $i++) {
  173. $ReportBody .= $bullet . $this->ChangeLog[$i][0] . ' was changed to [' .
  174. $this->ChangeLog[$i][1] . ']' . $eol;
  175. }
  176. $ReportBody .= $bullet_end . $eol . $eol;
  177. }
  178. // If there are notes then list them
  179. if (count($this->NoteLog) > 0) {
  180. $ReportBody .= 'Notes' . $eol;
  181. $ReportBody .= '-----' . $eol;
  182. $ReportBody .= $bullet_start;
  183. for ($i = 0; $i < count($this->NoteLog); $i++) {
  184. $ReportBody .= $bullet . $this->NoteLog[$i] . $eol;
  185. }
  186. $ReportBody .= $bullet_end;
  187. }
  188. // Re-attach the original body
  189. $this->Mail->Body .= $eol . $eol . $ReportBody;
  190. }
  191. /**
  192. * Check which default settings have been changed for the report.
  193. * @private
  194. * @return void
  195. */
  196. public function checkChanges()
  197. {
  198. if ($this->Mail->Priority != 3) {
  199. $this->addChange('Priority', $this->Mail->Priority);
  200. }
  201. if ($this->Mail->Encoding != '8bit') {
  202. $this->addChange('Encoding', $this->Mail->Encoding);
  203. }
  204. if ($this->Mail->CharSet != 'iso-8859-1') {
  205. $this->addChange('CharSet', $this->Mail->CharSet);
  206. }
  207. if ($this->Mail->Sender != '') {
  208. $this->addChange('Sender', $this->Mail->Sender);
  209. }
  210. if ($this->Mail->WordWrap != 0) {
  211. $this->addChange('WordWrap', $this->Mail->WordWrap);
  212. }
  213. if ($this->Mail->Mailer != 'mail') {
  214. $this->addChange('Mailer', $this->Mail->Mailer);
  215. }
  216. if ($this->Mail->Port != 25) {
  217. $this->addChange('Port', $this->Mail->Port);
  218. }
  219. if ($this->Mail->Helo != 'localhost.localdomain') {
  220. $this->addChange('Helo', $this->Mail->Helo);
  221. }
  222. if ($this->Mail->SMTPAuth) {
  223. $this->addChange('SMTPAuth', 'true');
  224. }
  225. }
  226. /**
  227. * Add a changelog entry.
  228. * @access private
  229. * @param string $sName
  230. * @param string $sNewValue
  231. * @return void
  232. */
  233. public function addChange($sName, $sNewValue)
  234. {
  235. $this->ChangeLog[] = array($sName, $sNewValue);
  236. }
  237. /**
  238. * Adds a simple note to the message.
  239. * @public
  240. * @param string $sValue
  241. * @return void
  242. */
  243. public function addNote($sValue)
  244. {
  245. $this->NoteLog[] = $sValue;
  246. }
  247. /**
  248. * Adds all of the addresses
  249. * @access public
  250. * @param string $sAddress
  251. * @param string $sName
  252. * @param string $sType
  253. * @return boolean
  254. */
  255. public function setAddress($sAddress, $sName = '', $sType = 'to')
  256. {
  257. switch ($sType) {
  258. case 'to':
  259. return $this->Mail->addAddress($sAddress, $sName);
  260. case 'cc':
  261. return $this->Mail->addCC($sAddress, $sName);
  262. case 'bcc':
  263. return $this->Mail->addBCC($sAddress, $sName);
  264. }
  265. return false;
  266. }
  267. /**
  268. * Test CRAM-MD5 authentication
  269. * Needs a connection to a server that supports this auth mechanism, so commented out by default
  270. */
  271. public function testAuthCRAMMD5()
  272. {
  273. $this->Mail->Host = 'hostname';
  274. $this->Mail->Port = 587;
  275. $this->Mail->SMTPAuth = true;
  276. $this->Mail->SMTPSecure = 'tls';
  277. $this->Mail->AuthType = 'CRAM-MD5';
  278. $this->Mail->Username = 'username';
  279. $this->Mail->Password = 'password';
  280. $this->Mail->Body = 'Test body';
  281. $this->Mail->Subject .= ': Auth CRAM-MD5';
  282. $this->Mail->From = 'from@example.com';
  283. $this->Mail->Sender = 'from@example.com';
  284. $this->Mail->clearAllRecipients();
  285. $this->Mail->addAddress('user@example.com');
  286. //$this->assertTrue($this->mail->send(), $this->mail->ErrorInfo);
  287. }
  288. /**
  289. * Test email address validation
  290. * Test addresses obtained from http://isemail.info
  291. * Some failing cases commented out that are apparently up for debate!
  292. */
  293. public function testValidate()
  294. {
  295. $validaddresses = array(
  296. 'first@iana.org',
  297. 'first.last@iana.org',
  298. '1234567890123456789012345678901234567890123456789012345678901234@iana.org',
  299. '"first\"last"@iana.org',
  300. '"first@last"@iana.org',
  301. '"first\last"@iana.org',
  302. 'first.last@[12.34.56.78]',
  303. 'first.last@[IPv6:::12.34.56.78]',
  304. 'first.last@[IPv6:1111:2222:3333::4444:12.34.56.78]',
  305. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.56.78]',
  306. 'first.last@[IPv6:::1111:2222:3333:4444:5555:6666]',
  307. 'first.last@[IPv6:1111:2222:3333::4444:5555:6666]',
  308. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666::]',
  309. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888]',
  310. 'first.last@x23456789012345678901234567890123456789012345678901234567890123.iana.org',
  311. 'first.last@3com.com',
  312. 'first.last@123.iana.org',
  313. '"first\last"@iana.org',
  314. 'first.last@[IPv6:1111:2222:3333::4444:5555:12.34.56.78]',
  315. 'first.last@[IPv6:1111:2222:3333::4444:5555:6666:7777]',
  316. 'first.last@example.123',
  317. 'first.last@com',
  318. '"Abc\@def"@iana.org',
  319. '"Fred\ Bloggs"@iana.org',
  320. '"Joe.\Blow"@iana.org',
  321. '"Abc@def"@iana.org',
  322. '"Fred Bloggs"@iana.org',
  323. 'user+mailbox@iana.org',
  324. 'customer/department=shipping@iana.org',
  325. '$A12345@iana.org',
  326. '!def!xyz%abc@iana.org',
  327. '_somename@iana.org',
  328. 'dclo@us.ibm.com',
  329. 'peter.piper@iana.org',
  330. '"Doug \"Ace\" L."@iana.org',
  331. 'test@iana.org',
  332. 'TEST@iana.org',
  333. '1234567890@iana.org',
  334. 'test+test@iana.org',
  335. 'test-test@iana.org',
  336. 't*est@iana.org',
  337. '+1~1+@iana.org',
  338. '{_test_}@iana.org',
  339. '"[[ test ]]"@iana.org',
  340. 'test.test@iana.org',
  341. '"test.test"@iana.org',
  342. 'test."test"@iana.org',
  343. '"test@test"@iana.org',
  344. 'test@123.123.123.x123',
  345. 'test@123.123.123.123',
  346. 'test@[123.123.123.123]',
  347. 'test@example.iana.org',
  348. 'test@example.example.iana.org',
  349. '"test\test"@iana.org',
  350. 'test@example',
  351. '"test\blah"@iana.org',
  352. '"test\blah"@iana.org',
  353. '"test\"blah"@iana.org',
  354. 'customer/department@iana.org',
  355. '_Yosemite.Sam@iana.org',
  356. '~@iana.org',
  357. '"Austin@Powers"@iana.org',
  358. 'Ima.Fool@iana.org',
  359. '"Ima.Fool"@iana.org',
  360. '"Ima Fool"@iana.org',
  361. '"first"."last"@iana.org',
  362. '"first".middle."last"@iana.org',
  363. '"first".last@iana.org',
  364. 'first."last"@iana.org',
  365. '"first"."middle"."last"@iana.org',
  366. '"first.middle"."last"@iana.org',
  367. '"first.middle.last"@iana.org',
  368. '"first..last"@iana.org',
  369. '"first\"last"@iana.org',
  370. 'first."mid\dle"."last"@iana.org',
  371. '"test blah"@iana.org',
  372. '(foo)cal(bar)@(baz)iamcal.com(quux)',
  373. 'cal@iamcal(woo).(yay)com',
  374. 'cal(woo(yay)hoopla)@iamcal.com',
  375. 'cal(foo\@bar)@iamcal.com',
  376. 'cal(foo\)bar)@iamcal.com',
  377. 'first().last@iana.org',
  378. 'pete(his account)@silly.test(his host)',
  379. 'c@(Chris\'s host.)public.example',
  380. 'jdoe@machine(comment). example',
  381. '1234 @ local(blah) .machine .example',
  382. 'first(abc.def).last@iana.org',
  383. 'first(a"bc.def).last@iana.org',
  384. 'first.(")middle.last(")@iana.org',
  385. 'first(abc\(def)@iana.org',
  386. 'first.last@x(1234567890123456789012345678901234567890123456789012345678901234567890).com',
  387. 'a(a(b(c)d(e(f))g)h(i)j)@iana.org',
  388. 'name.lastname@domain.com',
  389. 'a@b',
  390. 'a@bar.com',
  391. 'aaa@[123.123.123.123]',
  392. 'a@bar',
  393. 'a-b@bar.com',
  394. '+@b.c',
  395. '+@b.com',
  396. 'a@b.co-foo.uk',
  397. '"hello my name is"@stutter.com',
  398. '"Test \"Fail\" Ing"@iana.org',
  399. 'valid@about.museum',
  400. 'shaitan@my-domain.thisisminekthx',
  401. 'foobar@192.168.0.1',
  402. '"Joe\Blow"@iana.org',
  403. 'HM2Kinsists@(that comments are allowed)this.is.ok',
  404. 'user%uucp!path@berkeley.edu',
  405. 'first.last @iana.org',
  406. 'cdburgess+!#$%&\'*-/=?+_{}|~test@gmail.com',
  407. 'first.last@[IPv6:::a2:a3:a4:b1:b2:b3:b4]',
  408. 'first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3::]',
  409. 'first.last@[IPv6:::]',
  410. 'first.last@[IPv6:::b4]',
  411. 'first.last@[IPv6:::b3:b4]',
  412. 'first.last@[IPv6:a1::b4]',
  413. 'first.last@[IPv6:a1::]',
  414. 'first.last@[IPv6:a1:a2::]',
  415. 'first.last@[IPv6:0123:4567:89ab:cdef::]',
  416. 'first.last@[IPv6:0123:4567:89ab:CDEF::]',
  417. 'first.last@[IPv6:::a3:a4:b1:ffff:11.22.33.44]',
  418. 'first.last@[IPv6:::a2:a3:a4:b1:ffff:11.22.33.44]',
  419. 'first.last@[IPv6:a1:a2:a3:a4::11.22.33.44]',
  420. 'first.last@[IPv6:a1:a2:a3:a4:b1::11.22.33.44]',
  421. 'first.last@[IPv6:a1::11.22.33.44]',
  422. 'first.last@[IPv6:a1:a2::11.22.33.44]',
  423. 'first.last@[IPv6:0123:4567:89ab:cdef::11.22.33.44]',
  424. 'first.last@[IPv6:0123:4567:89ab:CDEF::11.22.33.44]',
  425. 'first.last@[IPv6:a1::b2:11.22.33.44]',
  426. 'test@test.com',
  427. 'test@xn--example.com',
  428. 'test@example.com'
  429. );
  430. $invalidaddresses = array(
  431. 'first.last@sub.do,com',
  432. 'first\@last@iana.org',
  433. '123456789012345678901234567890123456789012345678901234567890' .
  434. '@12345678901234567890123456789012345678901234 [...]',
  435. 'first.last',
  436. '12345678901234567890123456789012345678901234567890123456789012345@iana.org',
  437. '.first.last@iana.org',
  438. 'first.last.@iana.org',
  439. 'first..last@iana.org',
  440. '"first"last"@iana.org',
  441. '"""@iana.org',
  442. '"\"@iana.org',
  443. //'""@iana.org',
  444. 'first\@last@iana.org',
  445. 'first.last@',
  446. 'x@x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.x23456789.' .
  447. 'x23456789.x23456789.x23456789.x23 [...]',
  448. 'first.last@[.12.34.56.78]',
  449. 'first.last@[12.34.56.789]',
  450. 'first.last@[::12.34.56.78]',
  451. 'first.last@[IPv5:::12.34.56.78]',
  452. 'first.last@[IPv6:1111:2222:3333:4444:5555:12.34.56.78]',
  453. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:12.34.56.78]',
  454. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777]',
  455. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666:7777:8888:9999]',
  456. 'first.last@[IPv6:1111:2222::3333::4444:5555:6666]',
  457. 'first.last@[IPv6:1111:2222:333x::4444:5555]',
  458. 'first.last@[IPv6:1111:2222:33333::4444:5555]',
  459. 'first.last@-xample.com',
  460. 'first.last@exampl-.com',
  461. 'first.last@x234567890123456789012345678901234567890123456789012345678901234.iana.org',
  462. 'abc\@def@iana.org',
  463. 'abc\@iana.org',
  464. 'Doug\ \"Ace\"\ Lovell@iana.org',
  465. 'abc@def@iana.org',
  466. 'abc\@def@iana.org',
  467. 'abc\@iana.org',
  468. '@iana.org',
  469. 'doug@',
  470. '"qu@iana.org',
  471. 'ote"@iana.org',
  472. '.dot@iana.org',
  473. 'dot.@iana.org',
  474. 'two..dot@iana.org',
  475. '"Doug "Ace" L."@iana.org',
  476. 'Doug\ \"Ace\"\ L\.@iana.org',
  477. 'hello world@iana.org',
  478. //'helloworld@iana .org',
  479. 'gatsby@f.sc.ot.t.f.i.tzg.era.l.d.',
  480. 'test.iana.org',
  481. 'test.@iana.org',
  482. 'test..test@iana.org',
  483. '.test@iana.org',
  484. 'test@test@iana.org',
  485. 'test@@iana.org',
  486. '-- test --@iana.org',
  487. '[test]@iana.org',
  488. '"test"test"@iana.org',
  489. '()[]\;:,><@iana.org',
  490. 'test@.',
  491. 'test@example.',
  492. 'test@.org',
  493. 'test@12345678901234567890123456789012345678901234567890123456789012345678901234567890' .
  494. '12345678901234567890 [...]',
  495. 'test@[123.123.123.123',
  496. 'test@123.123.123.123]',
  497. 'NotAnEmail',
  498. '@NotAnEmail',
  499. '"test"blah"@iana.org',
  500. '.wooly@iana.org',
  501. 'wo..oly@iana.org',
  502. 'pootietang.@iana.org',
  503. '.@iana.org',
  504. 'Ima Fool@iana.org',
  505. 'phil.h\@\@ck@haacked.com',
  506. 'foo@[\1.2.3.4]',
  507. //'first."".last@iana.org',
  508. 'first\last@iana.org',
  509. 'Abc\@def@iana.org',
  510. 'Fred\ Bloggs@iana.org',
  511. 'Joe.\Blow@iana.org',
  512. 'first.last@[IPv6:1111:2222:3333:4444:5555:6666:12.34.567.89]',
  513. '{^c\@**Dog^}@cartoon.com',
  514. //'"foo"(yay)@(hoopla)[1.2.3.4]',
  515. 'cal(foo(bar)@iamcal.com',
  516. 'cal(foo)bar)@iamcal.com',
  517. 'cal(foo\)@iamcal.com',
  518. 'first(12345678901234567890123456789012345678901234567890)last@(1234567890123456789' .
  519. '01234567890123456789012 [...]',
  520. 'first(middle)last@iana.org',
  521. 'first(abc("def".ghi).mno)middle(abc("def".ghi).mno).last@(abc("def".ghi).mno)example' .
  522. '(abc("def".ghi).mno). [...]',
  523. 'a(a(b(c)d(e(f))g)(h(i)j)@iana.org',
  524. '.@',
  525. '@bar.com',
  526. '@@bar.com',
  527. 'aaa.com',
  528. 'aaa@.com',
  529. 'aaa@.123',
  530. 'aaa@[123.123.123.123]a',
  531. 'aaa@[123.123.123.333]',
  532. 'a@bar.com.',
  533. 'a@-b.com',
  534. 'a@b-.com',
  535. '-@..com',
  536. '-@a..com',
  537. 'invalid@about.museum-',
  538. 'test@...........com',
  539. '"Unicode NULL' . chr(0) . '"@char.com',
  540. 'Unicode NULL' . chr(0) . '@char.com',
  541. 'first.last@[IPv6::]',
  542. 'first.last@[IPv6::::]',
  543. 'first.last@[IPv6::b4]',
  544. 'first.last@[IPv6::::b4]',
  545. 'first.last@[IPv6::b3:b4]',
  546. 'first.last@[IPv6::::b3:b4]',
  547. 'first.last@[IPv6:a1:::b4]',
  548. 'first.last@[IPv6:a1:]',
  549. 'first.last@[IPv6:a1:::]',
  550. 'first.last@[IPv6:a1:a2:]',
  551. 'first.last@[IPv6:a1:a2:::]',
  552. 'first.last@[IPv6::11.22.33.44]',
  553. 'first.last@[IPv6::::11.22.33.44]',
  554. 'first.last@[IPv6:a1:11.22.33.44]',
  555. 'first.last@[IPv6:a1:::11.22.33.44]',
  556. 'first.last@[IPv6:a1:a2:::11.22.33.44]',
  557. 'first.last@[IPv6:0123:4567:89ab:cdef::11.22.33.xx]',
  558. 'first.last@[IPv6:0123:4567:89ab:CDEFF::11.22.33.44]',
  559. 'first.last@[IPv6:a1::a4:b1::b4:11.22.33.44]',
  560. 'first.last@[IPv6:a1::11.22.33]',
  561. 'first.last@[IPv6:a1::11.22.33.44.55]',
  562. 'first.last@[IPv6:a1::b211.22.33.44]',
  563. 'first.last@[IPv6:a1::b2::11.22.33.44]',
  564. 'first.last@[IPv6:a1::b3:]',
  565. 'first.last@[IPv6::a2::b4]',
  566. 'first.last@[IPv6:a1:a2:a3:a4:b1:b2:b3:]',
  567. 'first.last@[IPv6::a2:a3:a4:b1:b2:b3:b4]',
  568. 'first.last@[IPv6:a1:a2:a3:a4::b1:b2:b3:b4]'
  569. );
  570. $goodfails = array();
  571. foreach ($validaddresses as $address) {
  572. if (!PHPMailer::validateAddress($address)) {
  573. $goodfails[] = $address;
  574. }
  575. }
  576. $badpasses = array();
  577. foreach ($invalidaddresses as $address) {
  578. if (PHPMailer::validateAddress($address)) {
  579. $badpasses[] = $address;
  580. }
  581. }
  582. $err = '';
  583. if (count($goodfails) > 0) {
  584. $err .= "Good addresses that failed validation:\n";
  585. $err .= implode("\n", $goodfails);
  586. }
  587. if (count($badpasses) > 0) {
  588. if (!empty($err)) {
  589. $err .= "\n\n";
  590. }
  591. $err .= "Bad addresses that passed validation:\n";
  592. $err .= implode("\n", $badpasses);
  593. }
  594. $this->assertEmpty($err, $err);
  595. //For coverage
  596. $this->assertTrue(PHPMailer::validateAddress('test@example.com', 'auto'));
  597. $this->assertFalse(PHPMailer::validateAddress('test@example.com.', 'auto'));
  598. $this->assertTrue(PHPMailer::validateAddress('test@example.com', 'pcre'));
  599. $this->assertFalse(PHPMailer::validateAddress('test@example.com.', 'pcre'));
  600. $this->assertTrue(PHPMailer::validateAddress('test@example.com', 'pcre8'));
  601. $this->assertFalse(PHPMailer::validateAddress('test@example.com.', 'pcre8'));
  602. $this->assertTrue(PHPMailer::validateAddress('test@example.com', 'php'));
  603. $this->assertFalse(PHPMailer::validateAddress('test@example.com.', 'php'));
  604. $this->assertTrue(PHPMailer::validateAddress('test@example.com', 'noregex'));
  605. $this->assertFalse(PHPMailer::validateAddress('bad', 'noregex'));
  606. }
  607. /**
  608. * Try a plain message.
  609. */
  610. public function testWordWrap()
  611. {
  612. $this->Mail->WordWrap = 40;
  613. $my_body = 'Here is the main body of this message. It should ' .
  614. 'be quite a few lines. It should be wrapped at the ' .
  615. '40 characters. Make sure that it is.';
  616. $nBodyLen = strlen($my_body);
  617. $my_body .= "\n\nThis is the above body length: " . $nBodyLen;
  618. $this->Mail->Body = $my_body;
  619. $this->Mail->Subject .= ': Wordwrap';
  620. $this->buildBody();
  621. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  622. }
  623. /**
  624. * Try a plain message.
  625. */
  626. public function testLowPriority()
  627. {
  628. $this->Mail->Priority = 5;
  629. $this->Mail->Body = 'Here is the main body. There should be ' .
  630. 'a reply to address in this message.';
  631. $this->Mail->Subject .= ': Low Priority';
  632. $this->Mail->addReplyTo('nobody@nobody.com', 'Nobody (Unit Test)');
  633. $this->buildBody();
  634. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  635. }
  636. /**
  637. * Simple plain file attachment test.
  638. */
  639. public function testMultiplePlainFileAttachment()
  640. {
  641. $this->Mail->Body = 'Here is the text body';
  642. $this->Mail->Subject .= ': Plain + Multiple FileAttachments';
  643. if (!$this->Mail->addAttachment('../examples/images/phpmailer.png')) {
  644. $this->assertTrue(false, $this->Mail->ErrorInfo);
  645. return;
  646. }
  647. if (!$this->Mail->addAttachment(__FILE__, 'test.txt')) {
  648. $this->assertTrue(false, $this->Mail->ErrorInfo);
  649. return;
  650. }
  651. $this->buildBody();
  652. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  653. }
  654. /**
  655. * Simple plain string attachment test.
  656. */
  657. public function testPlainStringAttachment()
  658. {
  659. $this->Mail->Body = 'Here is the text body';
  660. $this->Mail->Subject .= ': Plain + StringAttachment';
  661. $sAttachment = 'These characters are the content of the ' .
  662. "string attachment.\nThis might be taken from a " .
  663. 'database or some other such thing. ';
  664. $this->Mail->addStringAttachment($sAttachment, 'string_attach.txt');
  665. $this->buildBody();
  666. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  667. }
  668. /**
  669. * Plain quoted-printable message.
  670. */
  671. public function testQuotedPrintable()
  672. {
  673. $this->Mail->Body = 'Here is the main body';
  674. $this->Mail->Subject .= ': Plain + Quoted-printable';
  675. $this->Mail->Encoding = 'quoted-printable';
  676. $this->buildBody();
  677. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  678. //Check that a quoted printable encode and decode results in the same as went in
  679. $t = file_get_contents(__FILE__); //Use this file as test content
  680. $this->assertEquals(
  681. $t,
  682. quoted_printable_decode($this->Mail->encodeQP($t)),
  683. 'Quoted-Printable encoding round-trip failed'
  684. );
  685. $this->assertEquals(
  686. $this->Mail->encodeQP($t),
  687. $this->Mail->encodeQPphp($t),
  688. 'Quoted-Printable BC wrapper failed'
  689. );
  690. }
  691. /**
  692. * Try a plain message.
  693. */
  694. public function testHtml()
  695. {
  696. $this->Mail->isHTML(true);
  697. $this->Mail->Subject .= ": HTML only";
  698. $this->Mail->Body = <<<EOT
  699. <html>
  700. <head>
  701. <title>HTML email test</title>
  702. </head>
  703. <body>
  704. <h1>PHPMailer does HTML!</h1>
  705. <p>This is a <strong>test message</strong> written in HTML.<br>
  706. Go to <a href="https://github.com/PHPMailer/PHPMailer/">https://github.com/PHPMailer/PHPMailer/</a>
  707. for new versions of PHPMailer.</p>
  708. <p>Thank you!</p>
  709. </body>
  710. </html>
  711. EOT;
  712. $this->buildBody();
  713. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  714. }
  715. /**
  716. * Test simple message builder and html2text converters
  717. */
  718. public function testMsgHTML()
  719. {
  720. $message = file_get_contents('../examples/contents.html');
  721. $this->Mail->CharSet = 'utf-8';
  722. $this->Mail->Body = '';
  723. $this->Mail->AltBody = '';
  724. $this->Mail->msgHTML($message, '../examples');
  725. $this->Mail->Subject .= ': msgHTML';
  726. $this->assertNotEmpty($this->Mail->Body, 'Body not set by msgHTML');
  727. $this->assertNotEmpty($this->Mail->AltBody, 'AltBody not set by msgHTML');
  728. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  729. //Again, using the advanced HTML to text converter
  730. $this->Mail->AltBody = '';
  731. $this->Mail->msgHTML($message, '../examples', true);
  732. $this->Mail->Subject .= ' + html2text advanced';
  733. $this->assertNotEmpty($this->Mail->AltBody, 'Advanced AltBody not set by msgHTML');
  734. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  735. }
  736. /**
  737. * Simple HTML and attachment test
  738. */
  739. public function testHTMLAttachment()
  740. {
  741. $this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.';
  742. $this->Mail->Subject .= ': HTML + Attachment';
  743. $this->Mail->isHTML(true);
  744. if (!$this->Mail->addAttachment(__FILE__, 'test_attach.txt')) {
  745. $this->assertTrue(false, $this->Mail->ErrorInfo);
  746. return;
  747. }
  748. //Make sure that trying to attach a nonexistent file fails
  749. $this->assertFalse($this->Mail->addAttachment(__FILE__ . md5(microtime()), 'nonexistent_file.txt'));
  750. $this->buildBody();
  751. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  752. }
  753. /**
  754. * An embedded attachment test.
  755. */
  756. public function testEmbeddedImage()
  757. {
  758. $this->Mail->Body = 'Embedded Image: <img alt="phpmailer" src="cid:my-attach">' .
  759. 'Here is an image!</a>';
  760. $this->Mail->Subject .= ': Embedded Image';
  761. $this->Mail->isHTML(true);
  762. if (!$this->Mail->addEmbeddedImage(
  763. '../examples/images/phpmailer.png',
  764. 'my-attach',
  765. 'phpmailer.png',
  766. 'base64',
  767. 'image/png'
  768. )
  769. ) {
  770. $this->assertTrue(false, $this->Mail->ErrorInfo);
  771. return;
  772. }
  773. $this->buildBody();
  774. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  775. //For code coverage
  776. $this->Mail->addEmbeddedImage('thisfiledoesntexist', 'xyz'); //Non-existent file
  777. $this->Mail->addEmbeddedImage(__FILE__, '123'); //Missing name
  778. }
  779. /**
  780. * An embedded attachment test.
  781. */
  782. public function testMultiEmbeddedImage()
  783. {
  784. $this->Mail->Body = 'Embedded Image: <img alt="phpmailer" src="cid:my-attach">' .
  785. 'Here is an image!</a>';
  786. $this->Mail->Subject .= ': Embedded Image + Attachment';
  787. $this->Mail->isHTML(true);
  788. if (!$this->Mail->addEmbeddedImage(
  789. '../examples/images/phpmailer.png',
  790. 'my-attach',
  791. 'phpmailer.png',
  792. 'base64',
  793. 'image/png'
  794. )
  795. ) {
  796. $this->assertTrue(false, $this->Mail->ErrorInfo);
  797. return;
  798. }
  799. if (!$this->Mail->addAttachment(__FILE__, 'test.txt')) {
  800. $this->assertTrue(false, $this->Mail->ErrorInfo);
  801. return;
  802. }
  803. $this->buildBody();
  804. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  805. }
  806. /**
  807. * Simple multipart/alternative test.
  808. */
  809. public function testAltBody()
  810. {
  811. $this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.';
  812. $this->Mail->AltBody = 'Here is the text body of this message. ' .
  813. 'It should be quite a few lines. It should be wrapped at the ' .
  814. '40 characters. Make sure that it is.';
  815. $this->Mail->WordWrap = 40;
  816. $this->addNote('This is a mulipart alternative email');
  817. $this->Mail->Subject .= ': AltBody + Word Wrap';
  818. $this->buildBody();
  819. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  820. }
  821. /**
  822. * Simple HTML and attachment test
  823. */
  824. public function testAltBodyAttachment()
  825. {
  826. $this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.';
  827. $this->Mail->AltBody = 'This is the text part of the email.';
  828. $this->Mail->Subject .= ': AltBody + Attachment';
  829. $this->Mail->isHTML(true);
  830. if (!$this->Mail->addAttachment(__FILE__, 'test_attach.txt')) {
  831. $this->assertTrue(false, $this->Mail->ErrorInfo);
  832. return;
  833. }
  834. $this->buildBody();
  835. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  836. if (is_writable('.')) {
  837. file_put_contents('message.txt', $this->Mail->createHeader() . $this->Mail->createBody());
  838. } else {
  839. $this->assertTrue(false, 'Could not write local file - check permissions');
  840. }
  841. }
  842. /**
  843. * iCal event test
  844. */
  845. public function testIcal()
  846. {
  847. $this->Mail->Body = 'This is the <strong>HTML</strong> part of the email.';
  848. $this->Mail->AltBody = 'This is the text part of the email.';
  849. $this->Mail->Subject .= ': iCal';
  850. $this->Mail->isHTML(true);
  851. $this->buildBody();
  852. require_once '../extras/EasyPeasyICS.php';
  853. $ICS = new EasyPeasyICS("PHPMailer test calendar");
  854. $ICS->addEvent(
  855. strtotime('tomorrow 10:00 Europe/Paris'),
  856. strtotime('tomorrow 11:00 Europe/Paris'),
  857. 'PHPMailer iCal test',
  858. 'A test of PHPMailer iCal support',
  859. 'https://github.com/PHPMailer/PHPMailer'
  860. );
  861. $this->Mail->Ical = $ICS->render(false);
  862. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  863. $this->Mail->Body = 'Embedded Image: <img alt="phpmailer" src="cid:my-attach">' .
  864. 'Here is an image!</a>.';
  865. $this->Mail->AltBody = 'This is the text part of the email.';
  866. $this->Mail->Subject .= ': iCal + inline';
  867. $this->Mail->isHTML(true);
  868. $this->Mail->addEmbeddedImage(
  869. '../examples/images/phpmailer.png',
  870. 'my-attach',
  871. 'phpmailer.png',
  872. 'base64',
  873. 'image/png'
  874. );
  875. $this->buildBody();
  876. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  877. }
  878. /**
  879. * Test sending multiple messages with separate connections
  880. */
  881. public function testMultipleSend()
  882. {
  883. $this->Mail->Body = 'Sending two messages without keepalive';
  884. $this->buildBody();
  885. $subject = $this->Mail->Subject;
  886. $this->Mail->Subject = $subject . ': SMTP 1';
  887. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  888. $this->Mail->Subject = $subject . ': SMTP 2';
  889. $this->Mail->Sender = 'blah@example.com';
  890. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  891. }
  892. /**
  893. * Test sending using SendMail
  894. */
  895. public function testSendmailSend()
  896. {
  897. $this->Mail->Body = 'Sending via sendmail';
  898. $this->buildBody();
  899. $subject = $this->Mail->Subject;
  900. $this->Mail->Subject = $subject . ': sendmail';
  901. $this->Mail->isSendmail();
  902. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  903. }
  904. /**
  905. * Test sending using Qmail
  906. */
  907. public function testQmailSend()
  908. {
  909. //Only run if we have qmail installed
  910. if (file_exists('/var/qmail/bin/qmail-inject')) {
  911. $this->Mail->Body = 'Sending via qmail';
  912. $this->BuildBody();
  913. $subject = $this->Mail->Subject;
  914. $this->Mail->Subject = $subject . ': qmail';
  915. $this->Mail->IsQmail();
  916. $this->assertTrue($this->Mail->Send(), $this->Mail->ErrorInfo);
  917. } else {
  918. $this->markTestSkipped('Qmail is not installed');
  919. }
  920. }
  921. /**
  922. * Test sending using PHP mail() function
  923. */
  924. public function testMailSend()
  925. {
  926. $sendmail = ini_get('sendmail_path');
  927. if (strpos($sendmail, '/') === false) { //No path in sendmail_path
  928. ini_set('sendmail_path', '/usr/sbin/sendmail -t -i ');
  929. }
  930. $this->Mail->Body = 'Sending via mail()';
  931. $this->buildBody();
  932. $this->Mail->Subject = $this->Mail->Subject . ': mail()';
  933. $this->Mail->isMail();
  934. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  935. }
  936. /**
  937. * Test sending an empty body
  938. */
  939. public function testEmptyBody()
  940. {
  941. $this->buildBody();
  942. $this->Mail->Body = '';
  943. $this->Mail->Subject = $this->Mail->Subject . ': Empty Body';
  944. $this->Mail->isMail();
  945. $this->Mail->AllowEmpty = true;
  946. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  947. $this->Mail->AllowEmpty = false;
  948. $this->assertFalse($this->Mail->send(), $this->Mail->ErrorInfo);
  949. }
  950. /**
  951. * Test keepalive (sending multiple messages in a single connection)
  952. */
  953. public function testSmtpKeepAlive()
  954. {
  955. $this->Mail->Body = 'This was done using the SMTP keep-alive.';
  956. $this->buildBody();
  957. $subject = $this->Mail->Subject;
  958. $this->Mail->SMTPKeepAlive = true;
  959. $this->Mail->Subject = $subject . ': SMTP keep-alive 1';
  960. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  961. $this->Mail->Subject = $subject . ': SMTP keep-alive 2';
  962. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  963. $this->Mail->smtpClose();
  964. }
  965. /**
  966. * Tests this denial of service attack:
  967. * http://www.cybsec.com/vuln/PHPMailer-DOS.pdf
  968. */
  969. public function testDenialOfServiceAttack()
  970. {
  971. $this->Mail->Body = 'This should no longer cause a denial of service.';
  972. $this->buildBody();
  973. $this->Mail->Subject = substr(str_repeat('0123456789', 100), 0, 998);
  974. $this->assertTrue($this->Mail->send(), $this->Mail->ErrorInfo);
  975. }
  976. /**
  977. * Tests this denial of service attack:
  978. * https://sourceforge.net/p/phpmailer/bugs/383/
  979. * According to the ticket, this should get stuck in a loop, though I can't make it happen.
  980. */
  981. public function testDenialOfServiceAttack2()
  982. {
  983. //Encoding name longer than 68 chars
  984. $this->Mail->Encoding = '1234567890123456789012345678901234567890123456789012345678901234567890';
  985. //Call wrapText with a zero length value
  986. $this->Mail->wrapText(str_repeat('This should no longer cause a denial of service. ', 30), 0);
  987. }
  988. /**
  989. * Test error handling
  990. */
  991. public function testError()
  992. {
  993. $this->Mail->Subject .= ': This should be sent';
  994. $this->buildBody();
  995. $this->Mail->clearAllRecipients(); // no addresses should cause an error
  996. $this->assertTrue($this->Mail->isError() == false, 'Error found');
  997. $this->assertTrue($this->Mail->send() == false, 'send succeeded');
  998. $this->assertTrue($this->Mail->isError(), 'No error found');
  999. $this->assertEquals('You must provide at least one recipient email address.', $this->Mail->ErrorInfo);
  1000. $this->Mail->addAddress($_REQUEST['mail_to']);
  1001. $this->assertTrue($this->Mail->send(), 'send failed');
  1002. }
  1003. /**
  1004. * Test addressing
  1005. */
  1006. public function testAddressing()
  1007. {
  1008. $this->assertFalse($this->Mail->addAddress(''), 'Empty address accepted');
  1009. $this->assertFalse($this->Mail->addAddress('', 'Nobody'), 'Empty address with name accepted');
  1010. $this->assertFalse($this->Mail->addAddress('a@example..com'), 'Invalid address accepted');
  1011. $this->assertTrue($this->Mail->addAddress('a@example.com'), 'Addressing failed');
  1012. $this->assertFalse($this->Mail->addAddress('a@example.com'), 'Duplicate addressing failed');
  1013. $this->assertTrue($this->Mail->addCC('b@example.com'), 'CC addressing failed');
  1014. $this->assertFalse($this->Mail->addCC('b@example.com'), 'CC duplicate addressing failed');
  1015. $this->assertFalse($this->Mail->addCC('a@example.com'), 'CC duplicate addressing failed (2)');
  1016. $this->assertTrue($this->Mail->addBCC('c@example.com'), 'BCC addressing failed');
  1017. $this->assertFalse($this->Mail->addBCC('c@example.com'), 'BCC duplicate addressing failed');
  1018. $this->assertFalse($this->Mail->addBCC('a@example.com'), 'BCC duplicate addressing failed (2)');
  1019. $this->assertTrue($this->Mail->addReplyTo('a@example.com'), 'Replyto Addressing failed');
  1020. $this->assertFalse($this->Mail->addReplyTo('a@example..com'), 'Invalid Replyto address accepted');
  1021. $this->assertTrue($this->Mail->setFrom('a@example.com', 'some name'), 'setFrom failed');
  1022. $this->assertFalse($this->Mail->setFrom('a@example.com.', 'some name'), 'setFrom accepted invalid address');
  1023. $this->Mail->Sender = '';
  1024. $this->Mail->setFrom('a@example.com', 'some name', true);
  1025. $this->assertEquals($this->Mail->Sender, 'a@example.com', 'setFrom failed to set sender');
  1026. $this->Mail->Sender = '';
  1027. $this->Mail->setFrom('a@example.com', 'some name', false);
  1028. $this->assertEquals($this->Mail->Sender, '', 'setFrom should not have set sender');
  1029. $this->Mail->clearCCs();
  1030. $this->Mail->clearBCCs();
  1031. $this->Mail->clearReplyTos();
  1032. }
  1033. /**
  1034. * Test address escaping
  1035. */
  1036. public function testAddressEscaping()
  1037. {
  1038. $this->Mail->Subject .= ': Address escaping';
  1039. $this->Mail->clearAddresses();
  1040. $this->Mail->addAddress('foo@example.com', 'Tim "The Book" O\'Reilly');
  1041. $this->Mail->Body = 'Test correct escaping of quotes in addresses.';
  1042. $this->buildBody();
  1043. $this->Mail->preSend();
  1044. $b = $this->Mail->getSentMIMEMessage();
  1045. $this->assertTrue((strpos($b, 'To: "Tim \"The Book\" O\'Reilly" <foo@example.com>') !== false));
  1046. }
  1047. /**
  1048. * Test BCC-only addressing
  1049. */
  1050. public function testBCCAddressing()
  1051. {
  1052. $this->Mail->Subject .= ': BCC-only addressing';
  1053. $this->buildBody();
  1054. $this->Mail->clearAllRecipients();
  1055. $this->assertTrue($this->Mail->addBCC('a@example.com'), 'BCC addressing failed');
  1056. $this->assertTrue($this->Mail->send(), 'send failed');
  1057. }
  1058. /**
  1059. * Encoding and charset tests
  1060. */
  1061. public function testEncodings()
  1062. {
  1063. $this->Mail->CharSet = 'iso-8859-1';
  1064. $this->assertEquals(
  1065. '=A1Hola!_Se=F1or!',
  1066. $this->Mail->encodeQ("\xa1Hola! Se\xf1or!", 'text'),
  1067. 'Q Encoding (text) failed'
  1068. );
  1069. $this->assertEquals(
  1070. '=A1Hola!_Se=F1or!',
  1071. $this->Mail->encodeQ("\xa1Hola! Se\xf1or!", 'comment'),
  1072. 'Q Encoding (comment) failed'
  1073. );
  1074. $this->assertEquals(
  1075. '=A1Hola!_Se=F1or!',
  1076. $this->Mail->encodeQ("\xa1Hola! Se\xf1or!", 'phrase'),
  1077. 'Q Encoding (phrase) failed'
  1078. );
  1079. $this->Mail->CharSet = 'UTF-8';
  1080. $this->assertEquals(
  1081. '=C2=A1Hola!_Se=C3=B1or!',
  1082. $this->Mail->encodeQ("\xc2\xa1Hola! Se\xc3\xb1or!", 'text'),
  1083. 'Q Encoding (text) failed'
  1084. );
  1085. //Strings containing '=' are a special case
  1086. $this->assertEquals(
  1087. 'Nov=C3=A1=3D',
  1088. $this->Mail->encodeQ("Nov\xc3\xa1=", 'text'),
  1089. 'Q Encoding (text) failed 2'
  1090. );
  1091. }
  1092. public function testBase64()
  1093. {
  1094. $this->Mail->Subject .= ': Base-64 encoding';
  1095. $this->Mail->Encoding = 'base64';
  1096. $this->buildBody();
  1097. $this->assertTrue($this->Mail->send(), 'Base64 encoding failed');
  1098. }
  1099. /**
  1100. * S/MIME Signing tests
  1101. */
  1102. public function testSigning()
  1103. {
  1104. $this->Mail->Subject .= ': S/MIME signing';
  1105. $this->Mail->Body = 'This message is S/MIME signed.';
  1106. $this->buildBody();
  1107. $dn = array(
  1108. 'countryName' => 'UK',
  1109. 'stateOrProvinceName' => 'Here',
  1110. 'localityName' => 'There',
  1111. 'organizationName' => 'PHP',
  1112. 'organizationalUnitName' => 'PHPMailer',
  1113. 'commonName' => 'PHPMailer Test',
  1114. 'emailAddress' => 'phpmailer@example.com'
  1115. );
  1116. $password = 'password';
  1117. $certfile = 'certfile.txt';
  1118. $keyfile = 'keyfile.txt';
  1119. //Make a new key pair
  1120. $pk = openssl_pkey_new();
  1121. //Create a certificate signing request
  1122. $csr = openssl_csr_new($dn, $pk);
  1123. //Create a self-signed cert
  1124. $cert = openssl_csr_sign($csr, null, $pk, 1);
  1125. //Save the cert
  1126. openssl_x509_export($cert, $certout);
  1127. file_put_contents($certfile, $certout);
  1128. //Save the key
  1129. openssl_pkey_export($pk, $pkeyout, $password);
  1130. file_put_contents($keyfile, $pkeyout);
  1131. $this->Mail->sign(
  1132. $certfile,
  1133. $keyfile,
  1134. $password
  1135. );
  1136. $this->assertTrue($this->Mail->send(), 'S/MIME signing failed');
  1137. unlink($certfile);
  1138. unlink($keyfile);
  1139. }
  1140. /**
  1141. * DKIM Signing tests
  1142. */
  1143. public function testDKIM()
  1144. {
  1145. $this->Mail->Subject .= ': DKIM signing';
  1146. $this->Mail->Body = 'This message is DKIM signed.';
  1147. $this->buildBody();
  1148. $privatekeyfile = 'dkim_private.key';
  1149. //Make a new key pair
  1150. //(2048 bits is the recommended minimum key length -
  1151. //gmail won't accept less than 1024 bits)
  1152. $pk = openssl_pkey_new(
  1153. array(
  1154. 'private_key_bits' => 2048,
  1155. 'private_key_type' => OPENSSL_KEYTYPE_RSA
  1156. )
  1157. );
  1158. openssl_pkey_export_to_file($pk, $privatekeyfile);
  1159. $this->Mail->DKIM_domain = 'example.com';
  1160. $this->Mail->DKIM_private = $privatekeyfile;
  1161. $this->Mail->DKIM_selector = 'phpmailer';
  1162. $this->Mail->DKIM_passphrase = ''; //key is not encrypted
  1163. $this->assertTrue($this->Mail->send(), 'DKIM signed mail failed');
  1164. unlink($privatekeyfile);
  1165. }
  1166. /**
  1167. * Test line break reformatting
  1168. */
  1169. public function testLineBreaks()
  1170. {
  1171. $unixsrc = "hello\nWorld\nAgain\n";
  1172. $macsrc = "hello\rWorld\rAgain\r";
  1173. $windowssrc = "hello\r\nWorld\r\nAgain\r\n";
  1174. $mixedsrc = "hello\nWorld\rAgain\r\n";
  1175. $target = "hello\r\nWorld\r\nAgain\r\n";
  1176. $this->assertEquals($target, PHPMailer::normalizeBreaks($unixsrc), 'UNIX break reformatting failed');
  1177. $this->assertEquals($target, PHPMailer::normalizeBreaks($macsrc), 'Mac break reformatting failed');
  1178. $this->assertEquals($target, PHPMailer::normalizeBreaks($windowssrc), 'Windows break reformatting failed');
  1179. $this->assertEquals($target, PHPMailer::normalizeBreaks($mixedsrc), 'Mixed break reformatting failed');
  1180. }
  1181. /**
  1182. * Test setting and retrieving message ID
  1183. */
  1184. public function testMessageID()
  1185. {
  1186. $this->Mail->Body = 'Test message ID.';
  1187. $id = md5(12345);
  1188. $this->Mail->MessageID = $id;
  1189. $this->buildBody();
  1190. $this->Mail->preSend();
  1191. $lastid = $this->Mail->getLastMessageID();
  1192. $this->assertEquals($lastid, $id, 'Custom Message ID mismatch');
  1193. }
  1194. /**
  1195. * Miscellaneous calls to improve test coverage and some small tests
  1196. */
  1197. public function testMiscellaneous()
  1198. {
  1199. $this->assertEquals('application/pdf', PHPMailer::_mime_types('pdf'), 'MIME TYPE lookup failed');
  1200. $this->Mail->addCustomHeader('SomeHeader: Some Value');
  1201. $this->Mail->clearCustomHeaders();
  1202. $this->Mail->clearAttachments();
  1203. $this->Mail->isHTML(false);
  1204. $this->Mail->isSMTP();
  1205. $this->Mail->isMail();
  1206. $this->Mail->isSendmail();
  1207. $this->Mail->isQmail();
  1208. $this->Mail->setLanguage('fr');
  1209. $this->Mail->Sender = '';
  1210. $this->Mail->createHeader();
  1211. $this->assertFalse($this->Mail->set('x', 'y'), 'Invalid property set succeeded');
  1212. $this->assertTrue($this->Mail->set('Timeout', 11), 'Valid property set failed');
  1213. //Test pathinfo
  1214. $a = '/mnt/files/飛兒樂 團光茫.mp3';
  1215. $q = PHPMailer::mb_pathinfo($a);
  1216. $this->assertEquals($q['dirname'], '/mnt/files', 'UNIX dirname not matched');
  1217. $this->assertEquals($q['basename'], '飛兒樂 團光茫.mp3', 'UNIX basename not matched');
  1218. $this->assertEquals($q['extension'], 'mp3', 'UNIX extension not matched');
  1219. $this->assertEquals($q['filename'], '飛兒樂 團光茫', 'UNIX filename not matched');
  1220. $this->assertEquals(
  1221. PHPMailer::mb_pathinfo($a, PATHINFO_DIRNAME),
  1222. '/mnt/files',
  1223. 'Dirname path element not matched'
  1224. );
  1225. $this->assertEquals(PHPMailer::mb_pathinfo($a, 'filename'), '飛兒樂 團光茫', 'Filename path element not matched');
  1226. $a = 'c:\mnt\files\飛兒樂 團光茫.mp3';
  1227. $q = PHPMailer::mb_pathinfo($a);
  1228. $this->assertEquals($q['dirname'], 'c:\mnt\files', 'Windows dirname not matched');
  1229. $this->assertEquals($q['basename'], '飛兒樂 團光茫.mp3', 'Windows basename not matched');
  1230. $this->assertEquals($q['extension'], 'mp3', 'Windows extension not matched');
  1231. $this->assertEquals($q['filename'], '飛兒樂 團光茫', 'Windows filename not matched');
  1232. }
  1233. /**
  1234. * Use a fake POP3 server to test POP-before-SMTP auth
  1235. * With a known-good login
  1236. */
  1237. public function testPopBeforeSmtpGood()
  1238. {
  1239. //Start a fake POP server
  1240. $pid = shell_exec('nohup ./runfakepopserver.sh >/dev/null 2>/dev/null & printf "%u" $!');
  1241. $this->pids[] = $pid;
  1242. sleep(2);
  1243. //Test a known-good login
  1244. $this->assertTrue(
  1245. POP3::popBeforeSmtp('localhost', 1100, 10, 'user', 'test', 0),
  1246. 'POP before SMTP failed'
  1247. );
  1248. //Kill the fake server
  1249. shell_exec('kill -TERM '.escapeshellarg($pid));
  1250. sleep(2);
  1251. }
  1252. /**
  1253. * Use a fake POP3 server to test POP-before-SMTP auth
  1254. * With a known-bad login
  1255. */
  1256. public function testPopBeforeSmtpBad()
  1257. {
  1258. //Start a fake POP server on a different port
  1259. //so we don't inadvertently connect to the previous instance
  1260. $pid = shell_exec('nohup ./runfakepopserver.sh 1101 >/dev/null 2>/dev/null & printf "%u" $!');
  1261. $this->pids[] = $pid;
  1262. sleep(2);
  1263. //Test a known-bad login
  1264. $this->assertFalse(
  1265. POP3::popBeforeSmtp('localhost', 1101, 10, 'user', 'xxx', 0),
  1266. 'POP before SMTP should have failed'
  1267. );
  1268. shell_exec('kill -TERM '.escapeshellarg($pid));
  1269. sleep(2);
  1270. }
  1271. /**
  1272. * Test SMTP host connections.
  1273. * This