From 824c1121e78e91e36953f241a02c94094c6ea21f Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Fri, 21 Sep 2012 04:11:49 -0400
Subject: [PATCH] Merge branch 'html_ent'

---
 CHANGELOG                             |    1 +
 program/include/html.php              |   23 +++++++----------------
 program/steps/addressbook/import.inc  |    2 +-
 program/include/rcube_output_html.php |    2 +-
 program/include/rcube_utils.php       |    3 ---
 program/steps/addressbook/edit.inc    |    7 ++++---
 program/include/rcmail.php            |    2 +-
 program/steps/addressbook/func.inc    |    5 +++--
 program/steps/settings/func.inc       |    2 +-
 9 files changed, 19 insertions(+), 28 deletions(-)

diff --git a/CHANGELOG b/CHANGELOG
index 8a010a4..61eced8 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,6 +1,7 @@
 CHANGELOG Roundcube Webmail
 ===========================
 
+- Fix HTML special characters handling in message list/header display (#1488523)
 - List related text/html part as attachment in plain text mode (#1488677)
 - Use IMAP BINARY (RFC3516) extension to fetch message/part bodies
 - Fix folder creation under public namespace root (#1488665)
diff --git a/program/include/html.php b/program/include/html.php
index c6507f8..9487942 100644
--- a/program/include/html.php
+++ b/program/include/html.php
@@ -295,7 +295,7 @@
                 }
             }
             else {
-                $attrib_arr[] = $key . '="' . self::quote($value, true) . '"';
+                $attrib_arr[] = $key . '="' . self::quote($value) . '"';
             }
         }
 
@@ -328,22 +328,13 @@
     /**
      * Replacing specials characters in html attribute value
      *
-     * @param  string  $str       Input string
-     * @param  bool    $validate  Enables double quotation prevention
+     * @param string $str Input string
      *
-     * @return string  The quoted string
+     * @return string The quoted string
      */
-    public static function quote($str, $validate = false)
+    public static function quote($str)
     {
-        $str = htmlspecialchars($str, ENT_COMPAT, RCMAIL_CHARSET);
-
-        // avoid douple quotation of &
-        // @TODO: get rid of it
-        if ($validate) {
-            $str = preg_replace('/&amp;([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', $str);
-        }
-
-        return $str;
+        return htmlspecialchars($str, ENT_COMPAT, RCMAIL_CHARSET);
     }
 }
 
