Author: Derick Rethans
Date: 2007-05-04 11:20:31 +0200 (Fri, 04 May 2007)
New Revision: 5037

Log:
- Implemented enhancement 10340: More selective encoding of mail headers.
#- This of course changes some of the expected output of tests
#- I also found that the testSubjectWithUtf8 test was actually still using
#  iso-8859-1, so I fixed that one as well.

Modified:
   trunk/Mail/ChangeLog
   trunk/Mail/src/mail.php
   trunk/Mail/src/tools.php
   trunk/Mail/tests/mail_test.php
   trunk/Mail/tests/tools_test.php

Modified: trunk/Mail/ChangeLog
===================================================================
--- trunk/Mail/ChangeLog        2007-05-04 07:53:03 UTC (rev 5036)
+++ trunk/Mail/ChangeLog        2007-05-04 09:20:31 UTC (rev 5037)
@@ -37,6 +37,7 @@
   can ignore the notices thrown by iconv in their own conversion function.
 - Implemented feature request #10682: The IMAP PEEK command is now supported
   through the top() method.
+- Implemented enhancement 10340: More selective encoding of mail headers.
 
 
 1.2.1 - [RELEASEDATE]

Modified: trunk/Mail/src/mail.php
===================================================================
--- trunk/Mail/src/mail.php     2007-05-04 07:53:03 UTC (rev 5036)
+++ trunk/Mail/src/mail.php     2007-05-04 09:20:31 UTC (rev 5037)
@@ -331,22 +331,37 @@
         }
 
         // build subject header
-        if ( $this->subjectCharset !== 'us-ascii' )
+        switch ( strtolower( $this->subjectCharset ) )
         {
-            $preferences = array(
-                'input-charset' => $this->subjectCharset,
-                'output-charset' => $this->subjectCharset,
-                'line-length' => ezcMailHeaderFolder::getLimit(),
-                'scheme' => 'B',
-                'line-break-chars' => ezcMailTools::lineBreak()
-            );
-            $subject = iconv_mime_encode( 'dummy', $this->subject, 
$preferences );
-            $this->setHeader( 'Subject', substr( $subject, 7 ) ); // "dummy: " 
+ 1
+            case 'us-ascii':
+                $this->setHeader( 'Subject', ezcMailHeaderFolder::foldAny( 
$this->subject ) );
+                break;
+
+            case 'iso-8859-1': case 'iso-8859-2': case 'iso-8859-3': case 
'iso-8859-4':
+            case 'iso-8859-5': case 'iso-8859-6': case 'iso-8859-7': case 
'iso-8859-8':
+            case 'iso-8859-9': case 'iso-8859-10': case 'iso-8859-11': case 
'iso-8859-12':
+            case 'iso-8859-13': case 'iso-8859-14': case 'iso-8859-15' :case 
'iso-8859-16':
+            case 'windows-1250': case 'windows-1251': case 'windows-1252':
+            case 'utf-8':
+                if ( strpbrk( $this->subject, 
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
 ) === false )
+                {
+                    $this->setHeader( 'Subject', ezcMailHeaderFolder::foldAny( 
$this->subject ) );
+                    break;
+                }
+                // break intentionally missing
+
+            default:
+                $preferences = array(
+                    'input-charset' => $this->subjectCharset,
+                    'output-charset' => $this->subjectCharset,
+                    'line-length' => ezcMailHeaderFolder::getLimit(),
+                    'scheme' => 'Q',
+                    'line-break-chars' => ezcMailTools::lineBreak()
+                );
+                $subject = iconv_mime_encode( 'dummy', $this->subject, 
$preferences );
+                $this->setHeader( 'Subject', substr( $subject, 7 ) ); // 
"dummy: " + 1
+                break;
         }
-        else
-        {
-            $this->setHeader( 'Subject', ezcMailHeaderFolder::foldAny( 
$this->subject ) );
-        }
 
         $this->setHeader( 'MIME-Version', '1.0' );
         $this->setHeader( 'User-Agent', 'eZ components' );

