diff options
-rw-r--r-- | lib/Kolab/CalDAV/CalendarBackend.php | 23 | ||||
-rw-r--r-- | lib/Kolab/CardDAV/ContactsBackend.php | 14 | ||||
-rw-r--r-- | lib/Kolab/CardDAV/LDAPDirectory.php | 9 | ||||
-rw-r--r-- | lib/Kolab/Utils/VObjectUtils.php | 24 |
4 files changed, 48 insertions, 22 deletions
diff --git a/lib/Kolab/CalDAV/CalendarBackend.php b/lib/Kolab/CalDAV/CalendarBackend.php index 8f141f0..53a2f84 100644 --- a/lib/Kolab/CalDAV/CalendarBackend.php +++ b/lib/Kolab/CalDAV/CalendarBackend.php @@ -291,7 +291,7 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend foreach ($storage->select($query) as $event) { $events[] = array( 'id' => $event['uid'], - 'uri' => $event['uid'] . '.ics', + 'uri' => VObjectUtils::uid2uri($event['uid'], '.ics'), 'lastmodified' => $event['changed'] ? $event['changed']->format('U') : null, 'calendarid' => $calendarId, 'etag' => self::_get_etag($event), @@ -320,12 +320,13 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend { console(__METHOD__, $calendarId, $objectUri); - $uid = basename($objectUri, '.ics'); + $uid = VObjectUtils::uri2uid($objectUri, '.ics'); $storage = $this->get_storage_folder($calendarId); // attachment content is requested if (preg_match('!^(.+).ics:attachment:(\d+):.+$!', $objectUri, $m)) { - $uid = $m[1]; $part = $m[2]; + $uid = VObjectUtils::uri2uid($m[1]); + $part = $m[2]; } if ($storage && ($event = $storage->get_object($uid))) { @@ -344,18 +345,18 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend // map attributes $event['attachments'] = $event['_attachments']; - // compose an absilute URI for referencing object attachments + // compose an absolute URI for referencing object attachments $base_uri = DAVBackend::abs_url(array( CalDAV\Plugin::CALENDAR_ROOT, preg_replace('!principals/!', '', $this->calendars[$calendarId]['principaluri']), $calendarId, - $event['uid'] . '.ics', + VObjectUtils::uid2uri($event['uid'], '.ics'), )); // default response return array( 'id' => $event['uid'], - 'uri' => $event['uid'] . '.ics', + 'uri' => VObjectUtils::uid2uri($event['uid'], '.ics'), 'lastmodified' => $event['changed'] ? $event['changed']->format('U') : null, 'calendarid' => $calendarId, 'calendardata' => $this->_to_ical($event, $base_uri, $storage), @@ -387,7 +388,7 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend { console(__METHOD__, $calendarId, $objectUri, $calendarData); - $uid = basename($objectUri, '.ics'); + $uid = VObjectUtils::uri2uid($objectUri, '.ics'); $storage = $this->get_storage_folder($calendarId); $object = $this->parse_calendar_data($calendarData, $uid); @@ -397,7 +398,7 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend // if URI doesn't match the content's UID, the object might already exist! if ($object['uid'] != $uid && $storage->get_object($object['uid'])) { - $objectUri = $object['uid'] . '.ics'; + $objectUri = VObjectUtils::uid2uri($object['uid'], '.ics'); Plugin::$redirect_basename = $objectUri; return $this->updateCalendarObject($calendarId, $objectUri, $calendarData); } @@ -419,7 +420,7 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend // send Location: header if URI doesn't match object's UID (Bug #2109) if ($object['uid'] != $uid) { - Plugin::$redirect_basename = $object['uid'].'.ics'; + Plugin::$redirect_basename = VObjectUtils::uid2uri($object['uid'], '.ics'); } // return new Etag @@ -446,7 +447,7 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend { console(__METHOD__, $calendarId, $objectUri, $calendarData); - $uid = basename($objectUri, '.ics'); + $uid = VObjectUtils::uri2uid($objectUri, '.ics'); $storage = $this->get_storage_folder($calendarId); $object = $this->parse_calendar_data($calendarData, $uid); @@ -511,7 +512,7 @@ class CalendarBackend extends CalDAV\Backend\AbstractBackend { console(__METHOD__, $calendarId, $objectUri); - $uid = basename($objectUri, '.ics'); + $uid = VObjectUtils::uri2uid($objectUri, '.ics'); if ($storage = $this->get_storage_folder($calendarId)) { $storage->delete($uid); } diff --git a/lib/Kolab/CardDAV/ContactsBackend.php b/lib/Kolab/CardDAV/ContactsBackend.php index cb0c448..a025d7d 100644 --- a/lib/Kolab/CardDAV/ContactsBackend.php +++ b/lib/Kolab/CardDAV/ContactsBackend.php @@ -274,7 +274,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend foreach ($storage->select($query) as $contact) { $cards[] = array( 'id' => $contact['uid'], - 'uri' => $contact['uid'] . '.vcf', + 'uri' => VObjectUtils::uid2uri($contact['uid'], '.vcf'), 'lastmodified' => is_a($contact['changed'], 'DateTime') ? $contact['changed']->format('U') : null, 'etag' => self::_get_etag($contact), 'size' => $contact['_size'], @@ -299,7 +299,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend { console(__METHOD__, $addressBookId, $cardUri); - $uid = basename($cardUri, '.vcf'); + $uid = VObjectUtils::uri2uid($cardUri, '.vcf'); // search all folders for the given card if ($addressBookId == '__all__') { @@ -319,7 +319,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend if ($contact) { return array( 'id' => $contact['uid'], - 'uri' => $contact['uid'] . '.vcf', + 'uri' => VObjectUtils::uid2uri($contact['uid'], '.vcf'), 'lastmodified' => is_a($contact['changed'], 'DateTime') ? $contact['changed']->format('U') : null, 'carddata' => $this->to_vcard($contact), 'etag' => self::_get_etag($contact), @@ -356,7 +356,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend { console(__METHOD__, $addressBookId, $cardUri, $cardData); - $uid = basename($cardUri, '.vcf'); + $uid = VObjectUtils::uri2uid($cardUri, '.vcf'); $storage = $this->get_storage_folder($addressBookId); $object = $this->parse_vcard($cardData, $uid); @@ -365,7 +365,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend } // if URI doesn't match the content's UID, the object might already exist! - $cardUri = $object['uid'] . '.vcf'; + $cardUri = VObjectUtils::uid2uri($object['uid'], '.vcf'); if ($object['uid'] != $uid && $this->getCard($addressBookId, $cardUri)) { Plugin::$redirect_basename = $cardUri; return $this->updateCard($addressBookId, $cardUri, $cardData); @@ -415,7 +415,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend { console(__METHOD__, $addressBookId, $cardUri, $cardData); - $uid = basename($cardUri, '.vcf'); + $uid = VObjectUtils::uri2uid($cardUri, '.vcf'); $object = $this->parse_vcard($cardData, $uid); // sanity check @@ -485,7 +485,7 @@ class ContactsBackend extends CardDAV\Backend\AbstractBackend { console(__METHOD__, $addressBookId, $cardUri); - $uid = basename($cardUri, '.vcf'); + $uid = VObjectUtils::uri2uid($cardUri, '.vcf'); if ($addressBookId == '__all__') { $this->get_card_by_uid($uid, $storage); diff --git a/lib/Kolab/CardDAV/LDAPDirectory.php b/lib/Kolab/CardDAV/LDAPDirectory.php index 6b41755..ca175f2 100644 --- a/lib/Kolab/CardDAV/LDAPDirectory.php +++ b/lib/Kolab/CardDAV/LDAPDirectory.php @@ -33,6 +33,7 @@ use \rcube_ldap_generic; use Sabre\DAV; use Sabre\DAVACL; use Sabre\CardDAV\Property; +use Kolab\Utils\VObjectUtils; /** * CardDAV Directory Gateway implementation @@ -126,7 +127,7 @@ class LDAPDirectory extends DAV\Collection implements \Sabre\CardDAV\IDirectory, { console(__METHOD__, $cardUri); - $uid = basename($cardUri, '.vcf'); + $uid = VObjectUtils::uri2uid($cardUri, '.vcf'); $record = null; // get from cache @@ -138,7 +139,7 @@ class LDAPDirectory extends DAV\Collection implements \Sabre\CardDAV\IDirectory, if ($contact = $this->getContactObject($uid)) { $obj = array( 'id' => $contact['uid'], - 'uri' => $contact['uid'] . '.vcf', + 'uri' => VObjectUtils::uid2uri($contact['uid'], '.vcf'), 'lastmodified' => $contact['_timestamp'], 'carddata' => $this->carddavBackend->to_vcard($contact), 'etag' => self::_get_etag($contact), @@ -199,7 +200,7 @@ class LDAPDirectory extends DAV\Collection implements \Sabre\CardDAV\IDirectory, foreach ($cached_index as $uid => $c) { $obj = array( 'id' => $uid, - 'uri' => $uid . '.vcf', + 'uri' => VObjectUtils::uid2uri($uid, '.vcf'), 'etag' => $c[1], 'lastmodified' => $c[2], ); @@ -233,7 +234,7 @@ class LDAPDirectory extends DAV\Collection implements \Sabre\CardDAV\IDirectory, $obj = array( 'id' => $contact['uid'], - 'uri' => $contact['uid'] . '.vcf', + 'uri' => VObjectUtils::uid2uri($contact['uid'], '.vcf'), 'lastmodified' => $contact['_timestamp'], 'carddata' => $this->carddavBackend->to_vcard($contact), 'etag' => self::_get_etag($contact), diff --git a/lib/Kolab/Utils/VObjectUtils.php b/lib/Kolab/Utils/VObjectUtils.php index f04884e..82f934b 100644 --- a/lib/Kolab/Utils/VObjectUtils.php +++ b/lib/Kolab/Utils/VObjectUtils.php @@ -30,6 +30,30 @@ use Sabre\VObject\Property; */ class VObjectUtils { + /** + * Convert an object URI into a valid UID value + */ + public static function uri2uid($uri, $suffix = '') + { + $base = basename($uri, $suffix); + $uid = strtr($base, array('%2F' => '/')); + + // assume full URL encoding + if (preg_match('/%[A-F0-9]{2}/', $uid)) { + return urldecode($base); + } + + return $uid; + } + + /** + * Encode an object UID into a valid URI + */ + public static function uid2uri($uid, $suffix = '') + { + $encode = strpos($uid, '/') !== false; + return ($encode ? urlencode($uid) : $uid) . $suffix; + } /** * Create a Sabre\VObject\Property instance from a PHP DateTime object |