@@ -559,7 +550,7 @@
         }
 
         if (!empty($value) && empty($this->attrib['is_escaped'])) {
-            $value = self::quote($value, true);
+            $value = self::quote($value);
         }
 
         return self::tag($this->tagname, $this->attrib, $value,
@@ -635,7 +626,7 @@
 
             $option_content = $option['text'];
             if (empty($this->attrib['is_escaped'])) {
-                $option_content = self::quote($option_content, true);
+                $option_content = self::quote($option_content);
             }
 
             $this->content .= self::tag('option', $attr, $option_content);
diff --git a/program/include/rcmail.php b/program/include/rcmail.php
index 5a9a1fa..ee144fa 100644
--- a/program/include/rcmail.php
+++ b/program/include/rcmail.php
@@ -281,7 +281,7 @@
         }
         $list[$id] = array(
           'id'       => $id,
-          'name'     => $prop['name'],
+          'name'     => html::quote($prop['name']),
           'groups'   => is_array($prop['groups']),
           'readonly' => !$prop['writable'],
           'hidden'   => $prop['hidden'],
diff --git a/program/include/rcube_output_html.php b/program/include/rcube_output_html.php
index 2743e77..6138e2a 100644
--- a/program/include/rcube_output_html.php
+++ b/program/include/rcube_output_html.php
@@ -527,7 +527,7 @@
     {
         $GLOBALS['__version']   = html::quote(RCMAIL_VERSION);
         $GLOBALS['__comm_path'] = html::quote($this->app->comm_path);
-        $GLOBALS['__skin_path'] = Q($this->config->get('skin_path'));
+        $GLOBALS['__skin_path'] = html::quote($this->config->get('skin_path'));
 
         return preg_replace_callback('/\$(__[a-z0-9_\-]+)/',
             array($this, 'globals_callback'), $input);
diff --git a/program/include/rcube_utils.php b/program/include/rcube_utils.php
index b278431..bf2b0db 100644
--- a/program/include/rcube_utils.php
+++ b/program/include/rcube_utils.php
@@ -250,9 +250,6 @@
 
             $out = strtr($str, $encode_arr);
 
-            // avoid douple quotation of &
-            $out = preg_replace('/&amp;([A-Za-z]{2,6}|#[0-9]{2,4});/', '&\\1;', $out);
-
             return $newlines ? nl2br($out) : $out;
         }
 
diff --git a/program/steps/addressbook/edit.inc b/program/steps/addressbook/edit.inc
index 90069a7..b216a7c 100644
--- a/program/steps/addressbook/edit.inc
+++ b/program/steps/addressbook/edit.inc
@@ -244,11 +244,12 @@
     if (count($sources_list) < 2) {
         $source = $sources_list[$SOURCE_ID];
         $hiddenfield = new html_hiddenfield(array('name' => '_source', 'value' => $SOURCE_ID));
-        return html::span($attrib, Q($source['name']) . $hiddenfield->show());
+        return html::span($attrib, $source['name'] . $hiddenfield->show());
     }
 
-    $attrib['name'] = '_source';
-    $attrib['onchange'] = JS_OBJECT_NAME . ".command('save', 'reload', this.form)";
+    $attrib['name']       = '_source';
+    $attrib['is_escaped'] = true;
+    $attrib['onchange']   = JS_OBJECT_NAME . ".command('save', 'reload', this.form)";
 
     $select = new html_select($attrib);
 
diff --git a/program/steps/addressbook/func.inc b/program/steps/addressbook/func.inc
index 5f5fcc6..4ef4d1b 100644
--- a/program/steps/addressbook/func.inc
+++ b/program/steps/addressbook/func.inc
@@ -178,7 +178,7 @@
         if (!$name && $source == 0) {
             $name = rcube_label('personaladrbook');
         }
-        $OUTPUT->set_env('sourcename', $name);
+        $OUTPUT->set_env('sourcename', html_entity_decode($name, ENT_COMPAT, 'UTF-8'));
     }
 }
 
@@ -219,12 +219,13 @@
         if ($source['class_name'])
             $class_name .= ' ' . $source['class_name'];
 
+        $name = !empty($source['name']) ? $source['name'] : $id;
         $out .= sprintf($line_templ,
             html_identifier($id),
             $class_name,
             Q(rcmail_url(null, array('_source' => $id))),
             $source['id'],
-            $js_id, (!empty($source['name']) ? Q($source['name']) : Q($id)));
+            $js_id, $name);
 
         $groupdata = array('out' => $out, 'jsdata' => $jsdata, 'source' => $id);
         if ($source['groups'])
diff --git a/program/steps/addressbook/import.inc b/program/steps/addressbook/import.inc
index 15e04b8..fb2251f 100644
--- a/program/steps/addressbook/import.inc
+++ b/program/steps/addressbook/import.inc
@@ -43,7 +43,7 @@
 
   // addressbook selector
   if (count($writable_books) > 1) {
-    $select = new html_select(array('name' => '_target', 'id' => 'rcmimporttarget'));
+    $select = new html_select(array('name' => '_target', 'id' => 'rcmimporttarget', 'is_escaped' => true));
 
     foreach ($writable_books as $book)
         $select->add($book['name'], $book['id']);
diff --git a/program/steps/settings/func.inc b/program/steps/settings/func.inc
index 59b4e37..4f8da13 100644
--- a/program/steps/settings/func.inc
+++ b/program/steps/settings/func.inc
@@ -667,7 +667,7 @@
       $select_abook = new html_select(array('name' => '_default_addressbook', 'id' => $field_id));
 
       foreach ($books as $book) {
-        $select_abook->add($book['name'], $book['id']);
+        $select_abook->add(html_entity_decode($book['name'], ENT_COMPAT, 'UTF-8'), $book['id']);
       }
 
       $blocks['main']['options']['default_addressbook'] = array(

--
Gitblit v1.9.1