]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-index: Fix storing cache fields' last_used with 64bit big endian CPUs
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Tue, 10 Aug 2021 09:22:08 +0000 (12:22 +0300)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Wed, 1 Dec 2021 13:17:17 +0000 (13:17 +0000)
src/lib-index/mail-cache-fields.c

index e929fb559d6e4114ec1f580088e8faf5e9a5f281..429e0d234cdc89c54abb69d81470be1fca53c5de 100644 (file)
@@ -524,6 +524,19 @@ static void copy_to_buf_byte(struct mail_cache *cache, buffer_t *dest,
        }
 }
 
+static void
+copy_to_buf_last_used(struct mail_cache *cache, buffer_t *dest, bool add_new)
+{
+       size_t offset = offsetof(struct mail_cache_field, last_used);
+#if defined(WORDS_BIGENDIAN) && SIZEOF_VOID_P == 8
+       /* 64bit time_t with big endian CPUs: copy the last 32 bits instead of
+          the first 32 bits (that are always 0). The 32 bits are enough until
+          year 2106, so we're not in a hurry to use 64 bits on disk. */
+       offset += sizeof(uint32_t);
+#endif
+       copy_to_buf(cache, dest, add_new, offset, sizeof(uint32_t));
+}
+
 static int mail_cache_header_fields_update_locked(struct mail_cache *cache)
 {
        buffer_t *buffer;
@@ -536,9 +549,7 @@ static int mail_cache_header_fields_update_locked(struct mail_cache *cache)
 
        buffer = t_buffer_create(256);
 
-       copy_to_buf(cache, buffer, FALSE,
-                   offsetof(struct mail_cache_field, last_used),
-                   sizeof(uint32_t));
+       copy_to_buf_last_used(cache, buffer, FALSE);
        ret = mail_cache_write(cache, buffer->data, buffer->used,
                               offset + MAIL_CACHE_FIELD_LAST_USED());
        if (ret == 0) {
@@ -599,9 +610,7 @@ void mail_cache_header_fields_get(struct mail_cache *cache, buffer_t *dest)
        buffer_append(dest, &hdr, sizeof(hdr));
 
        /* we have to keep the field order for the existing fields. */
-       copy_to_buf(cache, dest, TRUE,
-                   offsetof(struct mail_cache_field, last_used),
-                   sizeof(uint32_t));
+       copy_to_buf_last_used(cache, dest, TRUE);
        copy_to_buf(cache, dest, TRUE,
                    offsetof(struct mail_cache_field, field_size),
                    sizeof(uint32_t));