Overview

Request 2659 (accepted)

Check in version 2.3.16


kolab-syncroton.spec Changed
x
 
1
@@ -36,8 +36,8 @@
2
 %global _ap_sysconfdir %{_sysconfdir}/%{httpd_name}
3
 
4
 Name:           kolab-syncroton
5
-Version:        2.3.15
6
-Release:        2%{?dist}
7
+Version:        2.3.16
8
+Release:        1%{?dist}
9
 Summary:        ActiveSync for Kolab Groupware
10
 
11
 Group:          Applications/Internet
12
@@ -50,8 +50,6 @@
13
 
14
 Patch0:         defaults.patch
15
 
16
-Patch0001:      0001-Accept-MeetingResponse-commands-from-within-the-iOS-.patch
17
-
18
 BuildArch:      noarch
19
 
20
 # Use this build requirement to make sure we are using
21
@@ -101,8 +99,6 @@
22
 
23
 %patch0 -p1
24
 
25
-%patch0001 -p1
26
-
27
 %build
28
 
29
 %install
30
@@ -211,6 +207,9 @@
31
 %attr(0770,%{httpd_user},%{httpd_group}) %{_var}/log/%{name}
32
 
33
 %changelog
34
+* Wed Dec  4 2019 Jeroen van Meeuwen <vanmeeuwen@kolabsys.com> - 2.3.16-1
35
+- Release version 2.3.16
36
+
37
 * Mon Jul 29 2019 Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com> - 2.3.15-3
38
 - Fix MeetingResponse for Calendar events
39
 
40
0001-Accept-MeetingResponse-commands-from-within-the-iOS-.patch Deleted
93
 
