aharvey                                  Thu, 30 Sep 2010 11:04:21 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=303890

Log:
Fixed bug #52941 (The 'iconv_mime_decode_headers' function is skipping
headers).

Bug: http://bugs.php.net/52941 (Assigned) The 'iconv_mime_decode_headers' 
function is skipping headers 
      
Changed paths:
    U   php/php-src/branches/PHP_5_3/NEWS
    U   php/php-src/branches/PHP_5_3/ext/iconv/iconv.c
    A   php/php-src/branches/PHP_5_3/ext/iconv/tests/bug52941.phpt
    U   php/php-src/trunk/ext/iconv/iconv.c
    A   php/php-src/trunk/ext/iconv/tests/bug52941.phpt

Modified: php/php-src/branches/PHP_5_3/NEWS
===================================================================
--- php/php-src/branches/PHP_5_3/NEWS   2010-09-30 09:21:50 UTC (rev 303889)
+++ php/php-src/branches/PHP_5_3/NEWS   2010-09-30 11:04:21 UTC (rev 303890)
@@ -26,6 +26,8 @@
   used). (Felipe)
 - Fixed bug #52944 (Invalid write on second and subsequent reads with an
   inflate filter fed invalid data). (Gustavo)
+- Fixed bug #52941 (The 'iconv_mime_decode_headers' function is skipping
+  headers). (Adam)
 - Fixed bug #52931 (strripos not overloaded with function overloading enabled).
   (Felipe)
 - Fixed bug #52929 (Segfault in filter_var with FILTER_VALIDATE_EMAIL with

