Permalink
Browse files

slusarz (Michael Slusarz)

Added a patch that should fix this problem, and fixes the problem where
the previous code was counting escaped quotes inside of quoted string.
RFC 822 does not require that quotes be closed inside the string, so
these quotes need to be ignored.

Bug: #9137


git-svn-id: http://svn.php.net/repository/pear/packages/Mail/trunk@260832 c90b9560-bf6c-de11-be94-00142212c4b1
  • Loading branch information...
1 parent c7c6aa8 commit 843f9a01d1d6c0efa1a04b3e9ad6289f0055b148 Chuck Hagenbuch committed Jun 6, 2008
Showing with 65 additions and 9 deletions.
  1. +26 −9 Mail/RFC822.php
  2. +4 −0 tests/9137.phpt
  3. +35 −0 tests/9137_2.phpt
View
@@ -342,22 +342,39 @@ function _splitCheck($parts, $char)
}
/**
- * Checks if a string has an unclosed quotes or not.
+ * Checks if a string has unclosed quotes or not.
*
* @access private
- * @param string $string The string to check.
- * @return boolean True if there are unclosed quotes inside the string, false otherwise.
+ * @param string $string The string to check.
+ * @return boolean True if there are unclosed quotes inside the string,
+ * false otherwise.
*/
function _hasUnclosedQuotes($string)
{
- $string = explode('"', $string);
- $string_cnt = count($string);
+ $string = trim($string);
+ $iMax = strlen($string);
+ $in_quote = false;
+ $i = $slashes = 0;
+
+ for (; $i < $iMax; ++$i) {
+ switch ($string[$i]) {
+ case '\\':
+ ++$slashes;
+ break;
+
+ case '"':
+ if ($slashes % 2 == 0) {
+ $in_quote = !$in_quote;
+ }
+ // Fall through to default action below.
- for ($i = 0; $i < (count($string) - 1); $i++)
- if (substr($string[$i], -1) == '\\')
- $string_cnt--;
+ default:
+ $slashes = 0;
+ break;
+ }
+ }
- return ($string_cnt % 2 === 0);
+ return $in_quote;
}
/**
View
@@ -9,6 +9,8 @@ require_once 'PEAR.php';
$addresses = array(
array('name' => 'John Doe', 'email' => 'test@example.com'),
array('name' => 'John Doe\\', 'email' => 'test@example.com'),
+ array('name' => 'John "Doe', 'email' => 'test@example.com'),
+ array('name' => 'John "Doe\\', 'email' => 'test@example.com'),
);
for ($i = 0; $i < count($addresses); $i++) {
@@ -27,3 +29,5 @@ for ($i = 0; $i < count($addresses); $i++) {
--EXPECT--
"John Doe" <test@example.com> :: Parsed
"John Doe\\" <test@example.com> :: Parsed
+"John \"Doe" <test@example.com> :: Parsed
+"John \"Doe\\" <test@example.com> :: Parsed
View
@@ -0,0 +1,35 @@
+--TEST--
+Mail: Test for bug #9137, take 2
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . '/../Mail/RFC822.php';
+require_once 'PEAR.php';
+
+$addresses = array(
+ array('raw' => '"John Doe" <test@example.com>'),
+ array('raw' => '"John Doe' . chr(92) . '" <test@example.com>'),
+ array('raw' => '"John Doe' . chr(92) . chr(92) . '" <test@example.com>'),
+ array('raw' => '"John Doe' . chr(92) . chr(92) . chr(92) . '" <test@example.com>'),
+ array('raw' => '"John Doe' . chr(92) . chr(92) . chr(92) . chr(92) . '" <test@example.com>'),
+ array('raw' => '"John Doe <test@example.com>'),
+);
+
+for ($i = 0; $i < count($addresses); $i++) {
+ // construct the address
+ $address = $addresses[$i]['raw'];
+ $parsedAddresses = Mail_RFC822::parseAddressList($address);
+ if (PEAR::isError($parsedAddresses)) {
+ echo $address." :: Failed to validate\n";
+ } else {
+ echo $address." :: Parsed\n";
+ }
+}
+
+--EXPECT--
+"John Doe" <test@example.com> :: Parsed
+"John Doe\" <test@example.com> :: Failed to validate
+"John Doe\\" <test@example.com> :: Parsed
+"John Doe\\\" <test@example.com> :: Failed to validate
+"John Doe\\\\" <test@example.com> :: Parsed
+"John Doe <test@example.com> :: Failed to validate

0 comments on commit 843f9a0

Please sign in to comment.