1
@@ -1,91 +0,0 @@
2
-From 882701777baf1991e5c33bf55b5b1985794fa67b Mon Sep 17 00:00:00 2001
3
-From: Jeroen van Meeuwen <kanarip@kanarip.ch>
4
-Date: Mon, 29 Jul 2019 11:57:09 +0200
5
-Subject: [PATCH] Accept MeetingResponse commands from within the iOS calendar
6
- application.
7
-
8
-Summary: Resolves Bifrost#T228115
9
-
10
-Test Plan:
11
-* Configure an ActiveSync account on an iOS device.
12
-
13
-* Create an invitation from another user with the current user as a participant.
14
-
15
-* Synchronize the iOS device.
16
-
17
-* Click or edit the event in the calendar to change from/to Accepted/Tentative (Maybe)/Decline.
18
-
19
-* Refresh web interface and view event details.
20
-
21
-* As the organizer, expect a response.
22
-
23
-Reviewers: #syncroton_developers
24
-
25
-Subscribers: #syncroton_developers
26
-
27
-Differential Revision: https://git.kolab.org/D773
28
----
29
- lib/kolab_sync_data_calendar.php | 26 ++++++++++++++++++++++----
30
- 1 file changed, 22 insertions(+), 4 deletions(-)
31
-
32
-diff --git a/lib/kolab_sync_data_calendar.php b/lib/kolab_sync_data_calendar.php
33
-index e822c73..010dc23 100644
34
---- a/lib/kolab_sync_data_calendar.php
35
-+++ b/lib/kolab_sync_data_calendar.php
36
-@@ -596,7 +596,11 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data
37
-             $event = $this->get_event_from_invitation($request);
38
- 
39
-             // find the event in calendar
40
--            $existing = $this->find_event_by_uid($event['uid']);
41
-+            if (array_key_exists('uid', $event)) {
42
-+                $existing = $this->find_event_by_uid($event['uid']);
43
-+            } else {
44
-+                $existing = $this->find_event_by_uid($event->uID);
45
-+            }
46
- /*
47
-             switch ($status) {
48
-                 case 'ACCEPTED':  $event['free_busy'] = 'busy';      break;
49
-@@ -665,7 +669,11 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data
50
-         //        as it's expected by the specification. Server
51
-         //        should delete an event in such a case, but we
52
-         //        keep the event copy with appropriate attendee status instead.
53
--        return empty($status) ? null : $this->serverId($event['uid'], $folder);
54
-+        return empty($status) ? null : (
55
-+            array_key_exists('uid', $event) ?
56
-+                $this->serverId($event['uid'], $folder) :
57
-+                $this->serverId($event->uID, $folder)
58
-+        );
59
-     }
60
- 
61
-     /**
62
-@@ -684,6 +692,14 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data
63
-                 return $event;
64
-             }
65
- 
66
-+            $collection = new Syncroton_Model_SyncCollection(
67
-+                array('collectionId' => $request->collectionId)
68
-+            );
69
-+
70
-+            if ($event = $this->getEntry($collection, $request->requestId)) {
71
-+                return $event;
72
-+            }
73
-+
74
-             throw new Syncroton_Exception_Status_MeetingResponse(Syncroton_Exception_Status_MeetingResponse::INVALID_REQUEST);
75
-         }
76
- 
77
-@@ -723,8 +739,10 @@ class kolab_sync_data_calendar extends kolab_sync_data implements Syncroton_Data
78
- 
79
-         $this->update_attendee_status($old, $status);
80
- 
81
--        if ($event['free_busy']) {
82
--            $old['free_busy'] = $event['free_busy'];
83
-+        if (array_key_exists('free_busy', $event)) {
84
-+            if ($event['free_busy']) {
85
-+                $old['free_busy'] = $event['free_busy'];
86
-+            }
87
-         }
88
- 
89
-         // Updating an existing event is most-likely a response
90
--- 
91
-2.20.1
92
-
93
debian.changelog Changed
11
 
1
@@ -1,3 +1,9 @@
2
+kolab-syncroton (2.3.16-0~kolab1) unstable; urgency=low
3
+
4
+  * Release version 2.3.16
5
+
6
+ -- Jeroen van Meeuwen <vanmeeuwen@kolabsys.com>  Wed,  4 Dec 2019 15:13:40 +0200
7
+
8
 kolab-syncroton (2.3.15-0~kolab6) unstable; urgency=low
9
 
10
   * Fix MeetingResponse parsing for Calendar events
11
debian.series Changed
4
 
1
@@ -1,2 +1,1 @@
2
 defaults.patch -p1
3
-0001-Accept-MeetingResponse-commands-from-within-the-iOS-.patch -p1
4
kolab-syncroton-2.3.15.tar.gz/config/config.inc.php.dist -> kolab-syncroton-2.3.16.tar.gz/config/config.inc.php.dist Changed
38
 
1
@@ -67,7 +67,10 @@
2
 
3
 // List of Roundcube plugins
4
 // WARNING: Not all plugins used in Roundcube can be listed here
5
-$config['activesync_plugins'] = array();
6
+$config['activesync_plugins'] = array(
7
+    'libcalendaring',
8
+    'libkolab'
9
+);
10
 
11
 // Defines for how many seconds we'll sleep between every
12
 // action for detecting changes in folders. Default: 60
13
@@ -97,13 +100,13 @@
14
 //     8 - all folders in other users namespace
15
 //    16 - all subscribed folders in shared namespace
16
 //    32 - all folders in shared namespace
17
-$config['activesync_init_subscriptions'] = 0;
18
+$config['activesync_init_subscriptions'] = 21;
19
 
20
 // Defines blacklist of devices (device type strings) that do not support folder hierarchies.
21
 // When set to an array folder hierarchies are used on all devices not listed here.
22
 // When set to null an old whitelist approach will be used where we do opposite
23
 // action and enable folder hierarchies only on device types known to support it.
24
-$config['activesync_multifolder_blacklist'] = null;
25
+$config['activesync_multifolder_blacklist'] = array();
26
 
27
 // Blacklist overwrites for specified object type. If set to an array
28
 // it will have a precedence over 'activesync_multifolder_blacklist' list only for that type.
29
@@ -111,7 +114,7 @@
30
 //       in that case use $config['activesync_multifolder_blacklist_contact'] = array('windowsoutlook');
31
 $config['activesync_multifolder_blacklist_mail'] = null;
32
 $config['activesync_multifolder_blacklist_event'] = null;
33
-$config['activesync_multifolder_blacklist_contact'] = null;
34
+$config['activesync_multifolder_blacklist_contact'] = array('windowsoutlook');
35
 $config['activesync_multifolder_blacklist_note'] = null;
36
 $config['activesync_multifolder_blacklist_task'] = null;
37
 
38
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/ItemOperations.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/ItemOperations.php Changed
20
 
1
@@ -59,9 +59,6 @@
2
                 $this->_emptyFolderContents[] = $this->_handleEmptyFolderContents($emptyFolderContents);
3
             }
4
         }
5
-        
6
-        if ($this->_logger instanceof Zend_Log) 
7
-            $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " fetches: " . print_r($this->_fetches, true));        
8
     }
9
     
10
     /**
11
@@ -118,7 +115,7 @@
12
                     $fileReference = $dataController->getFileReference($fetch['fileReference']);
13
                     
14
                     // unset data field and move content to stream
15
-                    if ($this->_requestParameters['acceptMultipart'] == true) {
16
+                    if (!empty($this->_requestParameters['acceptMultipart'])) {
17
                         $this->_headers['Content-Type'] = 'application/vnd.ms-sync.multipart';
18
                         
19
                         $partStream = fopen("php://temp", 'r+');
20
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/MeetingResponse.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/MeetingResponse.php Changed
11
 
1
@@ -50,9 +50,6 @@
2
                 );
3
             }
4
         }
5
-
6
-        if ($this->_logger instanceof Zend_Log)
7
-            $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " results: " . print_r($this->_results, true));
8
     }
9
 
10
     /**
11
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/MoveItems.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/MoveItems.php Changed
11
 
1
@@ -46,9 +46,6 @@
2
                 'dstFldId' => (string)$move->DstFldId
3
             );
4
         }
5
-
6
-        if ($this->_logger instanceof Zend_Log)
7
-            $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " moves: " . print_r($this->_moves, true));
8
     }
9
 
10
     /**
11
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/Ping.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/Ping.php Changed
22
 
1
@@ -141,6 +141,10 @@
2
                 // reconnect external connections, etc.
3
                 call_user_func($wakeupCallback);
4
 
5
+                // Calculate secondsLeft before any loop break just to have a correct value
6
+                // for logging purposes in case we breaked from the loop early
7
+                $secondsLeft = $intervalEnd - time();
8
+
9
                 try {
10
                     $device = $this->_deviceBackend->get($this->_device->id);
11
                 } catch (Syncroton_Exception_NotFound $e) {
12
@@ -237,7 +241,8 @@
13
                 if ($status != self::STATUS_NO_CHANGES_FOUND) {
14
                     break;
15
                 }
16
-                
17
+
18
+                // Update secondsLeft (again)
19
                 $secondsLeft = $intervalEnd - time();
20
                 
21
                 if ($this->_logger instanceof Zend_Log)
22
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/Search.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/Search.php Changed
11
 
1
@@ -39,9 +39,6 @@
2
         $xml = simplexml_import_dom($this->_requestBody);
3
 
4
         $this->_store = new Syncroton_Model_StoreRequest($xml->Store);
5
-
6
-        if ($this->_logger instanceof Zend_Log)
7
-            $this->_logger->debug(__METHOD__ . '::' . __LINE__ . " stores: " . print_r($this->_store, true));
8
     }
9
 
10
     /**
11
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/SendMail.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/SendMail.php Changed
10
 
1
@@ -32,7 +32,7 @@
2
      */
