Hello community,

here is the log from the commit of package evolution-data-server for 
openSUSE:Factory checked in at 2018-07-19 22:49:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/evolution-data-server (Old)
 and      /work/SRC/openSUSE:Factory/.evolution-data-server.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "evolution-data-server"

Thu Jul 19 22:49:00 2018 rev:193 rq:623617 version:3.28.4

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/evolution-data-server/evolution-data-server.changes  
    2018-06-22 13:28:00.954989470 +0200
+++ 
/work/SRC/openSUSE:Factory/.evolution-data-server.new/evolution-data-server.changes
 2018-07-19 22:49:01.999142914 +0200
@@ -1,0 +2,14 @@
+Mon Jul 16 18:22:18 UTC 2018 - [email protected]
+
+- Update to version 3.28.4:
+  + Make sure errors reported from backends are valid UTF-8
+    strings.
+  + [CamelSMIMEContext] Fix a memory leak.
+  + [IMAPx] Search for whole word "Cyrus" when parsing version from
+    the server response.
+  + Bugs fixed: bgo#796174, bgo#702127,
+    glgo#GNOME/evolution-data-server#12,
+    glgo#GNOME/evolution-data-server#13,
+    glgo#GNOME/evolution-data-server#14.
+
+-------------------------------------------------------------------

Old:
----
  evolution-data-server-3.28.3.tar.xz

New:
----
  evolution-data-server-3.28.4.tar.xz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ evolution-data-server.spec ++++++
--- /var/tmp/diff_new_pack.9hi9nS/_old  2018-07-19 22:49:02.859140107 +0200
+++ /var/tmp/diff_new_pack.9hi9nS/_new  2018-07-19 22:49:02.871140068 +0200
@@ -30,7 +30,7 @@
 %define so_edata_cal 28
 %define _evo_version 3.28
 Name:           evolution-data-server
-Version:        3.28.3
+Version:        3.28.4
 Release:        0
 Summary:        Evolution Data Server
 License:        LGPL-2.1-or-later

++++++ evolution-data-server-3.28.3.tar.xz -> 
evolution-data-server-3.28.4.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/evolution-data-server-3.28.3/CMakeLists.txt 
new/evolution-data-server-3.28.4/CMakeLists.txt
--- old/evolution-data-server-3.28.3/CMakeLists.txt     2018-06-18 
10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/CMakeLists.txt     2018-07-16 
12:42:35.000000000 +0200
@@ -4,7 +4,7 @@
 cmake_policy(VERSION 3.1)
 
 project(evolution-data-server
-       VERSION 3.28.3
+       VERSION 3.28.4
        LANGUAGES C CXX)
 set(CMAKE_CXX_STANDARD 14)
 set(PROJECT_BUGREPORT 
"https://gitlab.gnome.org/GNOME/evolution-data-server/issues/";)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/evolution-data-server-3.28.3/NEWS 
new/evolution-data-server-3.28.4/NEWS
--- old/evolution-data-server-3.28.3/NEWS       2018-06-18 10:48:43.000000000 
+0200
+++ new/evolution-data-server-3.28.4/NEWS       2018-07-16 12:42:35.000000000 
+0200
@@ -1,3 +1,18 @@
+Evolution-Data-Server 3.28.4 2018-07-16
+---------------------------------------
+
+Bug Fixes:
+       Bug 796174 - strcat() considered unsafe for buffer overflow (Milan Crha)
+       Bug 702127 - Crash under cal_backend_store_save_cache_now() ][ (Milan 
Crha)
+       I#12 - vCard REV attribute should be a timestamp (Milan Crha)
+       I#13 - [IMAPx] Fails to append message to Yahoo! with no CRLF at the 
end (Milan Crha)
+       I#14 - [IMAPx] Use extended LIST with Cyrus IMAP >= 2.5.11 (Milan Crha)
+
+Miscellaneous:
+       Make sure errors reported from backends are valid UTF-8 strings (Milan 
Crha)
+       [CamelSMIMEContext] Fix a memory leak (Milan Crha)
+       [IMAPx] Search for whole word "Cyrus" when parsing version from the 
server response (Milan Crha)
+
 Evolution-Data-Server 3.28.3 2018-06-18
 ---------------------------------------
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/addressbook/backends/file/e-book-backend-file.c
 
new/evolution-data-server-3.28.4/src/addressbook/backends/file/e-book-backend-file.c
--- 
old/evolution-data-server-3.28.3/src/addressbook/backends/file/e-book-backend-file.c
        2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/addressbook/backends/file/e-book-backend-file.c
        2018-07-16 12:42:35.000000000 +0200
@@ -80,7 +80,7 @@
        gchar     *photo_dirname;
        gchar     *revision;
        gchar     *locale;
-       gint       rev_counter;
+       volatile gint rev_counter;
        gboolean   revision_guards;
        GRWLock    lock;
        GList     *cursors;
@@ -643,7 +643,8 @@
 }
 
 static gchar *