Modified: trunk/Mail/src/tools.php
===================================================================
--- trunk/Mail/src/tools.php    2007-05-04 07:53:03 UTC (rev 5036)
+++ trunk/Mail/src/tools.php    2007-05-04 09:20:31 UTC (rev 5037)
@@ -64,22 +64,37 @@
     {
         if ( $item->name !== '' )
         {
-            if ( $item->charset !== 'us-ascii' )
+            switch ( strtolower( $item->charset ) )
             {
-                $preferences = array(
-                    'input-charset' => $item->charset,
-                    'output-charset' => $item->charset,
-                    'scheme' => 'B',
-                    'line-break-chars' => ezcMailTools::lineBreak()
-                );
-                $name = iconv_mime_encode( 'dummy', $item->name, $preferences 
);
-                $name = substr( $name, 7 ); // "dummy: " + 1
-                $text = $name . ' <' . $item->email . '>';
+                case 'us-ascii':
+                    $text = $item->name . ' <' . $item->email . '>';
+                    break;
+
+                case 'iso-8859-1': case 'iso-8859-2': case 'iso-8859-3': case 
'iso-8859-4':
+                case 'iso-8859-5': case 'iso-8859-6': case 'iso-8859-7': case 
'iso-8859-8':
+                case 'iso-8859-9': case 'iso-8859-10': case 'iso-8859-11': 
case 'iso-8859-12':
+                case 'iso-8859-13': case 'iso-8859-14': case 'iso-8859-15' 
:case 'iso-8859-16':
+                case 'windows-1250': case 'windows-1251': case 'windows-1252':
+                case 'utf-8':
+                    if ( strpbrk( $item->name, 
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff"
 ) === false )
+                    {
+                        $text = $item->name . ' <' . $item->email . '>';
+                        break;
+                    }
+                    // break intentionally missing
+
+                default:
+                    $preferences = array(
+                        'input-charset' => $item->charset,
+                        'output-charset' => $item->charset,
+                        'scheme' => 'Q',
+                        'line-break-chars' => ezcMailTools::lineBreak()
+                    );
+                    $name = iconv_mime_encode( 'dummy', $item->name, 
$preferences );
+                    $name = substr( $name, 7 ); // "dummy: " + 1
+                    $text = $name . ' <' . $item->email . '>';
+                    break;
             }
-            else
-            {
-                $text = $item->name . ' <' . $item->email . '>';
-            }
         }
         else
         {

Modified: trunk/Mail/tests/mail_test.php
===================================================================
--- trunk/Mail/tests/mail_test.php      2007-05-04 07:53:03 UTC (rev 5036)
+++ trunk/Mail/tests/mail_test.php      2007-05-04 09:20:31 UTC (rev 5037)
@@ -89,15 +89,34 @@
         $this->assertEquals( $expected, $return );
     }
 
-    public function testSubjectWithCharset()
+    public function testSubjectWithCharset7Bit()
     {
         $this->mail->from = new ezcMailAddress( '[EMAIL PROTECTED]' );
         $this->mail->addTo( new ezcMailAddress( '[EMAIL PROTECTED]', 'Frederik 
Holljen' ) );
+        $this->mail->subject = "Dette er en test";
+        $this->mail->subjectCharset = 'ISO-8859-1';
+        $expected = "From: [EMAIL PROTECTED]" . ezcMailTools::lineBreak() .
+            "To: Frederik Holljen <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
+            "Subject: Dette er en test" . ezcMailTools::lineBreak() .
+            "MIME-Version: 1.0" . ezcMailTools::lineBreak() .
+            "User-Agent: eZ components";
+
+        $return = $this->mail->generate();
+        // cut away the Date and Message-ID headers as there is no way to 
predict what they will be
+        $return = join( ezcMailTools::lineBreak(), array_slice( explode( 
ezcMailTools::lineBreak(), $return ), 0, 5 ) );
+
+        $this->assertEquals( $expected, $return );
+    }
+
+    public function testSubjectWithCharset8Bit()
+    {
+        $this->mail->from = new ezcMailAddress( '[EMAIL PROTECTED]' );
+        $this->mail->addTo( new ezcMailAddress( '[EMAIL PROTECTED]', 'Frederik 
Holljen' ) );
         $this->mail->subject = "Døtte er en test";
         $this->mail->subjectCharset = 'ISO-8859-1';
         $expected = "From: [EMAIL PROTECTED]" . ezcMailTools::lineBreak() .
             "To: Frederik Holljen <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
-            "Subject: =?ISO-8859-1?B?RPh0dGUgZXIgZW4gdGVzdA==?=" . 
ezcMailTools::lineBreak() .
+            "Subject: =?ISO-8859-1?Q?D=F8tte=20er=20en=20test?=" . 
ezcMailTools::lineBreak() .
             "MIME-Version: 1.0" . ezcMailTools::lineBreak() .
             "User-Agent: eZ components";
 
@@ -116,11 +135,11 @@
         $this->mail->addBcc( new ezcMailAddress( '[EMAIL PROTECTED]', 
'Fræderik Hølljen','ISO-8859-1' ) );
         $this->mail->subject = "Døtte er en test";
         $this->mail->subjectCharset = 'ISO-8859-1';
-        $expected = "From: =?ISO-8859-1?B?RnLmZGVyaWsgSPhsbGplbg==?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
-            "To: =?ISO-8859-1?B?RnLmZGVyaWsgSPhsbGplbg==?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
-            "Cc: =?ISO-8859-1?B?RnLmZGVyaWsgSPhsbGplbg==?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
-            "Bcc: =?ISO-8859-1?B?RnLmZGVyaWsgSPhsbGplbg==?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
-            "Subject: =?ISO-8859-1?B?RPh0dGUgZXIgZW4gdGVzdA==?=" . 
ezcMailTools::lineBreak() .
+        $expected = "From: =?ISO-8859-1?Q?Fr=E6derik=20H=F8lljen?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
+            "To: =?ISO-8859-1?Q?Fr=E6derik=20H=F8lljen?= <[EMAIL PROTECTED]>" 
. ezcMailTools::lineBreak() .
+            "Cc: =?ISO-8859-1?Q?Fr=E6derik=20H=F8lljen?= <[EMAIL PROTECTED]>" 
. ezcMailTools::lineBreak() .
+            "Bcc: =?ISO-8859-1?Q?Fr=E6derik=20H=F8lljen?= <[EMAIL PROTECTED]>" 
. ezcMailTools::lineBreak() .
+            "Subject: =?ISO-8859-1?Q?D=F8tte=20er=20en=20test?=" . 
ezcMailTools::lineBreak() .
             "MIME-Version: 1.0" . ezcMailTools::lineBreak() .
             "User-Agent: eZ components";
 
@@ -130,16 +149,16 @@
 
         $this->assertEquals( $expected, $return );
     }
-    
-    public function testSubjectWithCharsetUtf8()
+
+    public function testSubjectWithCharset7BitUtf8()
     {
         $this->mail->from = new ezcMailAddress( '[EMAIL PROTECTED]' );
         $this->mail->addTo( new ezcMailAddress( '[EMAIL PROTECTED]', 'Frederik 
Holljen' ) );
-        $this->mail->subject = "Døtte er en test";
-        $this->mail->subjectCharset = 'ISO-8859-1';
+        $this->mail->subject = "Dette er en test";
+        $this->mail->subjectCharset = 'UTF-8';
         $expected = "From: [EMAIL PROTECTED]" . ezcMailTools::lineBreak() .
             "To: Frederik Holljen <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
-            "Subject: =?ISO-8859-1?B?RPh0dGUgZXIgZW4gdGVzdA==?=" . 
ezcMailTools::lineBreak() .
+            "Subject: Dette er en test" . ezcMailTools::lineBreak() .
             "MIME-Version: 1.0" . ezcMailTools::lineBreak() .
             "User-Agent: eZ components";
 
@@ -150,6 +169,25 @@
         $this->assertEquals( $expected, $return );
     }
 
+    public function testSubjectWithCharset8BitUtf8()
+    {
+        $this->mail->from = new ezcMailAddress( '[EMAIL PROTECTED]' );
+        $this->mail->addTo( new ezcMailAddress( '[EMAIL PROTECTED]', 'Frederik 
Holljen' ) );
+        $this->mail->subject = "Døtte er en test";
+        $this->mail->subjectCharset = 'UTF-8';
+        $expected = "From: [EMAIL PROTECTED]" . ezcMailTools::lineBreak() .
+            "To: Frederik Holljen <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
+            "Subject: =?UTF-8?Q?D=C3=B8tte=20er=20en=20test?=" . 
ezcMailTools::lineBreak() .
+            "MIME-Version: 1.0" . ezcMailTools::lineBreak() .
+            "User-Agent: eZ components";
+
+        $return = $this->mail->generate();
+        // cut away the Date and Message-ID headers as there is no way to 
predict what they will be
+        $return = join( ezcMailTools::lineBreak(), array_slice( explode( 
ezcMailTools::lineBreak(), $return ), 0, 5 ) );
+
+        $this->assertEquals( $expected, $return );
+    }
+
     public function testHeadersWithCharsetUtf8()
     {
         $this->mail->from = new ezcMailAddress( '[EMAIL PROTECTED]', 
'Fræderik Hølljen', 'UTF-8' );
@@ -158,11 +196,11 @@
         $this->mail->addBcc( new ezcMailAddress( '[EMAIL PROTECTED]', 
'Fræderik Hølljen','UTF-8' ) );
         $this->mail->subject = "Dätte er en test";
         $this->mail->subjectCharset = 'UTF-8';
-        $expected = "From: =?UTF-8?B?RnLDpmRlcmlrIEjDuGxsamVu?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
-            "To: =?UTF-8?B?RnLDpmRlcmlrIEjDuGxsamVu?= <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
-            "Cc: =?UTF-8?B?RnLDpmRlcmlrIEjDuGxsamVu?= <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
-            "Bcc: =?UTF-8?B?RnLDpmRlcmlrIEjDuGxsamVu?= <[EMAIL PROTECTED]>" . 
ezcMailTools::lineBreak() .
-            "Subject: =?UTF-8?B?RMOkdHRlIGVyIGVuIHRlc3Q=?=" . 
ezcMailTools::lineBreak() .
+        $expected = "From: =?UTF-8?Q?Fr=C3=A6derik=20H=C3=B8lljen?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
+            "To: =?UTF-8?Q?Fr=C3=A6derik=20H=C3=B8lljen?= <[EMAIL PROTECTED]>" 
. ezcMailTools::lineBreak() .
+            "Cc: =?UTF-8?Q?Fr=C3=A6derik=20H=C3=B8lljen?= <[EMAIL PROTECTED]>" 
. ezcMailTools::lineBreak() .
+            "Bcc: =?UTF-8?Q?Fr=C3=A6derik=20H=C3=B8lljen?= <[EMAIL 
PROTECTED]>" . ezcMailTools::lineBreak() .
+            "Subject: =?UTF-8?Q?D=C3=A4tte=20er=20en=20test?=" . 
ezcMailTools::lineBreak() .
             "MIME-Version: 1.0" . ezcMailTools::lineBreak() .
             "User-Agent: eZ components";
 
@@ -288,7 +326,7 @@
         $this->mail->body = new ezcMailText( "Dette er body ßßæøååå" );
 
         $this->mail->generateHeaders();
-        $expected = '<'. date( 'YmdGHjs' ) . '.' . getmypid() . '[EMAIL 
PROTECTED]>';
+        $expected = '<'. date( 'YmdGHjs' ) . '.' . getmypid() . '[EMAIL 
PROTECTED]>';
         $this->assertEquals( $expected, $this->mail->getHeader( 'Message-Id' ) 
);
     }
 

Modified: trunk/Mail/tests/tools_test.php
===================================================================
--- trunk/Mail/tests/tools_test.php     2007-05-04 07:53:03 UTC (rev 5036)
+++ trunk/Mail/tests/tools_test.php     2007-05-04 09:20:31 UTC (rev 5037)
@@ -46,6 +46,52 @@
                              ezcMailTools::composeEmailAddresses( $addresses ) 
);
     }
 
+    public function testComposeEmailAddressUsAscii()
+    {
+        $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Ascii' );
+        $this->assertEquals( 'John Ascii <[EMAIL PROTECTED]>', 
ezcMailTools::composeEmailAddress( $address ) );
+
+        // The Ä does not in US ASCII, but we pass it along anyway
+        $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Äscii' );
+        $this->assertEquals( 'John Äscii <[EMAIL PROTECTED]>', 
ezcMailTools::composeEmailAddress( $address ) );
+    }
+
+    public function testComposeEmailAddressLatin1()
+    {
+        // no 8-bit-chars
+        $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Ascii', 
'iso-8859-1' );
+        $this->assertEquals( 'John Ascii <[EMAIL PROTECTED]>', 
ezcMailTools::composeEmailAddress( $address ) );
+
+        // with 8-bit chars
+        $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Äscii', 
'iso-8859-1' );
+        $this->assertEquals( '=?iso-8859-1?Q?John=20=C4scii?= <[EMAIL 
PROTECTED]>', ezcMailTools::composeEmailAddress( $address ) );
+    }
+
+    public function testComposeEmailAddressOtherLatin()
+    {
+        foreach ( array( 'iso-8859-2', 'iso-8859-6', 'iso-8859-7', 
'iso-8859-9', 'iso-8859-15' ) as $charset )
+        {
+            // no 8-bit-chars
+            $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Ascii', 
$charset );
+            $this->assertEquals( 'John Ascii <[EMAIL PROTECTED]>', 
ezcMailTools::composeEmailAddress( $address ) );
+
+            // with 8-bit chars
+            $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Äscii', 
$charset );
+            $this->assertEquals( "=?{$charset}?Q?John=20=C4scii?= <[EMAIL 
PROTECTED]>", ezcMailTools::composeEmailAddress( $address ) );
+        }
+    }
+
+    public function testComposeEmailAddressUTF8()
+    {
+        // no 8-bit-chars
+        $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John Ascii', 
'UTF-8' );
+        $this->assertEquals( 'John Ascii <[EMAIL PROTECTED]>', 
ezcMailTools::composeEmailAddress( $address ) );
+
+        // with 8-bit chars
+        $address = new ezcMailAddress( '[EMAIL PROTECTED]', 'John 
Äscii','UTF-8' );
+        $this->assertEquals( "=?UTF-8?Q?John=20=C3=84scii?= <[EMAIL 
PROTECTED]>", ezcMailTools::composeEmailAddress( $address ) );
+    }
+
     public function testComposeEmailAddressesSingleFolding()
     {
         $reference = "John Doe <[EMAIL PROTECTED]>, Harry Doe <[EMAIL 
PROTECTED]>," .

-- 
svn-components mailing list
[email protected]
http://lists.ez.no/mailman/listinfo/svn-components

Reply via email to