]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
dsync: Fix syncing attributes with large values.
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Sun, 26 Feb 2017 13:21:13 +0000 (15:21 +0200)
committerGitLab <gitlab@git.dovecot.net>
Sun, 26 Feb 2017 13:39:35 +0000 (15:39 +0200)
This mainly meant that large Sieve scripts weren't synced properly, because
their last_change field was never deserialized, so it was set to 0.

src/doveadm/dsync/dsync-ibc-stream.c

index c6e54e9a511c93cf8f6d640ef38993fb1bca115b..abed19a2126240aa8a6d152df6e5241cc34d6a4e 100644 (file)
@@ -1554,16 +1554,6 @@ dsync_ibc_stream_recv_mailbox_attribute(struct dsync_ibc *_ibc,
        value = dsync_deserializer_decode_get(decoder, "key");
        attr->key = p_strdup(pool, value);
 
-       if (dsync_deserializer_decode_try(decoder, "stream", &value)) {
-               attr->value_stream = dsync_ibc_stream_input_stream(ibc);
-               if (dsync_ibc_stream_read_mail_stream(ibc) <= 0) {
-                       ibc->cur_attr = attr;
-                       return DSYNC_IBC_RECV_RET_TRYAGAIN;
-               }
-               /* already finished reading the stream */
-               i_assert(ibc->value_input == NULL);
-       } else if (dsync_deserializer_decode_try(decoder, "value", &value))
-               attr->value = p_strdup(pool, value);
        if (dsync_deserializer_decode_try(decoder, "deleted", &value))
                attr->deleted = TRUE;
        if (dsync_deserializer_decode_try(decoder, "last_change", &value) &&
@@ -1577,6 +1567,20 @@ dsync_ibc_stream_recv_mailbox_attribute(struct dsync_ibc *_ibc,
                return DSYNC_IBC_RECV_RET_TRYAGAIN;
        }
 
+       /* NOTE: stream reading must be the last here, because reading a large
+          stream will be finished later by return TRYAGAIN. We need to
+          deserialize all the other fields before that or they'll get lost. */
+       if (dsync_deserializer_decode_try(decoder, "stream", &value)) {
+               attr->value_stream = dsync_ibc_stream_input_stream(ibc);
+               if (dsync_ibc_stream_read_mail_stream(ibc) <= 0) {
+                       ibc->cur_attr = attr;
+                       return DSYNC_IBC_RECV_RET_TRYAGAIN;
+               }
+               /* already finished reading the stream */
+               i_assert(ibc->value_input == NULL);
+       } else if (dsync_deserializer_decode_try(decoder, "value", &value))
+               attr->value = p_strdup(pool, value);
+
        *attr_r = attr;
        return DSYNC_IBC_RECV_RET_OK;
 }