1<?php 2/** 3 * Copyright 2013-2017 Horde LLC (http://www.horde.org/) 4 * 5 * See the enclosed file COPYING for license information (LGPL). If you 6 * did not receive this file, see http://www.horde.org/licenses/lgpl21. 7 * 8 * @category Horde 9 * @copyright 2013-2017 Horde LLC 10 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 11 * @package Smtp 12 */ 13 14/** 15 * Stream filter to escape output to the SMTP DATA command (RFC 5321 16 * [4.1.1.4]). 17 * 18 * @author Michael Slusarz <slusarz@horde.org> 19 * @category Horde 20 * @copyright 2013-2017 Horde LLC 21 * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 22 * @package Smtp 23 */ 24class Horde_Smtp_Filter_Data extends php_user_filter 25{ 26 /** 27 * Last character. 28 * 29 * @var string 30 */ 31 private $_last = null; 32 33 /** 34 * @see stream_filter_register() 35 */ 36 public function filter($in, $out, &$consumed, $closing) 37 { 38 while ($bucket = stream_bucket_make_writeable($in)) { 39 $consumed += $bucket->datalen; 40 41 // Handle split EOL in the next data bucket. 42 if ($bucket->data[$bucket->datalen - 1] === "\r") { 43 $bucket->data = substr($bucket->data, 0, -1); 44 } 45 46 // If the first character is '.', need to check if it has to be 47 // doubled. 48 if (($bucket->data[0] === '.') && 49 (is_null($this->_last) || ($this->_last === "\n"))) { 50 $bucket->data = '.' . $bucket->data; 51 } 52 53 // EOLs need to be CRLF; double leading periods. 54 $bucket->data = str_replace( 55 array("\r\n", "\r", "\n", "\n."), 56 array("\n", "\n", "\r\n", "\n.."), 57 $bucket->data 58 ); 59 60 $this->_last = substr($bucket->data, -1); 61 62 stream_bucket_append($out, $bucket); 63 } 64 65 return PSFS_PASS_ON; 66 } 67 68} 69