-e_book_backend_file_new_revision (EBookBackendFile *bf)
+e_book_backend_file_new_revision (EBookBackendFile *bf,
+                                 gboolean with_counter)
 {
        gchar time_string[100] = {0};
        const struct tm *tm = NULL;
@@ -654,7 +655,10 @@
        if (tm)
                strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", tm);
 
-       return g_strdup_printf ("%s(%d)", time_string, bf->priv->rev_counter++);
+       if (with_counter)
+               return g_strdup_printf ("%s(%d)", time_string, g_atomic_int_add 
(&bf->priv->rev_counter, 1));
+
+       return g_strdup (time_string);
 }
 
 /* For now just bump the revision and set it in the DB every
@@ -670,7 +674,7 @@
        gchar *new_revision;
        gboolean success;
 
-       new_revision = e_book_backend_file_new_revision (bf);
+       new_revision = e_book_backend_file_new_revision (bf, TRUE);
        success = e_book_sqlite_set_key_value (
                bf->priv->sqlitedb,
                SQLITE_REVISION_KEY,
@@ -734,7 +738,7 @@
 {
        gchar *rev;
 
-       rev = e_book_backend_file_new_revision (bf);
+       rev = e_book_backend_file_new_revision (bf, FALSE);
        e_contact_set (contact, E_CONTACT_REV, rev);
        g_free (rev);
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/addressbook/backends/google/e-book-backend-google.c
 
new/evolution-data-server-3.28.4/src/addressbook/backends/google/e-book-backend-google.c
--- 
old/evolution-data-server-3.28.3/src/addressbook/backends/google/e-book-backend-google.c
    2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/addressbook/backends/google/e-book-backend-google.c
    2018-07-16 12:42:35.000000000 +0200
@@ -33,6 +33,15 @@
 #include "e-book-backend-google.h"
 #include "e-book-google-utils.h"
 
+#ifdef G_OS_WIN32
+#ifdef gmtime_r
+#undef gmtime_r
+#endif
+
+/* The gmtime() in Microsoft's C library is MT-safe */
+#define gmtime_r(tp,tmp) (gmtime(tp)?(*(tmp)=*gmtime(tp),(tmp)):0)
+#endif
+
 #define URI_GET_CONTACTS 
"https://www.google.com/m8/feeds/contacts/default/full";
 
 G_DEFINE_TYPE (EBookBackendGoogle, e_book_backend_google, 
E_TYPE_BOOK_META_BACKEND)
@@ -540,7 +549,9 @@
                                if (cached_contact) {
                                        gchar *old_etag;
 
-                                       old_etag = e_contact_get 
(cached_contact, E_CONTACT_REV);
+                                       old_etag = e_vcard_util_dup_x_attribute 
(E_VCARD (cached_contact), E_GOOGLE_X_ETAG);
+                                       if (!old_etag)
+                                               old_etag = e_contact_get 
(cached_contact, E_CONTACT_REV);
 
                                        if (g_strcmp0 (gdata_entry_get_etag 
(GDATA_ENTRY (gdata_contact)), old_etag) == 0) {
                                                g_object_unref (cached_contact);
@@ -558,8 +569,8 @@
                                g_rec_mutex_unlock 
(&bbgoogle->priv->groups_lock);
 
                                if (new_contact) {
-                                       const gchar *revision, *photo_etag;
-                                       gchar *object, *extra;
+                                       const gchar *etag, *photo_etag;
+                                       gchar *object, *revision, *extra;
 
                                        photo_etag = 
gdata_contacts_contact_get_photo_etag (gdata_contact);
                                        if (photo_etag && cached_contact) {
@@ -616,7 +627,9 @@
                                                }
                                        }
 
-                                       revision = gdata_entry_get_etag 
(GDATA_ENTRY (gdata_contact));
+                                       etag = gdata_entry_get_etag 
(GDATA_ENTRY (gdata_contact));
+                                       e_vcard_util_set_x_attribute (E_VCARD 
(new_contact), E_GOOGLE_X_ETAG, etag);
+                                       revision = 
e_book_google_utils_time_to_revision (gdata_entry_get_updated (GDATA_ENTRY 
(gdata_contact)));
                                        e_contact_set (new_contact, 
E_CONTACT_REV, revision);
                                        object = e_vcard_to_string (E_VCARD 
(new_contact), EVC_FORMAT_VCARD_30);
                                        extra = gdata_parsable_get_xml 
(GDATA_PARSABLE (gdata_contact));
@@ -629,6 +642,7 @@
                                                        
e_book_meta_backend_info_new (uid, revision, object, extra));
                                        }
 
+                                       g_free (revision);
                                        g_free (object);
                                        g_free (extra);
                                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/addressbook/backends/google/e-book-google-utils.c
 
new/evolution-data-server-3.28.4/src/addressbook/backends/google/e-book-google-utils.c
--- 
old/evolution-data-server-3.28.3/src/addressbook/backends/google/e-book-google-utils.c
      2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/addressbook/backends/google/e-book-google-utils.c
      2018-07-16 12:42:35.000000000 +0200
@@ -581,6 +581,8 @@
        GHashTable *extended_props;
        GList *websites, *events;
        GDate bdate;
+       GDateTime *dt;
+       gchar *rev = NULL;
        gboolean bdate_has_year;
        gboolean have_uri_home = FALSE, have_uri_blog = FALSE;
 
@@ -603,27 +605,23 @@
        attr = e_vcard_attribute_new (NULL, EVC_UID);
        e_vcard_add_attribute_with_value (vcard, attr, uid);
 
+       if (gdata_entry_get_etag (entry))
+               e_vcard_util_set_x_attribute (vcard, E_GOOGLE_X_ETAG, 
gdata_entry_get_etag (entry));
+
        /* REV */
        attr = e_vcard_attribute_new (NULL, EVC_REV);
-       if (gdata_entry_get_etag (entry)) {
-               e_vcard_add_attribute_with_value (vcard, attr, 
gdata_entry_get_etag (entry));
-       } else {
-               GDateTime *dt;
-               gchar *rev = NULL;
-
-               dt = g_date_time_new_from_unix_utc (gdata_entry_get_updated 
(entry));
-               if (dt) {
-                       rev = g_date_time_format (dt, "%Y-%m-%dT%H:%M:%S");
-                       g_date_time_unref (dt);
-               }
+       dt = g_date_time_new_from_unix_utc (gdata_entry_get_updated (entry));
+       if (dt) {
+               rev = g_date_time_format (dt, "%Y-%m-%dT%H:%M:%SZ");
+               g_date_time_unref (dt);
+       }
 
-               if (!rev)
-                       rev = g_strdup_printf ("%" G_GINT64_FORMAT, 
gdata_entry_get_updated (entry));
+       if (!rev)
+               rev = g_strdup_printf ("%" G_GINT64_FORMAT, 
gdata_entry_get_updated (entry));
 
-               e_vcard_add_attribute_with_value (vcard, attr, rev);
+       e_vcard_add_attribute_with_value (vcard, attr, rev);
 
-               g_free (rev);
-       }
+       g_free (rev);
 
        /* FN, N */
        name = gdata_contacts_contact_get_name (GDATA_CONTACTS_CONTACT (entry));