3
     public function handle()
4
     {
5
-        if ($this->_requestParameters['contentType'] == 'message/rfc822') {
6
+        if (!empty($this->_requestParameters['contentType']) && $this->_requestParameters['contentType'] == 'message/rfc822') {
7
             $this->_mime          = $this->_requestBody;
8
             $this->_saveInSent    = $this->_requestParameters['saveInSent'];
9
             $this->_replaceMime   = false;
10
kolab-syncroton-2.3.15.tar.gz/lib/ext/Syncroton/Command/Wbxml.php -> kolab-syncroton-2.3.16.tar.gz/lib/ext/Syncroton/Command/Wbxml.php Changed
12
 
1
@@ -143,8 +143,8 @@
2
         $this->_requestBody       = $requestBody;
3
         $this->_device            = $device;
4
         $this->_requestParameters = $requestParameters;
5
-        $this->_policyKey         = $requestParameters['policyKey'];
6
-        
7
+        $this->_policyKey         = isset($requestParameters['policyKey']) ? $requestParameters['policyKey'] : null;
8
+
9
         $this->_deviceBackend       = Syncroton_Registry::getDeviceBackend();
10
         $this->_folderBackend       = Syncroton_Registry::getFolderBackend();
11
         $this->_syncStateBackend    = Syncroton_Registry::getSyncStateBackend();
12
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync.php Changed
21
 
1
@@ -46,7 +46,7 @@
2
     public $password;
3
 
4
     const CHARSET = 'UTF-8';
5
-    const VERSION = "2.3.15";
6
+    const VERSION = "2.3.16";
7
 
8
 
9
     /**
10
@@ -232,7 +232,9 @@
11
             $err_str = $this->get_storage()->get_error_str();
12
         }
13
 
14
-        kolab_auth::log_login_error($auth['user'], $err_str ?: $err);
15
+        if (class_exists('kolab_auth', false)) {
16
+            kolab_auth::log_login_error($auth['user'], $err_str ?: $err);
17
+        }
18
 
19
         $this->plugins->exec_hook('login_failed', array(
20
             'host' => $auth['host'],
21
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync_data.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync_data.php Changed
59
 
1
@@ -428,6 +428,11 @@
2
             // Remove subfolders
3
             if (!empty($options['deleteSubFolders'])) {
4
                 $list = $this->listFolders($folderid);
5
+
6
+                if (!is_array($list)) {
7
+                    throw new Syncroton_Exception_Status_ItemOperations(Syncroton_Exception_Status_ItemOperations::ITEM_SERVER_ERROR);
8
+                }
9
+
10
                 foreach ($list as $folderid => $folder) {
11
                     $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid);
12
                     $folder     = $this->getFolderObject($foldername);
13
@@ -508,7 +513,7 @@
14
         $oldEntry = $this->getObject($folderId, $serverId);
15
 
16
         if (empty($oldEntry)) {
17
-            throw new Syncroton_Exception_NotFound('id not found');
18
+            throw new Syncroton_Exception_NotFound('entry not found');
19
         }
20
 
21
         $entry = $this->toKolab($entry, $folderId, $oldEntry);
22
@@ -947,6 +952,10 @@
23
     {
24
         $folders = $this->extractFolders($folderid);
25
 
26
+        if (empty($folders)) {
27
+            return null;
28
+        }
29
+
30
         foreach ($folders as $folderid) {
31
             $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid);
32
             $folder     = $this->getFolderObject($foldername);
33
@@ -1125,7 +1134,7 @@
34
                 $this->device->deviceid, $this->modelName, $this->isMultiFolder());
35
         }
36
 
37
-        if ($parentid === null) {
38
+        if ($parentid === null || !is_array($this->imap_folders)) {
39
             return $this->imap_folders;
40
         }
41
 
42
@@ -1675,8 +1684,14 @@
43
      */
44
     protected function recurrence_to_kolab($data, $folderid, $timezone = null)
45
     {
46
-        if (!($data->recurrence instanceof Syncroton_Model_EventRecurrence) || !isset($data->recurrence->type)) {
47
-            return null;
48
+        if (!($data->recurrence instanceof Syncroton_Model_EventRecurrence)
49
+            && !($data->recurrence instanceof Syncroton_Model_TaskRecurrence)
50
+        ) {
51
+            return;
52
+        }
53
+
54
+        if (!isset($data->recurrence->type)) {
55
+            return;
56
         }
57
 
58
         $recurrence = $data->recurrence;
59
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync_data_calendar.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync_data_calendar.php Changed
87
 
1
@@ -592,11 +592,8 @@
2
         );
3
 
4
         if ($status = $status_map[$request->userResponse]) {
5
-            // extract event data from the invitation
6
-            $event = $this->get_event_from_invitation($request);
7
-
8
-            // find the event in calendar
9
-            $existing = $this->find_event_by_uid($event['uid']);
10
+            // extract event from the invitation
11
+            list($event, $existing) = $this->get_event_from_invitation($request);
12
 /*
13
             switch ($status) {
14
                 case 'ACCEPTED':  $event['free_busy'] = 'busy';      break;
15
@@ -669,19 +666,26 @@
16
     }
17
 
18
     /**
19
-     * Get an event from the invitation email
20
+     * Get an event from the invitation email or calendar folder
21
      */
22
     protected function get_event_from_invitation(Syncroton_Model_MeetingResponse $request)
23
     {
24
-        // Limitations:
25
-        // 1. The meeting request may be in an iTip or the calendar event
26
-        // For now we support iTips only here
27
-        // 2. LongId might be used instead of RequestId, this is not supported
28
+        // Limitation: LongId might be used instead of RequestId, this is not supported
29
+
30
         if ($request->requestId) {
31
             $mail_class = new kolab_sync_data_email($this->device, $this->syncTimeStamp);
32
 
33
+            // Event from an invitation email
34
             if ($event = $mail_class->get_invitation_event($request->requestId)) {
35
-                return $event;
36
+                // find the event in calendar
37
+                $existing = $this->find_event_by_uid($event['uid']);
38
+
39
+                return array($event, $existing);
40
+            }
41
+
42
+            // Event from calendar folder
43
+            if ($event = $this->getObject($request->collectionId, $request->requestId, $folder)) {
44
+                return array($event, $event);
45
             }
46
 
47
             throw new Syncroton_Exception_Status_MeetingResponse(Syncroton_Exception_Status_MeetingResponse::INVALID_REQUEST);
48
@@ -721,8 +725,6 @@
49
             throw new Syncroton_Exception_Status_MeetingResponse(Syncroton_Exception_Status_MeetingResponse::INVALID_REQUEST);
50
         }
51
 
52
-        $this->update_attendee_status($old, $status);
53
-
54
         if ($event['free_busy']) {
55
             $old['free_busy'] = $event['free_busy'];
56
         }
57
@@ -731,10 +733,8 @@
58
         // to an iTip request with bumped SEQUENCE
59
         $old['sequence'] += 1;
60
 
61
-        // TODO: Free/busy trigger?
62
-
63
         // Update the event
64
-        return $this->save_event($old);
65
+        return $this->save_event($old, $status);
66
     }
67
 
68
     /**
69
@@ -744,7 +744,7 @@
70
     protected function save_event(&$event, $status = null)
71
     {
72
         // Find default folder to which we'll save the event
73
-        if (empty($event['_mailbox'])) {
74
+        if (!isset($event['_mailbox'])) {
75
             $folders = $this->listFolders();
76
             $storage = rcube::get_instance()->get_storage();
77
 
78
@@ -774,6 +774,8 @@
79
             $this->update_attendee_status($event, $status);
80
         }
81
 
82
+        // TODO: Free/busy trigger?
83
+
84
         if (isset($event['_mailbox'])) {
85
             $folder = $this->getFolderObject($event['_mailbox']);
86
 
87
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync_data_contacts.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync_data_contacts.php Changed
10
 
1
@@ -168,7 +168,7 @@
2
                 if ($value) {
3
                     // ActiveSync limits photo size to 48KB (of base64 encoded string)
4
                     if (strlen($value) * 1.33 > 48 * 1024) {
5
-                        continue;
6
+                        continue 2;
7
                     }
8
                 }
9
                 break;
10
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync_data_email.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync_data_email.php Changed
148
 
1
@@ -131,6 +131,10 @@
2
 
3
         $headers = $message->headers; // rcube_message_header
4
 
5
+        $this->storage->set_folder($message->folder);
6
+
7
+        $this->logger->debug(sprintf("Processing message %s (size: %.2f MB)", $serverId, $headers->size / 1024 / 1024));
8
+
9
         // Calendar namespace fields
10
         foreach ($this->mapping as $key => $name) {
11
             $value = null;
12
@@ -187,6 +191,8 @@
13
                 'flagType' => 'FollowUp',
14
                 'status'   => Syncroton_Model_EmailFlag::STATUS_ACTIVE,
15
             ));
16
+        } else {
17
+            $result['flag'] = new Syncroton_Model_EmailFlag();
18
         }
19
 
20
         // Importance/Priority
21
@@ -274,15 +280,22 @@
22
         // only it's estimated size
23
         if (empty($prefs)) {
24
             $messageBody = '';
25
-            $real_length = $message->size;
26
+            $real_length = $headers->size;
27
             $truncateAt  = 0;
28
             $body_length = 0;
29
             $isTruncated = 1;
30
         }
31
         else if ($airSyncBaseType == Syncroton_Command_Sync::BODY_TYPE_MIME) {
32
-            $messageBody = $this->storage->get_raw_body($message->uid);
33
+            // Check if we have enough memory to handle the message
34
+            $messageBody = $this->message_mem_check($message, $headers->size);
35
+
36
+            if (empty($messageBody)) {
37
+                $messageBody = $this->storage->get_raw_body($message->uid);
38
+            }
39
+
40
             // make the source safe (Bug #2715, #2757)
41
             $messageBody = kolab_sync_message::recode_message($messageBody);
42
+
43
             // strip out any non utf-8 characters
44
             $messageBody = rcube_charset::clean($messageBody);
45
             $real_length = $body_length = strlen($messageBody);
46
@@ -1231,12 +1244,17 @@
47
             $entryid = $entryid['itemId'];
48
         }
49
 
50
+        // Note: the id might be in a form of <folder>::<uid>[::<part_id>]
51
         list($folderid, $uid) = explode('::', $entryid);
52
+
53
+        if (empty($uid)) {
54
+            return;
55
+        }
56
+
57
         $foldername = $this->backend->folder_id2name($folderid, $this->device->deviceid);
58
 
59
         if ($foldername === null || $foldername === false) {
60
-            // @TODO exception?
61
-            return null;
62
+            return;
63
         }
64
 
65
         return array(
66
@@ -1283,12 +1301,11 @@
67
     protected function getMessagePartBody($message, $part, $html = false)
68
     {
69
         // Check if we have enough memory to handle the message in it
70
-        // @FIXME: we need up to 5x more memory than the body
71
-        if (!rcube_utils::mem_check($part->size * 5)) {
72
-            return '';
73
-        }
74
+        $body = $this->message_mem_check($message, $part->size, false);
75
 
76
-        $body = $message->get_part_body($part->mime_id, true);
77
+        if ($body !== false) {
78
+            $body = $message->get_part_body($part->mime_id, true);
79
+        }
80
 
81
         // message is cached but not exists, or other error
82
         if ($body === false) {
83
@@ -1643,4 +1660,64 @@
84
             }
85
         }
86
     }
87
+
88
+    /**
89
+     * Checks if the message can be processed, depending on its size and
90
+     * memory_limit, otherwise throws an exception or returns fake body.
91
+     */
92
+    protected function message_mem_check($message, $size, $result = null)
93
+    {
94
+        static $memory_rised;
95
+
96
+        // @FIXME: we need up to 5x more memory than the body
97
+        // Note: Biggest memory multiplication happens in recode_message()
98
+        //       and the Syncroton engine (which also does not support passing bodies
99
+        //       as streams). It also happens when parsing the plain/html text body
100
+        //       in getMessagePartBody() though the footprint there is probably lower.
101
+
102
+        if (!rcube_utils::mem_check($size * 5)) {
103
+            // If we already rised the memory we throw an exception, so the message
104
+            // will be synchronized in the next run (then we might have enough memory)
105
+            if ($memory_rised) {
106
+                throw new Syncroton_Exception_MemoryExhausted;
107
+            }
108
+
109
+            $memory_rised  = true;
110
+            $memory_max    = 512; // maximum in MB
111
+            $memory_limit  = round(parse_bytes(ini_get('memory_limit')) / 1024 / 1024); // current limit (in MB)
112
+            $memory_add    = round($size * 5 / 1024 / 1024); // how much we need (in MB)
113
+            $memory_needed = min($memory_limit + $memory_add, $memory_max) . "M";
114
+
115
+            if ($memory_limit < $memory_max) {
116
+                $this->logger->debug("Setting memory_limit=$memory_needed");
117
+
118
+                if (ini_set('memory_limit', $memory_needed) !== false) {
119
+                    // Memory has been rised, check again
120
+                    if (rcube_utils::mem_check($size * 5)) {
121
+                        return;
122
+                    }
123
+                }
124
+            }
125
+
126
+            $this->logger->warn("Not enough memory. Using fake email body.");
127
+
128
+            if ($result !== null) {
129
+                return $result;
130
+            }
131
+
132
+            // Let's return a fake message. If we return an empty body Outlook
133
+            // will not list the message at all. This way user can do something
134
+            // with the message (flag, delete, move) and see the reason why it's fake
135
+            // and importantly see its subject, sender, etc.
136
+            // TODO: Localization?
137
+            $msg = "This message is too large for ActiveSync.";
138
+            // $msg .= "See https://kb.kolabenterprise.com/documentation/some-place for more information.";
139
+
140
+            // Get original message headers
141
+            $headers = $this->storage->get_raw_headers($message->uid);
142
+
143
+            // Build a fake message with original headers, but changed body
144
+            return kolab_sync_message::fake_message($headers, $msg);
145
+        }
146
+    }
147
 }
148
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync_data_gal.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync_data_gal.php Changed
10
 
1
@@ -153,7 +153,7 @@
2
                 }
3
 
4
                 if (strlen($value) > $maxsize) {
5
-                    continue;
6
+                    continue 2;
7
                 }
8
 
9
                 $value = new Syncroton_Model_GALPicture(array(
10
kolab-syncroton-2.3.15.tar.gz/lib/kolab_sync_message.php -> kolab-syncroton-2.3.16.tar.gz/lib/kolab_sync_message.php Changed
31
 
1
@@ -347,6 +347,29 @@
2
     }
3
 
4
     /**
5
+     * Creates a fake plain text message source with predefined headers and body
6
+     *
7
+     * @param string $headers Message headers
8
+     * @param string $body    Plain text body
9
+     *
10
+     * @return string Message source
11
+     */
12
+    public static function fake_message($headers, $body = '')
13
+    {
14
+        $hdrs   = self::parse_headers($headers);
15
+        $result = '';
16
+
17
+        $hdrs['Content-Type']              = 'text/plain; charset=UTF-8';
18
+        $hdrs['Content-Transfer-Encoding'] = 'quoted-printable';
19
+
20
+        foreach ($hdrs as $header => $header_value) {
21
+            $result .= $header . ': ' . $header_value . "\r\n";
22
+        }
23
+
24
+        return $result . "\r\n" . self::encode($body, 'quoted-printable');
25
+    }
26
+
27
+    /**
28
      * MIME message parser
29
      *
30
      * @param string|resource $message     MIME message source
31
kolab-syncroton.dsc Changed
21
 
1
@@ -2,9 +2,9 @@
2
 Source: kolab-syncroton
3
 Binary: kolab-syncroton
4
 Architecture: all
5
-Version: 2.3.15-0~kolab6
6
-Maintainer: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>
7
-Uploaders: Jeroen van Meeuwen (Kolab Systems) <vanmeeuwen@kolabsys.com>
8
+Version: 2.3.16-0~kolab1
9
+Maintainer: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com>
10
+Uploaders: Jeroen van Meeuwen <vanmeeuwen@kolabsys.com>
11
 Homepage: http://www.kolab.org/
12
 Standards-Version: 3.9.3
13
 Vcs-Git: http://git.kolab.org/kolab-syncroton
14
@@ -12,5 +12,5 @@
15
 Package-List:
16
  kolab-syncroton deb utils extra
17
 Files:
18
- 00000000000000000000000000000000 0 kolab-syncroton-2.3.15.tar.gz
19
+ 00000000000000000000000000000000 0 kolab-syncroton-2.3.16.tar.gz
20
  00000000000000000000000000000000 0 debian.tar.gz
21
Refresh


Request History
Jeroen van Meeuwen's avatar

vanmeeuwen created request over 5 years ago

Check in version 2.3.16


Jeroen van Meeuwen's avatar

vanmeeuwen accepted review over 5 years ago

Accept


Jeroen van Meeuwen's avatar

vanmeeuwen accepted review over 5 years ago

Accept


Jeroen van Meeuwen's avatar

vanmeeuwen approved review over 5 years ago

Accept


Jeroen van Meeuwen's avatar

vanmeeuwen accepted request over 5 years ago

Accept