From 4f8be46f38223c4e45ad966e977197e40e2eeb9a Mon Sep 17 00:00:00 2001
From: alecpl <alec@alec.pl>
Date: Fri, 02 Dec 2011 02:51:07 -0500
Subject: [PATCH] - Improved handling of some malformed values encoded with quoted-printable (#1488232)

---
 tests/maildecode.php           |   46 ++++++++++++++++++++++++++++++++++++++++++++++
 CHANGELOG                      |    1 +
 program/include/rcube_imap.php |    2 +-
 3 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 78ac477..f476e94 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Improved handling of some malformed values encoded with quoted-printable (#1488232)
 - Add possibility to do LDAP bind before searching for bind DN
 - Fix handling of empty <U> tags in HTML messages (#1488225)
 - Add content filter for embedded attachments to protect from XSS on IE (#1487895)
diff --git a/program/include/rcube_imap.php b/program/include/rcube_imap.php
index 50656f2..c4175cb 100644
--- a/program/include/rcube_imap.php
+++ b/program/include/rcube_imap.php
@@ -4164,7 +4164,7 @@
         $input = preg_replace("/\?=\s+=\?/", '?==?', $input);
 
         // encoded-word regexp
-        $re = '/=\?([^?]+)\?([BbQq])\?([^?\n]*)\?=/';
+        $re = '/=\?([^?]+)\?([BbQq])\?([^\n]*?)\?=/';
 
         // Find all RFC2047's encoded words
         if (preg_match_all($re, $input, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
diff --git a/tests/maildecode.php b/tests/maildecode.php
index 7d67352..664161c 100644
--- a/tests/maildecode.php
+++ b/tests/maildecode.php
@@ -84,4 +84,50 @@
     }
   }
 
+  /**
+   * Test decoding of header values
+   * Uses rcube_imap::decode_mime_string()
+   */
+  function test_header_decode_qp()
+  {
+    $test = array(
+      // #1488232: invalid character "?"
+      'quoted-printable (1)' => array(
+        'in'  => '=?utf-8?Q?Certifica=C3=A7=C3=A3??=',
+        'out' => 'Certifica=C3=A7=C3=A3?',
+      ),
+      'quoted-printable (2)' => array(
+        'in'  => '=?utf-8?Q?Certifica=?= =?utf-8?Q?C3=A7=C3=A3?=',
+        'out' => 'Certifica=C3=A7=C3=A3',
+      ),
+      'quoted-printable (3)' => array(
+        'in'  => '=?utf-8?Q??= =?utf-8?Q??=',
+        'out' => '',
+      ),
+      'quoted-printable (4)' => array(
+        'in'  => '=?utf-8?Q??= a =?utf-8?Q??=',
+        'out' => ' a ',
+      ),
+      'quoted-printable (5)' => array(
+        'in'  => '=?utf-8?Q?a?= =?utf-8?Q?b?=',
+        'out' => 'ab',
+      ),
+      'quoted-printable (6)' => array(
+        'in'  => '=?utf-8?Q?   ?= =?utf-8?Q?a?=',
+        'out' => '   a',
+      ),
+      'quoted-printable (7)' => array(
+        'in'  => '=?utf-8?Q?___?= =?utf-8?Q?a?=',
+        'out' => '   a',
+      ),
+    );
+
+    foreach ($test as $idx => $item) {
+      $res = $this->app->imap->decode_mime_string($item['in'], 'UTF-8');
+      $res = quoted_printable_encode($res);
+
+      $this->assertEqual($item['out'], $res, "Header decoding for: " . $idx);
+    }
+
+  }
 }

--
Gitblit v1.9.1