From: Timo Sirainen Date: Sun, 26 Feb 2017 13:21:13 +0000 (+0200) Subject: dsync: Fix syncing attributes with large values. X-Git-Tag: 2.3.0.rc1~1991 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=27ccbb0f36e07141785db94557afb63a2aa9eeba;p=thirdparty%2Fdovecot%2Fcore.git dsync: Fix syncing attributes with large values. 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. --- diff --git a/src/doveadm/dsync/dsync-ibc-stream.c b/src/doveadm/dsync/dsync-ibc-stream.c index c6e54e9a51..abed19a212 100644 --- a/src/doveadm/dsync/dsync-ibc-stream.c +++ b/src/doveadm/dsync/dsync-ibc-stream.c @@ -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; }