Modified: php/php-src/branches/PHP_5_3/ext/iconv/iconv.c
===================================================================
--- php/php-src/branches/PHP_5_3/ext/iconv/iconv.c      2010-09-30 09:21:50 UTC 
(rev 303889)
+++ php/php-src/branches/PHP_5_3/ext/iconv/iconv.c      2010-09-30 11:04:21 UTC 
(rev 303890)
@@ -1457,16 +1457,43 @@

                                        if (cd == (iconv_t)(-1)) {
                                                if ((mode & 
PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) {
+                                                       /* Bad character set, 
but the user wants us to
+                                                        * press on. In this 
case, we'll just insert the
+                                                        * undecoded encoded 
word, since there isn't really
+                                                        * a more sensible 
behaviour available; the only
+                                                        * other options are to 
swallow the encoded word
+                                                        * entirely or decode 
it with an arbitrarily chosen
+                                                        * single byte 
encoding, both of which seem to have
+                                                        * a higher WTF factor 
than leaving it undecoded.
+                                                        *
+                                                        * Given this approach, 
we need to skip ahead to
+                                                        * the end of the 
encoded word. */
+                                                       int qmarks = 2;
+                                                       while (qmarks > 0 && 
str_left > 1) {
+                                                               if (*(++p1) == 
'?') {
+                                                                       
--qmarks;
+                                                               }
+                                                               --str_left;
+                                                       }
+
+                                                       /* Look ahead to check 
for the terminating = that
+                                                        * should be there as 
well; if it's there, we'll
+                                                        * also include that. 
If it's not, there isn't much
+                                                        * we can do at this 
point. */
+                                                       if (*(p1 + 1) == '=') {
+                                                               ++p1;
+                                                               --str_left;
+                                                       }
+
                                                        err = 
_php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), 
cd_pl);
                                                        if (err != 
PHP_ICONV_ERR_SUCCESS) {
                                                                goto out;
                                                        }
-                                                       encoded_word = NULL;
-                                                       if ((mode & 
PHP_ICONV_MIME_DECODE_STRICT)) {
-                                                               scan_stat = 12;
-                                                       } else {
-                                                               scan_stat = 0;
-                                                       }
+
+                                                       /* Let's go back and 
see if there are further
+                                                        * encoded words or 
bare content, and hope they
+                                                        * might actually have 
a valid character set. */
+                                                       scan_stat = 12;
                                                        break;
                                                } else {
 #if ICONV_SUPPORTS_ERRNO

Added: php/php-src/branches/PHP_5_3/ext/iconv/tests/bug52941.phpt
===================================================================
--- php/php-src/branches/PHP_5_3/ext/iconv/tests/bug52941.phpt                  
        (rev 0)
+++ php/php-src/branches/PHP_5_3/ext/iconv/tests/bug52941.phpt  2010-09-30 
11:04:21 UTC (rev 303890)
@@ -0,0 +1,41 @@
+--TEST--
+Bug #52941 (The 'iconv_mime_decode_headers' function is skipping headers)
+--SKIPIF--
+<?php extension_loaded('iconv') or die('skip iconv extension is not 
available'); ?>
+--FILE--
+<?php
+$headers = <<<HEADERS
+From: =?UTF-8?B?PGZvb0BleGFtcGxlLmNvbT4=?=
+Subject: =?ks_c_5601-1987?B?UkU6odk=?=
+X-Foo: =?ks_c_5601-1987?B?UkU6odk=?= Foo
+X-Bar: =?ks_c_5601-1987?B?UkU6odk=?= =?UTF-8?Q?Foo?=
+To: <t...@example.com>
+HEADERS;
+
+$decoded = iconv_mime_decode_headers($headers, 
ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8');
+
+var_dump($decoded['From']);
+var_dump($decoded['Subject']);
+var_dump($decoded['X-Foo']);
+var_dump($decoded['X-Bar']);
+var_dump($decoded['To']);
+
+$decoded = iconv_mime_decode_headers($headers, 
ICONV_MIME_DECODE_CONTINUE_ON_ERROR | ICONV_MIME_DECODE_STRICT, 'UTF-8');
+
+var_dump($decoded['From']);
+var_dump($decoded['Subject']);
+var_dump($decoded['X-Foo']);
+var_dump($decoded['X-Bar']);
+var_dump($decoded['To']);
+?>
+--EXPECT--
+string(17) "<f...@example.com>"
+string(29) "=?ks_c_5601-1987?B?UkU6odk=?="
+string(33) "=?ks_c_5601-1987?B?UkU6odk=?= Foo"
+string(32) "=?ks_c_5601-1987?B?UkU6odk=?=Foo"
+string(18) "<t...@example.com>"
+string(17) "<f...@example.com>"
+string(29) "=?ks_c_5601-1987?B?UkU6odk=?="
+string(33) "=?ks_c_5601-1987?B?UkU6odk=?= Foo"
+string(32) "=?ks_c_5601-1987?B?UkU6odk=?=Foo"
+string(18) "<t...@example.com>"

Modified: php/php-src/trunk/ext/iconv/iconv.c
===================================================================
--- php/php-src/trunk/ext/iconv/iconv.c 2010-09-30 09:21:50 UTC (rev 303889)
+++ php/php-src/trunk/ext/iconv/iconv.c 2010-09-30 11:04:21 UTC (rev 303890)
@@ -1521,16 +1521,43 @@

                                        if (cd == (iconv_t)(-1)) {
                                                if ((mode & 
PHP_ICONV_MIME_DECODE_CONTINUE_ON_ERROR)) {
+                                                       /* Bad character set, 
but the user wants us to
+                                                        * press on. In this 
case, we'll just insert the
+                                                        * undecoded encoded 
word, since there isn't really
+                                                        * a more sensible 
behaviour available; the only
+                                                        * other options are to 
swallow the encoded word
+                                                        * entirely or decode 
it with an arbitrarily chosen
+                                                        * single byte 
encoding, both of which seem to have
+                                                        * a higher WTF factor 
than leaving it undecoded.
+                                                        *
+                                                        * Given this approach, 
we need to skip ahead to
+                                                        * the end of the 
encoded word. */
+                                                       int qmarks = 2;
+                                                       while (qmarks > 0 && 
str_left > 1) {
+                                                               if (*(++p1) == 
'?') {
+                                                                       
--qmarks;
+                                                               }
+                                                               --str_left;
+                                                       }
+
+                                                       /* Look ahead to check 
for the terminating = that
+                                                        * should be there as 
well; if it's there, we'll
+                                                        * also include that. 
If it's not, there isn't much
+                                                        * we can do at this 
point. */
+                                                       if (*(p1 + 1) == '=') {
+                                                               ++p1;
+                                                               --str_left;
+                                                       }
+
                                                        err = 
_php_iconv_appendl(pretval, encoded_word, (size_t)((p1 + 1) - encoded_word), 
cd_pl);
                                                        if (err != 
PHP_ICONV_ERR_SUCCESS) {
                                                                goto out;
                                                        }
-                                                       encoded_word = NULL;
-                                                       if ((mode & 
PHP_ICONV_MIME_DECODE_STRICT)) {
-                                                               scan_stat = 12;
-                                                       } else {
-                                                               scan_stat = 0;
-                                                       }
+
+                                                       /* Let's go back and 
see if there are further
+                                                        * encoded words or 
bare content, and hope they
+                                                        * might actually have 
a valid character set. */
+                                                       scan_stat = 12;
                                                        break;
                                                } else {
 #if ICONV_SUPPORTS_ERRNO

Added: php/php-src/trunk/ext/iconv/tests/bug52941.phpt
===================================================================
--- php/php-src/trunk/ext/iconv/tests/bug52941.phpt                             
(rev 0)
+++ php/php-src/trunk/ext/iconv/tests/bug52941.phpt     2010-09-30 11:04:21 UTC 
(rev 303890)
@@ -0,0 +1,41 @@
+--TEST--
+Bug #52941 (The 'iconv_mime_decode_headers' function is skipping headers)
+--SKIPIF--
+<?php extension_loaded('iconv') or die('skip iconv extension is not 
available'); ?>
+--FILE--
+<?php
+$headers = <<<HEADERS
+From: =?UTF-8?B?PGZvb0BleGFtcGxlLmNvbT4=?=
+Subject: =?ks_c_5601-1987?B?UkU6odk=?=
+X-Foo: =?ks_c_5601-1987?B?UkU6odk=?= Foo
+X-Bar: =?ks_c_5601-1987?B?UkU6odk=?= =?UTF-8?Q?Foo?=
+To: <t...@example.com>
+HEADERS;
+
+$decoded = iconv_mime_decode_headers($headers, 
ICONV_MIME_DECODE_CONTINUE_ON_ERROR, 'UTF-8');
+
+var_dump($decoded['From']);
+var_dump($decoded['Subject']);
+var_dump($decoded['X-Foo']);
+var_dump($decoded['X-Bar']);
+var_dump($decoded['To']);
+
+$decoded = iconv_mime_decode_headers($headers, 
ICONV_MIME_DECODE_CONTINUE_ON_ERROR | ICONV_MIME_DECODE_STRICT, 'UTF-8');
+
+var_dump($decoded['From']);
+var_dump($decoded['Subject']);
+var_dump($decoded['X-Foo']);
+var_dump($decoded['X-Bar']);
+var_dump($decoded['To']);
+?>
+--EXPECT--
+string(17) "<f...@example.com>"
+string(29) "=?ks_c_5601-1987?B?UkU6odk=?="
+string(33) "=?ks_c_5601-1987?B?UkU6odk=?= Foo"
+string(32) "=?ks_c_5601-1987?B?UkU6odk=?=Foo"
+string(18) "<t...@example.com>"
+string(17) "<f...@example.com>"
+string(29) "=?ks_c_5601-1987?B?UkU6odk=?="
+string(33) "=?ks_c_5601-1987?B?UkU6odk=?= Foo"
+string(32) "=?ks_c_5601-1987?B?UkU6odk=?=Foo"
+string(18) "<t...@example.com>"

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to