From 037af6890fe6fdb84a08d3c86083e847c90ec0ad Mon Sep 17 00:00:00 2001
From: Aleksander Machniak <alec@alec.pl>
Date: Tue, 22 Oct 2013 08:17:26 -0400
Subject: [PATCH] Fix vulnerability in handling _session argument of utils/save-prefs (#1489382)

---
 program/lib/Roundcube/rcube_vcard.php |   39 ++++++++++++++++++++++++++++++++++-----
 1 files changed, 34 insertions(+), 5 deletions(-)

diff --git a/program/lib/Roundcube/rcube_vcard.php b/program/lib/Roundcube/rcube_vcard.php
index de28767..285dc29 100644
--- a/program/lib/Roundcube/rcube_vcard.php
+++ b/program/lib/Roundcube/rcube_vcard.php
@@ -90,7 +90,7 @@
      */
     public function __construct($vcard = null, $charset = RCUBE_CHARSET, $detect = false, $fieldmap = array())
     {
-        if (!empty($fielmap)) {
+        if (!empty($fieldmap)) {
             $this->extend_fieldmap($fieldmap);
         }
 
@@ -491,7 +491,9 @@
             if (preg_match('/^END:VCARD$/i', $line)) {
                 // parse vcard
                 $obj = new rcube_vcard(self::cleanup($vcard_block), $charset, true, self::$fieldmap);
-                if (!empty($obj->displayname) || !empty($obj->email)) {
+                // FN and N is required by vCard format (RFC 2426)
+                // on import we can be less restrictive, let's addressbook decide
+                if (!empty($obj->displayname) || !empty($obj->surname) || !empty($obj->firstname) || !empty($obj->email)) {
                     $out[] = $obj;
                 }
 
@@ -712,9 +714,15 @@
                             $value[] = $attrvalues;
                         }
                         else if (is_bool($attrvalues)) {
-                            // true means just tag, not tag=value, as in PHOTO;BASE64:...
+                            // true means just a tag, not tag=value, as in PHOTO;BASE64:...
                             if ($attrvalues) {
-                                $attr .= strtoupper(";$attrname");
+                                // vCard v3 uses ENCODING=B (#1489183)
+                                if ($attrname == 'base64') {
+                                    $attr .= ";ENCODING=B";
+                                }
+                                else {
+                                    $attr .= strtoupper(";$attrname");
+                                }
                             }
                         }
                         else {
@@ -782,9 +790,30 @@
                 }
                 return $result;
             }
+
+            $s = strtr($s, $rep2);
         }
 
-        return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';'));
+        // some implementations (GMail) use non-standard backslash before colon (#1489085)
+        // we will handle properly any backslashed character - removing dummy backslahes
+        // return strtr($s, array("\r" => '', '\\\\' => '\\', '\n' => "\n", '\N' => "\n", '\,' => ',', '\;' => ';'));
+
+        $s   = str_replace("\r", '', $s);
+        $pos = 0;
+
+        while (($pos = strpos($s, '\\', $pos)) !== false) {
+            $next = substr($s, $pos + 1, 1);
+            if ($next == 'n' || $next == 'N') {
+                $s = substr_replace($s, "\n", $pos, 2);
+            }
+            else {
+                $s = substr_replace($s, '', $pos, 1);
+            }
+
+            $pos += 1;
+        }
+
+        return $s;
     }
 
     /**

--
Gitblit v1.9.1