@@ -1716,3 +1714,16 @@
                return g_strdup (gdata_entry_get_title (group));
        }
 }
+
+gchar *
+e_book_google_utils_time_to_revision (gint64 unix_time)
+{
+       struct tm stm;
+       time_t tt = (time_t) unix_time;
+       gchar time_string[100] = { 0 };
+
+       gmtime_r (&tt, &stm);
+       strftime (time_string, 100, "%Y-%m-%dT%H:%M:%SZ", &stm);
+
+       return g_strdup (time_string);
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/addressbook/backends/google/e-book-google-utils.h
 
new/evolution-data-server-3.28.4/src/addressbook/backends/google/e-book-google-utils.h
--- 
old/evolution-data-server-3.28.3/src/addressbook/backends/google/e-book-google-utils.h
      2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/addressbook/backends/google/e-book-google-utils.h
      2018-07-16 12:42:35.000000000 +0200
@@ -24,7 +24,8 @@
 
 #include "e-book-backend-google.h"
 
-#define E_GOOGLE_X_PHOTO_ETAG "X-EVOLUTION-GOOGLE-PHOTO-ETAG"
+#define E_GOOGLE_X_ETAG                "X-EVOLUTION-GOOGLE-ETAG"
+#define E_GOOGLE_X_PHOTO_ETAG  "X-EVOLUTION-GOOGLE-PHOTO-ETAG"
 
 G_BEGIN_DECLS
 
@@ -60,6 +61,8 @@
 gchar *e_contact_sanitise_google_group_id (const gchar *group_id) 
G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT;
 gchar *e_contact_sanitise_google_group_name (GDataEntry *group) G_GNUC_MALLOC 
G_GNUC_WARN_UNUSED_RESULT;
 
+gchar *                e_book_google_utils_time_to_revision    (gint64 
unix_time);
+
 G_END_DECLS
 
 #endif /* E_BOOK_GOOGLE_UTILS_H */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/addressbook/backends/ldap/e-book-backend-ldap.c
 
new/evolution-data-server-3.28.4/src/addressbook/backends/ldap/e-book-backend-ldap.c
--- 
old/evolution-data-server-3.28.3/src/addressbook/backends/ldap/e-book-backend-ldap.c
        2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/addressbook/backends/ldap/e-book-backend-ldap.c
        2018-07-16 12:42:35.000000000 +0200
@@ -3583,8 +3583,7 @@
 
                if (!strcmp (propname, "x-evolution-any-field")) {
                        gint i;
-                       gint query_length;
-                       gchar *big_query;
+                       GString *big_query;
                        gchar *match_str;
                        if (one_star) {
                                g_free (str);
@@ -3597,14 +3596,8 @@
 
                        match_str = g_strdup_printf ("=*%s*)", str);
 
-                       query_length = 3; /* strlen ("(|") + strlen (")") */
-
-                       for (i = 0; i < G_N_ELEMENTS (prop_info); i++) {
-                               query_length += 1 /* strlen ("(") */ + strlen 
(prop_info[i].ldap_attr) + strlen (match_str);
-                       }
-
-                       big_query = g_malloc0 (query_length + 1);
-                       strcat (big_query, "(|");
+                       big_query = g_string_sized_new (G_N_ELEMENTS 
(prop_info) * 7);
+                       g_string_append (big_query, "(|");
                        for (i = 0; i < G_N_ELEMENTS (prop_info); i++) {
                                if ((prop_info[i].prop_type & PROP_TYPE_STRING) 
!= 0 &&
                                    !(prop_info[i].prop_type & PROP_WRITE_ONLY) 
&&
@@ -3612,14 +3605,14 @@
                                     !(prop_info[i].prop_type & PROP_EVOLVE)) &&
                                    (ldap_data->bl->priv->calEntrySupported ||
                                     !(prop_info[i].prop_type & 
PROP_CALENTRY))) {
-                                       strcat (big_query, "(");
-                                       strcat (big_query, 
prop_info[i].ldap_attr);
-                                       strcat (big_query, match_str);
+                                       g_string_append (big_query, "(");
+                                       g_string_append (big_query, 
prop_info[i].ldap_attr);
+                                       g_string_append (big_query, match_str);
                                }
                        }
-                       strcat (big_query, ")");
+                       g_string_append (big_query, ")");
 
-                       ldap_data->list = g_list_prepend (ldap_data->list, 
big_query);
+                       ldap_data->list = g_list_prepend (ldap_data->list, 
g_string_free (big_query, FALSE));
 
                        g_free (match_str);
                }
@@ -3800,34 +3793,27 @@
 
                if (!strcmp (propname, "x-evolution-any-field")) {
                        gint i;
-                       gint query_length;
-                       gchar *big_query;
+                       GString *big_query;
                        gchar *match_str;
 
                        match_str = g_strdup ("=*)");
 
-                       query_length = 3; /* strlen ("(|") + strlen (")") */
-
-                       for (i = 0; i < G_N_ELEMENTS (prop_info); i++) {
-                               query_length += 1 /* strlen ("(") */ + strlen 
(prop_info[i].ldap_attr) + strlen (match_str);
-                       }
-
-                       big_query = g_malloc0 (query_length + 1);
-                       strcat (big_query, "(|");
+                       big_query = g_string_sized_new (G_N_ELEMENTS 
(prop_info) * 7);
+                       g_string_append (big_query, "(|");
                        for (i = 0; i < G_N_ELEMENTS (prop_info); i++) {
                                if (!(prop_info[i].prop_type & PROP_WRITE_ONLY) 
&&
                                    
(ldap_data->bl->priv->evolutionPersonSupported ||
                                     !(prop_info[i].prop_type & PROP_EVOLVE)) &&
                                    (ldap_data->bl->priv->calEntrySupported ||
                                     !(prop_info[i].prop_type & 
PROP_CALENTRY))) {
-                                       strcat (big_query, "(");
-                                       strcat (big_query, 
prop_info[i].ldap_attr);
-                                       strcat (big_query, match_str);
+                                       g_string_append (big_query, "(");
+                                       g_string_append (big_query, 
prop_info[i].ldap_attr);
+                                       g_string_append (big_query, match_str);
                                }
                        }
-                       strcat (big_query, ")");
+                       g_string_append (big_query, ")");
 
-                       ldap_data->list = g_list_prepend (ldap_data->list, 
big_query);
+                       ldap_data->list = g_list_prepend (ldap_data->list, 
g_string_free (big_query, FALSE));
 
                        g_free (match_str);
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/addressbook/libedata-book/e-data-book.c 
new/evolution-data-server-3.28.4/src/addressbook/libedata-book/e-data-book.c
--- 
old/evolution-data-server-3.28.3/src/addressbook/libedata-book/e-data-book.c    
    2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/addressbook/libedata-book/e-data-book.c    
    2018-07-16 12:42:35.000000000 +0200
@@ -1789,10 +1789,16 @@
 e_data_book_report_error (EDataBook *book,
                           const gchar *message)
 {
+       gchar *valid_utf8;
+
        g_return_if_fail (E_IS_DATA_BOOK (book));
        g_return_if_fail (message != NULL);
 
-       e_dbus_address_book_emit_error (book->priv->dbus_interface, message);
+       valid_utf8 = e_util_utf8_make_valid (message);
+
+       e_dbus_address_book_emit_error (book->priv->dbus_interface, valid_utf8 
? valid_utf8 : message);
+
+       g_free (valid_utf8);
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/calendar/libedata-cal/e-cal-backend-store.c
 
new/evolution-data-server-3.28.4/src/calendar/libedata-cal/e-cal-backend-store.c
--- 
old/evolution-data-server-3.28.3/src/calendar/libedata-cal/e-cal-backend-store.c
    2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/calendar/libedata-cal/e-cal-backend-store.c
    2018-07-16 12:42:35.000000000 +0200
@@ -373,52 +373,33 @@
        g_free (data);
 }
 
-static void
-cal_backend_store_toggle_ref_cb (gpointer data,
-                                GObject *object,
-                                gboolean is_last_ref)
-{
-       ECalBackendStore *store;
-
-       g_return_if_fail (E_IS_CAL_BACKEND_STORE (object));
-
-       if (!is_last_ref)
-               return;
-
-       store = E_CAL_BACKEND_STORE (object);
-
-       g_mutex_lock (&store->priv->save_timeout_lock);
-       g_object_ref (store);
-       g_object_remove_toggle_ref (G_OBJECT (store), 
cal_backend_store_toggle_ref_cb, NULL);
-       store->priv->dirty = TRUE;
-       store->priv->save_timeout_id = 0;
-       g_mutex_unlock (&store->priv->save_timeout_lock);
-
-       g_object_unref (store);
-}
-
 static gboolean
 cal_backend_store_save_cache_timeout_cb (gpointer user_data)
 {
-       ECalBackendStore *store;
+       GWeakRef *weakref = user_data;
        GSource *source;
+       ECalBackendStore *store;
        GList *timezones_to_save;
 
        source = g_main_current_source ();
        if (g_source_is_destroyed (source))
                return FALSE;
 
-       store = E_CAL_BACKEND_STORE (user_data);
+       g_return_val_if_fail (weakref != NULL, FALSE);
+
+       store = g_weak_ref_get (weakref);
+       if (!store)
+               return FALSE;
+
+       g_return_val_if_fail (E_IS_CAL_BACKEND_STORE (store), FALSE);
 
        g_mutex_lock (&store->priv->save_timeout_lock);
        if (store->priv->save_timeout_id != g_source_get_id (source)) {
                g_mutex_unlock (&store->priv->save_timeout_lock);
+               g_object_unref (store);
                return FALSE;
        }
 
-       g_object_ref (store);
-
-       g_object_remove_toggle_ref (G_OBJECT (store), 
cal_backend_store_toggle_ref_cb, NULL);
        store->priv->save_timeout_id = 0;
        timezones_to_save = store->priv->timezones_to_save;
        store->priv->timezones_to_save = NULL;
@@ -463,16 +444,13 @@
 
        g_mutex_lock (&store->priv->save_timeout_lock);
 
-       if (store->priv->save_timeout_id > 0) {
+       if (store->priv->save_timeout_id > 0)
                g_source_remove (store->priv->save_timeout_id);
-               g_object_remove_toggle_ref (G_OBJECT (store), 
cal_backend_store_toggle_ref_cb, NULL);
-       }
-
-       g_object_add_toggle_ref (G_OBJECT (store), 
cal_backend_store_toggle_ref_cb, NULL);
 
-       store->priv->save_timeout_id = e_named_timeout_add_seconds (
-               IDLE_SAVE_TIMEOUT_SECONDS,
-               cal_backend_store_save_cache_timeout_cb, store);
+       store->priv->save_timeout_id = e_named_timeout_add_seconds_full (
+               G_PRIORITY_DEFAULT, IDLE_SAVE_TIMEOUT_SECONDS,
+               cal_backend_store_save_cache_timeout_cb, e_weak_ref_new (store),
+               (GDestroyNotify) e_weak_ref_free);
 
        g_list_free_full (
                store->priv->timezones_to_save,
@@ -575,7 +553,6 @@
        g_mutex_lock (&priv->save_timeout_lock);
        if (priv->save_timeout_id > 0 || priv->dirty) {
                if (priv->save_timeout_id > 0) {
-                       g_object_remove_toggle_ref (object, 
cal_backend_store_toggle_ref_cb, NULL);
                        g_source_remove (priv->save_timeout_id);
                        priv->save_timeout_id = 0;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/calendar/libedata-cal/e-data-cal.c 
new/evolution-data-server-3.28.4/src/calendar/libedata-cal/e-data-cal.c
--- old/evolution-data-server-3.28.3/src/calendar/libedata-cal/e-data-cal.c     
2018-06-18 10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/calendar/libedata-cal/e-data-cal.c     
2018-07-16 12:42:35.000000000 +0200
@@ -2379,10 +2379,16 @@
 e_data_cal_report_error (EDataCal *cal,
                          const gchar *message)
 {
+       gchar *valid_utf8;
+
        g_return_if_fail (E_IS_DATA_CAL (cal));
        g_return_if_fail (message != NULL);
 
-       e_dbus_calendar_emit_error (cal->priv->dbus_interface, message);
+       valid_utf8 = e_util_utf8_make_valid (message);
+
+       e_dbus_calendar_emit_error (cal->priv->dbus_interface, valid_utf8 ? 
valid_utf8 : message);
+
+       g_free (valid_utf8);
 }
 
 /**
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/camel-null-output-stream.c 
new/evolution-data-server-3.28.4/src/camel/camel-null-output-stream.c
--- old/evolution-data-server-3.28.3/src/camel/camel-null-output-stream.c       
2018-06-18 10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/camel/camel-null-output-stream.c       
2018-07-16 12:42:35.000000000 +0200
@@ -35,6 +35,8 @@
 
 struct _CamelNullOutputStreamPrivate {
        gsize bytes_written;
+       gboolean ends_with_crlf;
+       gboolean ends_with_cr; /* Just for cases when the CRLF is split into 
two writes, CR and LF */
 };
 
 G_DEFINE_TYPE (
@@ -50,11 +52,20 @@
                           GError **error)
 {
        CamelNullOutputStreamPrivate *priv;
+       const guchar *data = buffer;
 
        priv = CAMEL_NULL_OUTPUT_STREAM_GET_PRIVATE (stream);
 
        priv->bytes_written += count;
 
+       if (count >= 2) {
+               priv->ends_with_crlf = data[count - 2] == '\r' && data[count - 
1] == '\n';
+               priv->ends_with_cr = data[count - 1] == '\r';
+       } else if (count == 1) {
+               priv->ends_with_crlf = priv->ends_with_cr && data[count - 1] == 
'\n';
+               priv->ends_with_cr = data[count - 1] == '\r';
+       }
+
        return count;
 }
 
@@ -74,6 +85,8 @@
 camel_null_output_stream_init (CamelNullOutputStream *null_stream)
 {
        null_stream->priv = CAMEL_NULL_OUTPUT_STREAM_GET_PRIVATE (null_stream);
+       null_stream->priv->ends_with_crlf = FALSE;
+       null_stream->priv->ends_with_cr = FALSE;
 }
 
 /**
@@ -109,3 +122,18 @@
        return null_stream->priv->bytes_written;
 }
 
+/**
+ * camel_null_output_stream_get_ends_with_crlf:
+ * @null_stream: a #CamelNullOutputStream
+ *
+ * Returns: Whether the data being written to @null_stream ended with CRLF.
+ *
+ * Since: 3.28.4
+ **/
+gboolean
+camel_null_output_stream_get_ends_with_crlf (CamelNullOutputStream 
*null_stream)
+{
+       g_return_val_if_fail (CAMEL_IS_NULL_OUTPUT_STREAM (null_stream), FALSE);
+
+       return null_stream->priv->ends_with_crlf;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/camel-null-output-stream.h 
new/evolution-data-server-3.28.4/src/camel/camel-null-output-stream.h
--- old/evolution-data-server-3.28.3/src/camel/camel-null-output-stream.h       
2018-06-18 10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/camel/camel-null-output-stream.h       
2018-07-16 12:42:35.000000000 +0200
@@ -67,6 +67,8 @@
                                        (void);
 gsize          camel_null_output_stream_get_bytes_written
                                        (CamelNullOutputStream *null_stream);
+gboolean       camel_null_output_stream_get_ends_with_crlf
+                                       (CamelNullOutputStream *null_stream);
 
 G_END_DECLS
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/camel-smime-context.c 
new/evolution-data-server-3.28.4/src/camel/camel-smime-context.c
--- old/evolution-data-server-3.28.3/src/camel/camel-smime-context.c    
2018-06-18 10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/camel/camel-smime-context.c    
2018-07-16 12:42:35.000000000 +0200
@@ -1523,9 +1523,21 @@
 }
 
 static void
+camel_smime_context_finalize (GObject *object)
+{
+       CamelSMIMEContext *smime = CAMEL_SMIME_CONTEXT (object);
+
+       g_free (smime->priv->encrypt_key);
+
+       /* Chain up to parent's method. */
+       G_OBJECT_CLASS (camel_smime_context_parent_class)->finalize (object);
+}
+
+static void
 camel_smime_context_class_init (CamelSMIMEContextClass *class)
 {
        CamelCipherContextClass *cipher_context_class;
+       GObjectClass *object_class;
 
        g_type_class_add_private (class, sizeof (CamelSMIMEContextPrivate));
 
@@ -1539,6 +1551,9 @@
        cipher_context_class->verify_sync = smime_context_verify_sync;
        cipher_context_class->encrypt_sync = smime_context_encrypt_sync;
        cipher_context_class->decrypt_sync = smime_context_decrypt_sync;
+
+       object_class = G_OBJECT_CLASS (class);
+       object_class->finalize = camel_smime_context_finalize;
 }
 
 static void
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/camel-stream-null.c 
new/evolution-data-server-3.28.4/src/camel/camel-stream-null.c
--- old/evolution-data-server-3.28.3/src/camel/camel-stream-null.c      
2018-06-18 10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/camel/camel-stream-null.c      
2018-07-16 12:42:35.000000000 +0200
@@ -26,6 +26,8 @@
 
 struct _CamelStreamNullPrivate {
        gsize written;
+       gboolean ends_with_crlf;
+       gboolean ends_with_cr; /* Just for cases when the CRLF is split into 
two writes, CR and LF */
 };
 
 static void camel_stream_null_seekable_init (GSeekableIface *iface);
@@ -40,7 +42,17 @@
                    GCancellable *cancellable,
                    GError **error)
 {
-       CAMEL_STREAM_NULL (stream)->priv->written += n;
+       CamelStreamNull *stream_null = CAMEL_STREAM_NULL (stream);
+
+       stream_null->priv->written += n;
+
+       if (n >= 2) {
+               stream_null->priv->ends_with_crlf = buffer[n - 2] == '\r' && 
buffer[n - 1] == '\n';
+               stream_null->priv->ends_with_cr = buffer[n - 1] == '\r';
+       } else if (n == 1) {
+               stream_null->priv->ends_with_crlf = 
stream_null->priv->ends_with_cr && buffer[n - 1] == '\n';
+               stream_null->priv->ends_with_cr = buffer[n - 1] == '\r';
+       }
 
        return n;
 }
@@ -128,6 +140,8 @@
 camel_stream_null_init (CamelStreamNull *stream_null)
 {
        stream_null->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream_null, 
CAMEL_TYPE_STREAM_NULL, CamelStreamNullPrivate);
+       stream_null->priv->ends_with_crlf = FALSE;
+       stream_null->priv->ends_with_cr = FALSE;
 }
 
 /**
@@ -160,3 +174,19 @@
 
        return stream_null->priv->written;
 }
+
+/**
+ * camel_stream_null_get_ends_with_crlf:
+ * @stream_null: a #CamelStreamNull
+ *
+ * Returns: Whether the data being written to @stream_null ended with CRLF.
+ *
+ * Since: 3.28.4
+ **/
+gboolean
+camel_stream_null_get_ends_with_crlf (CamelStreamNull *stream_null)
+{
+       g_return_val_if_fail (CAMEL_IS_STREAM_NULL (stream_null), FALSE);
+
+       return stream_null->priv->ends_with_crlf;
+}
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/camel-stream-null.h 
new/evolution-data-server-3.28.4/src/camel/camel-stream-null.h
--- old/evolution-data-server-3.28.3/src/camel/camel-stream-null.h      
2018-06-18 10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/camel/camel-stream-null.h      
2018-07-16 12:42:35.000000000 +0200
@@ -68,6 +68,8 @@
 CamelStream *  camel_stream_null_new           (void);
 gsize          camel_stream_null_get_bytes_written
                                                (CamelStreamNull *stream_null);
+gboolean       camel_stream_null_get_ends_with_crlf
+                                               (CamelStreamNull *stream_null);
 
 G_END_DECLS
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/providers/imapx/camel-imapx-command.c
 
new/evolution-data-server-3.28.4/src/camel/providers/imapx/camel-imapx-command.c
--- 
old/evolution-data-server-3.28.3/src/camel/providers/imapx/camel-imapx-command.c
    2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/camel/providers/imapx/camel-imapx-command.c
    2018-07-16 12:42:35.000000000 +0200
@@ -371,6 +371,30 @@
        g_string_append_len (buffer, ps, p - ps - 1);
 }
 
+static gboolean
+imapx_file_ends_with_crlf (const gchar *filename)
+{
+       CamelStream *null_stream, *input_stream;
+       gboolean ends_with_crlf;
+
+       g_return_val_if_fail (filename != NULL, FALSE);
+
+       input_stream = camel_stream_fs_new_with_name (filename, O_RDONLY, 0, 
NULL);
+       if (!input_stream)
+               return FALSE;
+
+       null_stream = camel_stream_null_new ();
+       camel_stream_write_to_stream (input_stream, null_stream, NULL, NULL);
+       camel_stream_flush (input_stream, NULL, NULL);
+       g_object_unref (input_stream);
+
+       ends_with_crlf = camel_stream_null_get_ends_with_crlf 
(CAMEL_STREAM_NULL (null_stream));
+
+       g_object_unref (null_stream);
+
+       return ends_with_crlf;
+}
+
 void
 camel_imapx_command_add_part (CamelIMAPXCommand *ic,
                               CamelIMAPXCommandPartType type,
@@ -379,6 +403,7 @@
        CamelIMAPXCommandPart *cp;
        GString *buffer;
        guint ob_size = 0;
+       gboolean ends_with_crlf = TRUE;
 
        buffer = ((CamelIMAPXRealCommand *) ic)->buffer;
 
@@ -396,6 +421,7 @@
                g_object_ref (ob);
                ob_size = camel_null_output_stream_get_bytes_written (
                        CAMEL_NULL_OUTPUT_STREAM (stream));
+               ends_with_crlf = camel_null_output_stream_get_ends_with_crlf 
(CAMEL_NULL_OUTPUT_STREAM (stream));
                g_object_unref (stream);
                break;
        }
@@ -420,6 +446,8 @@
                if (g_stat (path, &st) == 0) {
                        data = g_strdup (data);
                        ob_size = st.st_size;
+
+                       ends_with_crlf = imapx_file_ends_with_crlf (data);
                } else
                        data = NULL;
 
@@ -436,8 +464,13 @@
        }
 
        if (type & CAMEL_IMAPX_COMMAND_LITERAL_PLUS) {
+               guint total_size = ob_size;
+
+               if (ic->job_kind == CAMEL_IMAPX_JOB_APPEND_MESSAGE && 
!ends_with_crlf)
+                       total_size += 2;
+
                g_string_append_c (buffer, '{');
-               g_string_append_printf (buffer, "%u", ob_size);
+               g_string_append_printf (buffer, "%u", total_size);
                if (camel_imapx_server_have_capability (ic->is, 
IMAPX_CAPABILITY_LITERALPLUS)) {
                        g_string_append_c (buffer, '+');
                } else {
@@ -453,6 +486,7 @@
        cp->ob = data;
        cp->data_size = buffer->len;
        cp->data = g_strdup (buffer->str);
+       cp->ends_with_crlf = ends_with_crlf;
 
        g_string_set_size (buffer, 0);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/providers/imapx/camel-imapx-command.h
 
new/evolution-data-server-3.28.4/src/camel/providers/imapx/camel-imapx-command.h
--- 
old/evolution-data-server-3.28.3/src/camel/providers/imapx/camel-imapx-command.h
    2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/camel/providers/imapx/camel-imapx-command.h
    2018-07-16 12:42:35.000000000 +0200
@@ -58,6 +58,7 @@
 
        gint ob_size;
        gpointer ob;
+       gboolean ends_with_crlf;
 };
 
 struct _CamelIMAPXCommand {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/camel/providers/imapx/camel-imapx-server.c 
new/evolution-data-server-3.28.4/src/camel/providers/imapx/camel-imapx-server.c
--- 
old/evolution-data-server-3.28.3/src/camel/providers/imapx/camel-imapx-server.c 
    2018-06-18 10:48:43.000000000 +0200
+++ 
new/evolution-data-server-3.28.4/src/camel/providers/imapx/camel-imapx-server.c 
    2018-07-16 12:42:35.000000000 +0200
@@ -292,6 +292,7 @@
        guint idle_stamp;
 
        gboolean is_cyrus;
+       gboolean is_broken_cyrus;
 
        /* Info about the current connection; guarded by priv->stream_lock */
        struct _capability_info *cinfo;
@@ -619,7 +620,7 @@
        is->priv->status_data_items = g_string_free (buffer, FALSE);
 
        g_free (is->priv->list_return_opts);
-       if (!is->priv->is_cyrus && CAMEL_IMAPX_HAVE_CAPABILITY 
(is->priv->cinfo, LIST_EXTENDED)) {
+       if (!is->priv->is_broken_cyrus && CAMEL_IMAPX_HAVE_CAPABILITY 
(is->priv->cinfo, LIST_EXTENDED)) {
                buffer = g_string_new ("CHILDREN SUBSCRIBED");
                if (CAMEL_IMAPX_HAVE_CAPABILITY (is->priv->cinfo, LIST_STATUS))
                        g_string_append_printf (
@@ -1837,6 +1838,86 @@
 }
 
 static gboolean
+imapx_server_check_is_broken_cyrus (const gchar *response_text,
+                                   gboolean *inout_is_cyrus)
+{
+       const gchar *pp, *from;
+       gint vermajor = 0, verminor = 0, vermicro = 0;
+
+       g_return_val_if_fail (inout_is_cyrus != NULL, FALSE);
+
+       /* If already known that this is cyrus server, then it had been
+          identified as a good server, thus just return here. */
+       if (*inout_is_cyrus)
+               return FALSE;
+
+       if (!response_text || !*response_text)
+               return FALSE;
+
+       /* Expects "Cyrus IMAP v1.2.3", eventually "Cyrus IMAP 4.5.6" (with or 
without 'v' prefix) */
+       pp = response_text;
+       while (pp = camel_strstrcase (pp, "cyrus"), pp) {
+               /* It's a whole word */
+               if ((pp == response_text || g_ascii_isspace (pp[-1])) && 
g_ascii_isspace (pp[5]))
+                       break;
+               pp++;
+       }
+
+       if (!pp)
+               return FALSE;
+
+       from = pp;
+
+       /* In case there is the 'cyrus' word multiple times */
+       while (pp = from, pp && *pp) {
+               #define skip_word() \
+                       while (*pp && *pp != ' ') {     \
+                               pp++;                   \
+                       }                               \
+                                                       \
+                       if (!*pp)                       \
+                               return TRUE;            \
+                                                       \
+                       pp++;
+
+               /* Skip the 'Cyrus' word */
+               skip_word ();
+
+               /* Skip the 'IMAP' word */
+               skip_word ();
+
+               #undef skip_word
+
+               /* Now is at version with or without 'v' prefix */
+               if (*pp == 'v')
+                       pp++;
+
+               if (sscanf (pp, "%d.%d.%d", &vermajor, &verminor, &vermicro) == 
3) {
+                       *inout_is_cyrus = TRUE;
+                       break;
+               }
+
+               vermajor = 0;
+
+               pp = from + 1;
+               from = NULL;
+
+               while (pp = camel_strstrcase (pp, "cyrus"), pp) {
+                       /* It's a whole word */
+                       if (g_ascii_isspace (pp[-1]) && g_ascii_isspace 
(pp[5])) {
+                               from = pp;
+                               break;
+                       }
+
+                       pp++;
+               }
+       }
+
+       /* The 2.5.11, inclusive, has the issue fixed, thus check for that 
version. */
+       return !(vermajor > 2 || (vermajor == 2 && (verminor > 5 || (verminor 
== 5 && vermicro >= 11))));
+}
+
+static gboolean
 imapx_untagged_ok_no_bad (CamelIMAPXServer *is,
                           GInputStream *input_stream,
                           GCancellable *cancellable,
@@ -1965,8 +2046,8 @@
                        if (is->priv->context->sinfo->text) {
                                guint32 list_extended = imapx_lookup_capability 
("LIST-EXTENDED");
 
-                               is->priv->is_cyrus = is->priv->is_cyrus || 
camel_strstrcase (is->priv->context->sinfo->text, "cyrus");
-                               if (is->priv->is_cyrus && is->priv->cinfo && 
(is->priv->cinfo->capa & list_extended) != 0) {
+                               is->priv->is_broken_cyrus = 
is->priv->is_broken_cyrus || imapx_server_check_is_broken_cyrus 
(is->priv->context->sinfo->text, &is->priv->is_cyrus);
+                               if (is->priv->is_broken_cyrus && 
is->priv->cinfo && (is->priv->cinfo->capa & list_extended) != 0) {
                                        /* Disable LIST-EXTENDED for cyrus 
servers */
                                        c (is->priv->tagprefix, "Disabling 
LIST-EXTENDED extension for a Cyrus server\n");
                                        is->priv->cinfo->capa &= ~list_extended;
@@ -2267,6 +2348,15 @@
                return FALSE;
        }
 
+       if (ic->job_kind == CAMEL_IMAPX_JOB_APPEND_MESSAGE && 
!cp->ends_with_crlf) {
+               g_mutex_lock (&is->priv->stream_lock);
+               n_bytes_written = g_output_stream_write_all (
+                       output_stream, "\r\n", 2, NULL, cancellable, error);
+               g_mutex_unlock (&is->priv->stream_lock);
+               if (n_bytes_written < 0)
+                       return FALSE;
+       }
+
        if (!litplus) {
                success = camel_imapx_input_stream_skip (
                        CAMEL_IMAPX_INPUT_STREAM (input_stream),
@@ -2417,8 +2507,8 @@
        if (ic->status->condition == IMAPX_CAPABILITY) {
                guint32 list_extended = imapx_lookup_capability 
("LIST-EXTENDED");
 
-               is->priv->is_cyrus = is->priv->is_cyrus || (ic->status->text && 
camel_strstrcase (ic->status->text, "cyrus"));
-               if (is->priv->is_cyrus && ic->status->u.cinfo && 
(ic->status->u.cinfo->capa & list_extended) != 0) {
+               is->priv->is_broken_cyrus = is->priv->is_broken_cyrus || 
(ic->status->text && imapx_server_check_is_broken_cyrus (ic->status->text, 
&is->priv->is_cyrus));
+               if (is->priv->is_broken_cyrus && ic->status->u.cinfo && 
(ic->status->u.cinfo->capa & list_extended) != 0) {
                        /* Disable LIST-EXTENDED for cyrus servers */
                        c (is->priv->tagprefix, "Disabling LIST-EXTENDED 
extension for a Cyrus server\n");
                        ic->status->u.cinfo->capa &= ~list_extended;
@@ -3516,6 +3606,7 @@
 
        is->priv->state = IMAPX_DISCONNECTED;
        is->priv->is_cyrus = FALSE;
+       is->priv->is_broken_cyrus = FALSE;
        is->priv->copyuid_status = NULL;
 
        is->priv->changes = camel_folder_change_info_new ();
@@ -3998,6 +4089,7 @@
        g_mutex_unlock (&is->priv->select_lock);
 
        is->priv->is_cyrus = FALSE;
+       is->priv->is_broken_cyrus = FALSE;
        is->priv->state = IMAPX_DISCONNECTED;
 
        g_mutex_lock (&is->priv->idle_lock);
@@ -4026,6 +4118,7 @@
                return TRUE;
 
        is->priv->is_cyrus = FALSE;
+       is->priv->is_broken_cyrus = FALSE;
 
        if (!imapx_reconnect (is, cancellable, error))
                return FALSE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/evolution-data-server-3.28.3/src/libebackend/e-cache.c 
new/evolution-data-server-3.28.4/src/libebackend/e-cache.c
--- old/evolution-data-server-3.28.3/src/libebackend/e-cache.c  2018-06-18 
10:48:43.000000000 +0200
+++ new/evolution-data-server-3.28.4/src/libebackend/e-cache.c  2018-07-16 
12:42:35.000000000 +0200
@@ -39,6 +39,7 @@
 #include <glib/gstdio.h>
 
 #include <camel/camel.h>
+#include <libedataserver/libedataserver.h>
 
 #include "e-sqlite3-vfs.h"
 
@@ -510,8 +511,10 @@
                } else if (code == SQLITE_ABORT || code == SQLITE_INTERRUPT) { \
                        g_set_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED, 
"Operation cancelled: %s", message); \
                } else { \
+                       gchar *valid_utf8 = e_util_utf8_make_valid (stmt); \
                        g_set_error (error, E_CACHE_ERROR, 
E_CACHE_ERROR_ENGINE, \
-                               "SQLite error code '%d': %s (statement:%s)", 
code, message, stmt); \
+                               "SQLite error code '%d': %s (statement:%s)", 
code, message, valid_utf8 ? valid_utf8 : stmt); \
+                       g_free (valid_utf8); \
                } \
        } G_STMT_END
 


Reply via email to