diff --git a/include/pear/Mail/mimeDecode.php b/include/pear/Mail/mimeDecode.php index 1f7d412d4b44b8c4fadff9497c61e159af4a7cd3..f2a768005e1ec4fdccf57a5e523c2e643a224e74 100644 --- a/include/pear/Mail/mimeDecode.php +++ b/include/pear/Mail/mimeDecode.php @@ -405,10 +405,9 @@ class Mail_mimeDecode extends PEAR function _splitBodyHeader(&$input) { // The headers should end within the first 500k of the email... - $to_check = substr($input, 0, 500<<10); - if (preg_match("/^.*?(\r?\n\r?\n)(.)/s", $to_check, $match, PREG_OFFSET_CAPTURE)) { + if (preg_match("/^.*?(\r?\n\r?\n)(.)/s", $input, $match, PREG_OFFSET_CAPTURE)) { return array(substr($input, 0, $match[1][1]), - substr($input, $match[2][1])); + new StringView($input, $match[2][1])); } $this->_error = 'Could not split header and body'; return false; @@ -520,6 +519,9 @@ class Mail_mimeDecode extends PEAR $boundary = $bs_possible; } + if ($input instanceof StringView) + return $input->split('--' . $boundary); + $tmp = explode('--' . $boundary, $input); for ($i = 1; $i < count($tmp) - 1; $i++) { @@ -867,3 +869,44 @@ class Mail_mimeDecode extends PEAR } } // End of class + +class StringView { + var $string; + var $start; + var $end; + + function __construct(&$string, $start=0, $end=false) { + $this->string = &$string; + $this->start = $start; + $this->end = $end; + } + + function __toString() { + return $this->end + ? substr($this->string, $this->start, $this->end - $this->start) + : substr($this->string, $this->start); + } + + function split($boundary) { + $matches = array(); + if (!preg_match_all('/^' . preg_quote($boundary) . '/m', $this->string, + $matches, PREG_OFFSET_CAPTURE, $this->start)) + return array(); + + $windows = array(); + foreach ($matches[0] as $i => $m) { + $start = $m[1] + strlen($m[0]); + // Enforce local window + if ($i > 0) + $windows[$i-1]['stop'] = min($this->end ?: $m[1], $m[1]); + if ($this->end && $start > $this->end) + break; + $windows[$i]['start'] = $m[1] + strlen($m[0]); + } + $parts = array(); + foreach ($windows as $w) { + $parts[] = new StringView($this->string, $w['start'], @$w['stop'] ?: false); + } + return $parts; + } +}