From f94e442469deca30b39f3fa08aade83cbd0ede70 Mon Sep 17 00:00:00 2001
From: thomascube <thomas@roundcube.net>
Date: Fri, 16 Dec 2011 13:38:59 -0500
Subject: [PATCH] Add more classes and options to HTML elements for better styleability

---
 program/include/main.inc |   59 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 47 insertions(+), 12 deletions(-)

diff --git a/program/include/main.inc b/program/include/main.inc
index 8aa38c8..012ee8d 100644
--- a/program/include/main.inc
+++ b/program/include/main.inc
@@ -883,23 +883,37 @@
  * @param string Container ID to use as prefix
  * @return string Modified CSS source
  */
-function rcmail_mod_css_styles($source, $container_id)
+function rcmail_mod_css_styles($source, $container_id, $allow_remote=false)
   {
   $last_pos = 0;
   $replacements = new rcube_string_replacer;
 
   // ignore the whole block if evil styles are detected
-  $stripped = preg_replace('/[^a-z\(:;]/', '', rcmail_xss_entity_decode($source));
-  if (preg_match('/expression|behavior|url\(|import[^a]/', $stripped))
+  $source = rcmail_xss_entity_decode($source);
+  $stripped = preg_replace('/[^a-z\(:;]/i', '', $source);
+  $evilexpr = 'expression|behavior|javascript:|import[^a]' . (!$allow_remote ? '|url\(' : '');
+  if (preg_match("/$evilexpr/i", $stripped))
     return '/* evil! */';
 
-  // remove css comments (sometimes used for some ugly hacks)
-  $source = preg_replace('!/\*(.+)\*/!Ums', '', $source);
-
   // cut out all contents between { and }
-  while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos)))
-  {
-    $key = $replacements->add(substr($source, $pos+1, $pos2-($pos+1)));
+  while (($pos = strpos($source, '{', $last_pos)) && ($pos2 = strpos($source, '}', $pos))) {
+    $styles = substr($source, $pos+1, $pos2-($pos+1));
+
+    // check every line of a style block...
+    if ($allow_remote) {
+      $a_styles = preg_split('/;[\r\n]*/', $styles, -1, PREG_SPLIT_NO_EMPTY);
+      foreach ($a_styles as $line) {
+        $stripped = preg_replace('/[^a-z\(:;]/i', '', $line);
+        // ... and only allow strict url() values
+        if (stripos($stripped, 'url(') && !preg_match('!url\s*\([ "\'](https?:)//[a-z0-9/._+-]+["\' ]\)!Uims', $line)) {
+          $a_styles = array('/* evil! */');
+          break;
+        }
+      }
+      $styles = join(";\n", $a_styles);
+    }
+
+    $key = $replacements->add($styles);
     $source = substr($source, 0, $pos+1) . $replacements->get_replacement($key) . substr($source, $pos2, strlen($source)-$pos2);
     $last_pos = $pos+2;
   }
@@ -937,7 +951,7 @@
 {
   $out = html_entity_decode(html_entity_decode($content));
   $out = preg_replace_callback('/\\\([0-9a-f]{4})/i', 'rcmail_xss_entity_decode_callback', $out);
-  $out = preg_replace('#/\*.*\*/#Um', '', $out);
+  $out = preg_replace('#/\*.*\*/#Ums', '', $out);
   return $out;
 }
 
@@ -1156,7 +1170,7 @@
   global $RCMAIL;
   static $a_mailboxes;
 
-  $attrib += array('maxlength' => 100, 'realnames' => false);
+  $attrib += array('maxlength' => 100, 'realnames' => false, 'unreadwrap' => ' (%s)');
 
   // add some labels to client
   $RCMAIL->output->add_label('purgefolderconfirm', 'deletemessagesconfirm');
@@ -1203,6 +1217,7 @@
 
     $RCMAIL->output->add_gui_object('mailboxlist', $attrib['id']);
     $RCMAIL->output->set_env('mailboxes', $js_mailboxlist);
+    $RCMAIL->output->set_env('unreadwrap', $attrib['unreadwrap']);
     $RCMAIL->output->set_env('collapsed_folders', (string)$RCMAIL->config->get('collapsed_folders'));
   }
 
@@ -1358,7 +1373,7 @@
       $classes[] = 'unread';
 
     $js_name = JQ($folder['id']);
-    $html_name = Q($foldername) . ($unread ? html::span('unreadcount', " ($unread)") : '');
+    $html_name = Q($foldername) . ($unread ? html::span('unreadcount', sprintf($attrib['unreadwrap'], $unread)) : '');
     $link_attrib = $folder['virtual'] ? array() : array(
       'href' => rcmail_url('', array('_mbox' => $folder['id'])),
       'onclick' => sprintf("return %s.command('list','%s',this)", JS_OBJECT_NAME, $js_name),
@@ -1593,6 +1608,26 @@
 
 
 /**
+ * Generate CSS classes from mimetype and filename extension
+ *
+ * @param string Mimetype
+ * @param string The filename
+ * @return string CSS classes separated by space
+ */
+function rcmail_filetype2classname($mimetype, $filename)
+{
+  list($primary, $secondary) = explode('/', $mimetype);
+
+  $classes = array($primary ? $primary : 'unknown');
+  if ($secondary)
+    $classes[] = $secondary;
+  if (preg_match('/\.([a-z0-9]+)$/', $filename, $m))
+    $classes[] = $m[1];
+
+  return join(" ", $classes);
+}
+
+/**
  * Output HTML editor scripts
  *
  * @param string Editor mode

--
Gitblit v1.9.1