NeoMutt  2025-12-11-980-ge38c27
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
serialize.c
Go to the documentation of this file.
1
24
30
31#include "config.h"
32#include <stdbool.h>
33#include <stddef.h>
34#include <string.h>
35#include <sys/types.h>
36#include "mutt/lib.h"
37#include "address/lib.h"
38#include "config/lib.h"
39#include "email/lib.h"
40#include "core/lib.h"
41#include "alias/lib.h"
42#include "serialize.h"
43
45#define SERIAL_MAX_CHAR_SIZE (256 * 1024)
46
48#define SERIAL_MAX_LIST_COUNT 1024
49
61static bool serial_in_bounds(int off, size_t need, size_t dlen)
62{
63 return (off >= 0) && (need <= dlen) && ((size_t) off <= (dlen - need));
64}
65
73void lazy_realloc(void *ptr, size_t size)
74{
75 void **p = (void **) ptr;
76
77 if (p && (size < 4096))
78 return;
79
80 mutt_mem_realloc(ptr, size);
81}
82
90unsigned char *serial_dump_int(const unsigned int i, unsigned char *d, int *off)
91{
92 lazy_realloc(&d, *off + sizeof(int));
93 memcpy(d + *off, &i, sizeof(int));
94 (*off) += sizeof(int);
95
96 return d;
97}
98
106unsigned char *serial_dump_uint32_t(const uint32_t s, unsigned char *d, int *off)
107{
108 lazy_realloc(&d, *off + sizeof(uint32_t));
109 memcpy(d + *off, &s, sizeof(uint32_t));
110 (*off) += sizeof(uint32_t);
111
112 return d;
113}
114
122unsigned char *serial_dump_uint64_t(const uint64_t s, unsigned char *d, int *off)
123{
124 lazy_realloc(&d, *off + sizeof(uint64_t));
125 memcpy(d + *off, &s, sizeof(uint64_t));
126 (*off) += sizeof(uint64_t);
127
128 return d;
129}
130
140bool serial_restore_int(unsigned int *i, const unsigned char *d, int *off, size_t dlen)
141{
142 if (!serial_in_bounds(*off, sizeof(int), dlen))
143 return false;
144
145 memcpy(i, d + *off, sizeof(int));
146 (*off) += sizeof(int);
147 return true;
148}
149
159bool serial_restore_uint32_t(uint32_t *s, const unsigned char *d, int *off, size_t dlen)
160{
161 if (!serial_in_bounds(*off, sizeof(uint32_t), dlen))
162 return false;
163
164 memcpy(s, d + *off, sizeof(uint32_t));
165 (*off) += sizeof(uint32_t);
166 return true;
167}
168
178bool serial_restore_uint64_t(uint64_t *s, const unsigned char *d, int *off, size_t dlen)
179{
180 if (!serial_in_bounds(*off, sizeof(uint64_t), dlen))
181 return false;
182
183 memcpy(s, d + *off, sizeof(uint64_t));
184 (*off) += sizeof(uint64_t);
185 return true;
186}
187
197unsigned char *serial_dump_char_size(const char *c, ssize_t size,
198 unsigned char *d, int *off, bool convert)
199{
200 char *p = NULL;
201
202 if (!c || (*c == '\0') || (size == 0))
203 {
204 return serial_dump_int(0, d, off);
205 }
206
207 if (convert && !mutt_str_is_ascii(c, size))
208 {
209 p = mutt_strn_dup(c, size);
210 if (mutt_ch_convert_string(&p, cc_charset(), "utf-8", MUTT_ICONV_NONE) == 0)
211 {
212 size = mutt_str_len(p) + 1;
213 }
214 }
215
216 d = serial_dump_int(size, d, off);
217 lazy_realloc(&d, *off + size);
218 memcpy(d + *off, p ? p : c, size);
219 *off += size;
220
221 FREE(&p);
222
223 return d;
224}
225
234unsigned char *serial_dump_char(const char *c, unsigned char *d, int *off, bool convert)
235{
236 return serial_dump_char_size(c, mutt_str_len(c) + 1, d, off, convert);
237}
238
249bool serial_restore_char(char **c, const unsigned char *d, int *off, size_t dlen, bool convert)
250{
251 *c = NULL;
252
253 unsigned int size = 0;
254 if (!serial_restore_int(&size, d, off, dlen))
255 return false;
256
257 if (size == 0)
258 return true;
259
260 if ((size > SERIAL_MAX_CHAR_SIZE) || !serial_in_bounds(*off, size, dlen))
261 return false;
262
263 *c = MUTT_MEM_MALLOC(size, char);
264 memcpy(*c, d + *off, size);
265 if (convert && !mutt_str_is_ascii(*c, size))
266 {
267 char *tmp = mutt_str_dup(*c);
268 if (mutt_ch_convert_string(&tmp, "utf-8", cc_charset(), MUTT_ICONV_NONE) == 0)
269 {
270 FREE(c);
271 *c = tmp;
272 }
273 else
274 {
275 FREE(&tmp);
276 }
277 }
278 *off += size;
279 return true;
280}
281
290unsigned char *serial_dump_address(const struct AddressList *al,
291 unsigned char *d, int *off, bool convert)
292{
293 unsigned int counter = 0;
294 unsigned int start_off = *off;
295
296 d = serial_dump_int(0xdeadbeef, d, off);
297
298 struct Address *a = NULL;
299 TAILQ_FOREACH(a, al, entries)
300 {
301 d = serial_dump_buffer(a->personal, d, off, convert);
302 d = serial_dump_buffer(a->mailbox, d, off, convert);
303 d = serial_dump_int(a->group, d, off);
304 counter++;
305 }
306
307 memcpy(d + start_off, &counter, sizeof(int));
308
309 return d;
310}
311
322bool serial_restore_address(struct AddressList *al, const unsigned char *d,
323 int *off, size_t dlen, bool convert)
324{
325 unsigned int counter = 0;
326 unsigned int g = 0;
327
328 if (!serial_restore_int(&counter, d, off, dlen))
329 return false;
330
331 if (counter > SERIAL_MAX_LIST_COUNT)
332 return false;
333
334 while (counter > 0)
335 {
336 struct Address *a = mutt_addr_new();
338
339 a->personal = buf_new(NULL);
340 if (!serial_restore_buffer(a->personal, d, off, dlen, convert))
341 return false;
342 if (buf_is_empty(a->personal))
343 {
344 buf_free(&a->personal);
345 }
346
347 a->mailbox = buf_new(NULL);
348 if (!serial_restore_buffer(a->mailbox, d, off, dlen, false))
349 return false;
350 if (buf_is_empty(a->mailbox))
351 {
352 buf_free(&a->mailbox);
353 }
354
355 if (!serial_restore_int(&g, d, off, dlen))
356 return false;
357 a->group = !!g;
358 counter--;
359 }
360
361 return true;
362}
363
372unsigned char *serial_dump_stailq(const struct ListHead *l, unsigned char *d,
373 int *off, bool convert)
374{
375 unsigned int counter = 0;
376 unsigned int start_off = *off;
377
378 d = serial_dump_int(0xdeadbeef, d, off);
379
380 struct ListNode *np = NULL;
381 STAILQ_FOREACH(np, l, entries)
382 {
383 d = serial_dump_char(np->data, d, off, convert);
384 counter++;
385 }
386
387 memcpy(d + start_off, &counter, sizeof(int));
388
389 return d;
390}
391
402bool serial_restore_stailq(struct ListHead *l, const unsigned char *d, int *off,
403 size_t dlen, bool convert)
404{
405 unsigned int counter = 0;
406
407 if (!serial_restore_int(&counter, d, off, dlen))
408 return false;
409
410 if (counter > SERIAL_MAX_LIST_COUNT)
411 return false;
412
413 struct ListNode *np = NULL;
414 while (counter > 0)
415 {
416 np = mutt_list_insert_tail(l, NULL);
417 if (!serial_restore_char(&np->data, d, off, dlen, convert))
418 return false;
419 counter--;
420 }
421
422 return true;
423}
424
433unsigned char *serial_dump_buffer(const struct Buffer *buf, unsigned char *d,
434 int *off, bool convert)
435{
436 if (buf_is_empty(buf))
437 {
438 d = serial_dump_int(0, d, off);
439 return d;
440 }
441
442 d = serial_dump_int(1, d, off);
443
444 d = serial_dump_char(buf->data, d, off, convert);
445
446 return d;
447}
448
459bool serial_restore_buffer(struct Buffer *buf, const unsigned char *d, int *off,
460 size_t dlen, bool convert)
461{
462 buf_alloc(buf, 1);
463
464 unsigned int used = 0;
465 if (!serial_restore_int(&used, d, off, dlen))
466 return false;
467 if (used == 0)
468 return true;
469
470 char *str = NULL;
471 if (!serial_restore_char(&str, d, off, dlen, convert))
472 return false;
473
474 buf_addstr(buf, str);
475 FREE(&str);
476 return true;
477}
478
487unsigned char *serial_dump_parameter(const struct ParameterList *pl,
488 unsigned char *d, int *off, bool convert)
489{
490 unsigned int counter = 0;
491 unsigned int start_off = *off;
492
493 d = serial_dump_int(0xdeadbeef, d, off);
494
495 struct Parameter *np = NULL;
496 TAILQ_FOREACH(np, pl, entries)
497 {
498 d = serial_dump_char(np->attribute, d, off, false);
499 d = serial_dump_char(np->value, d, off, convert);
500 counter++;
501 }
502
503 memcpy(d + start_off, &counter, sizeof(int));
504
505 return d;
506}
507
518bool serial_restore_parameter(struct ParameterList *pl, const unsigned char *d,
519 int *off, size_t dlen, bool convert)
520{
521 unsigned int counter = 0;
522
523 if (!serial_restore_int(&counter, d, off, dlen))
524 return false;
525
526 if (counter > SERIAL_MAX_LIST_COUNT)
527 return false;
528
529 struct Parameter *np = NULL;
530 while (counter > 0)
531 {
532 np = mutt_param_new();
533 TAILQ_INSERT_TAIL(pl, np, entries);
534 if (!serial_restore_char(&np->attribute, d, off, dlen, false))
535 return false;
536 if (!serial_restore_char(&np->value, d, off, dlen, convert))
537 return false;
538 counter--;
539 }
540
541 return true;
542}
543
551static inline uint32_t body_pack_flags(const struct Body *b)
552{
553 if (!b)
554 return 0;
555
556 // clang-format off
557 uint32_t packed = b->type +
558 (b->encoding << 4) +
559 (b->disposition << 7) +
560 (b->badsig << 9) +
561 (b->force_charset << 10) +
562 (b->goodsig << 11) +
563 (b->noconv << 12) +
564 (b->use_disp << 13) +
565 (b->warnsig << 14);
566 // clang-format on
567#ifdef USE_AUTOCRYPT
568 packed += (b->is_autocrypt << 15);
569#endif
570
571 return packed;
572}
573
581static inline void body_unpack_flags(struct Body *b, uint32_t packed)
582{
583 if (!b)
584 return;
585
586 // clang-format off
587 b->type = (packed & ((1 << 4) - 1)); // bits 0-3 (4)
588 b->encoding = ((packed >> 4) & ((1 << 3) - 1)); // bits 4-6 (3)
589 b->disposition = ((packed >> 7) & ((1 << 2) - 1)); // bits 7-8 (2)
590
591 b->badsig = (packed & (1 << 9));
592 b->force_charset = (packed & (1 << 10));
593 b->goodsig = (packed & (1 << 11));
594 b->noconv = (packed & (1 << 12));
595 b->use_disp = (packed & (1 << 13));
596 b->warnsig = (packed & (1 << 14));
597#ifdef USE_AUTOCRYPT
598 b->is_autocrypt = (packed & (1 << 15));
599#endif
600 // clang-format on
601}
602
611unsigned char *serial_dump_body(const struct Body *b, unsigned char *d, int *off, bool convert)
612{
613 uint32_t packed = body_pack_flags(b);
614 d = serial_dump_uint32_t(packed, d, off);
615
616 uint64_t big = b->offset;
617 d = serial_dump_uint64_t(big, d, off);
618
619 big = b->length;
620 d = serial_dump_uint64_t(big, d, off);
621
622 d = serial_dump_char(b->xtype, d, off, false);
623 d = serial_dump_char(b->subtype, d, off, false);
624
625 d = serial_dump_parameter(&b->parameter, d, off, convert);
626
627 d = serial_dump_char(b->description, d, off, convert);
628 d = serial_dump_char(b->content_id, d, off, convert);
629 d = serial_dump_char(b->form_name, d, off, convert);
630 d = serial_dump_char(b->filename, d, off, convert);
631 d = serial_dump_char(b->d_filename, d, off, convert);
632
633 return d;
634}
635
646bool serial_restore_body(struct Body *b, const unsigned char *d, int *off,
647 size_t dlen, bool convert)
648{
649 uint32_t packed = 0;
650 if (!serial_restore_uint32_t(&packed, d, off, dlen))
651 return false;
652 body_unpack_flags(b, packed);
653
654 uint64_t big = 0;
655 if (!serial_restore_uint64_t(&big, d, off, dlen))
656 return false;
657 b->offset = big;
658
659 big = 0;
660 if (!serial_restore_uint64_t(&big, d, off, dlen))
661 return false;
662 b->length = big;
663
664 if (!serial_restore_char(&b->xtype, d, off, dlen, false))
665 return false;
666 if (!serial_restore_char(&b->subtype, d, off, dlen, false))
667 return false;
668
670 if (!serial_restore_parameter(&b->parameter, d, off, dlen, convert))
671 return false;
672
673 if (!serial_restore_char(&b->description, d, off, dlen, convert))
674 return false;
675 if (!serial_restore_char(&b->content_id, d, off, dlen, convert))
676 return false;
677 if (!serial_restore_char(&b->form_name, d, off, dlen, convert))
678 return false;
679 if (!serial_restore_char(&b->filename, d, off, dlen, convert))
680 return false;
681 if (!serial_restore_char(&b->d_filename, d, off, dlen, convert))
682 return false;
683
684 return true;
685}
686
695unsigned char *serial_dump_envelope(const struct Envelope *env,
696 unsigned char *d, int *off, bool convert)
697{
698 d = serial_dump_address(&env->return_path, d, off, convert);
699 d = serial_dump_address(&env->from, d, off, convert);
700 d = serial_dump_address(&env->to, d, off, convert);
701 d = serial_dump_address(&env->cc, d, off, convert);
702 d = serial_dump_address(&env->bcc, d, off, convert);
703 d = serial_dump_address(&env->sender, d, off, convert);
704 d = serial_dump_address(&env->reply_to, d, off, convert);
705 d = serial_dump_address(&env->mail_followup_to, d, off, convert);
706
707 d = serial_dump_char(env->list_post, d, off, convert);
708 d = serial_dump_char(env->list_subscribe, d, off, convert);
709 d = serial_dump_char(env->list_unsubscribe, d, off, convert);
710 d = serial_dump_char(env->subject, d, off, convert);
711
712 if (env->real_subj)
713 d = serial_dump_int(env->real_subj - env->subject, d, off);
714 else
715 d = serial_dump_int(-1, d, off);
716
717 d = serial_dump_char(env->message_id, d, off, false);
718 d = serial_dump_char(env->supersedes, d, off, false);
719 d = serial_dump_char(env->date, d, off, false);
720 d = serial_dump_char(env->x_label, d, off, convert);
721 d = serial_dump_char(env->organization, d, off, convert);
722
723 d = serial_dump_buffer(&env->spam, d, off, convert);
724
725 d = serial_dump_stailq(&env->references, d, off, false);
726 d = serial_dump_stailq(&env->in_reply_to, d, off, false);
727 d = serial_dump_stailq(&env->userhdrs, d, off, convert);
728
729 d = serial_dump_char(env->xref, d, off, false);
730 d = serial_dump_char(env->followup_to, d, off, false);
731 d = serial_dump_char(env->x_comment_to, d, off, convert);
732
733 return d;
734}
735
746bool serial_restore_envelope(struct Envelope *env, const unsigned char *d,
747 int *off, size_t dlen, bool convert)
748{
749 int real_subj_off = 0;
750
751 if (!serial_restore_address(&env->return_path, d, off, dlen, convert) ||
752 !serial_restore_address(&env->from, d, off, dlen, convert) ||
753 !serial_restore_address(&env->to, d, off, dlen, convert) ||
754 !serial_restore_address(&env->cc, d, off, dlen, convert) ||
755 !serial_restore_address(&env->bcc, d, off, dlen, convert) ||
756 !serial_restore_address(&env->sender, d, off, dlen, convert) ||
757 !serial_restore_address(&env->reply_to, d, off, dlen, convert) ||
758 !serial_restore_address(&env->mail_followup_to, d, off, dlen, convert))
759 {
760 return false;
761 }
762
763 if (!serial_restore_char(&env->list_post, d, off, dlen, convert) ||
764 !serial_restore_char(&env->list_subscribe, d, off, dlen, convert) ||
765 !serial_restore_char(&env->list_unsubscribe, d, off, dlen, convert))
766 {
767 return false;
768 }
769
770 const bool c_auto_subscribe = cs_subset_bool(NeoMutt->sub, "auto_subscribe");
771 if (c_auto_subscribe)
773
774 if (!serial_restore_char((char **) &env->subject, d, off, dlen, convert))
775 return false;
776 if (!serial_restore_int((unsigned int *) (&real_subj_off), d, off, dlen))
777 return false;
778
779 size_t len = mutt_str_len(env->subject);
780 if ((real_subj_off < 0) || (real_subj_off >= len))
781 *(char **) &env->real_subj = NULL;
782 else
783 *(char **) &env->real_subj = env->subject + real_subj_off;
784
785 if (!serial_restore_char(&env->message_id, d, off, dlen, false) ||
786 !serial_restore_char(&env->supersedes, d, off, dlen, false) ||
787 !serial_restore_char(&env->date, d, off, dlen, false) ||
788 !serial_restore_char(&env->x_label, d, off, dlen, convert) ||
789 !serial_restore_char(&env->organization, d, off, dlen, convert))
790 {
791 return false;
792 }
793
794 if (!serial_restore_buffer(&env->spam, d, off, dlen, convert))
795 return false;
796
797 if (!serial_restore_stailq(&env->references, d, off, dlen, false) ||
798 !serial_restore_stailq(&env->in_reply_to, d, off, dlen, false) ||
799 !serial_restore_stailq(&env->userhdrs, d, off, dlen, convert))
800 {
801 return false;
802 }
803
804 if (!serial_restore_char(&env->xref, d, off, dlen, false) ||
805 !serial_restore_char(&env->followup_to, d, off, dlen, false) ||
806 !serial_restore_char(&env->x_comment_to, d, off, dlen, convert))
807 {
808 return false;
809 }
810
811 return true;
812}
813
821unsigned char *serial_dump_tags(const struct TagList *tl, unsigned char *d, int *off)
822{
823 unsigned int counter = 0;
824 unsigned int start_off = *off;
825
826 d = serial_dump_int(0xdeadbeef, d, off);
827
828 struct Tag *tag = NULL;
829 STAILQ_FOREACH(tag, tl, entries)
830 {
831 d = serial_dump_char(tag->name, d, off, false);
832 counter++;
833 }
834
835 memcpy(d + start_off, &counter, sizeof(int));
836
837 return d;
838}
839
849bool serial_restore_tags(struct TagList *tl, const unsigned char *d, int *off, size_t dlen)
850{
851 unsigned int counter = 0;
852
853 if (!serial_restore_int(&counter, d, off, dlen))
854 return false;
855
856 if (counter > SERIAL_MAX_LIST_COUNT)
857 return false;
858
859 while (counter > 0)
860 {
861 char *name = NULL;
862 if (!serial_restore_char(&name, d, off, dlen, false))
863 return false;
865 counter--;
866 }
867
868 return true;
869}
void mutt_addrlist_append(struct AddressList *al, struct Address *a)
Append an Address to an AddressList.
Definition address.c:1496
struct Address * mutt_addr_new(void)
Create a new Address.
Definition address.c:401
Email Address Handling.
void mutt_auto_subscribe(const char *mailto)
Check if user is subscribed to mailing list.
Definition commands.c:49
Email Aliases.
bool buf_is_empty(const struct Buffer *buf)
Is the Buffer empty?
Definition buffer.c:298
void buf_free(struct Buffer **ptr)
Deallocates a buffer.
Definition buffer.c:326
struct Buffer * buf_new(const char *str)
Allocate a new Buffer.
Definition buffer.c:311
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
Definition buffer.c:233
void buf_alloc(struct Buffer *buf, size_t new_size)
Make sure a buffer can store at least new_size bytes.
Definition buffer.c:342
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
Convenience wrapper for the config headers.
const char * cc_charset(void)
Get the cached value of $charset.
Convenience wrapper for the core headers.
Structs that make up an email.
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition list.c:65
void mutt_mem_realloc(void *pptr, size_t size)
Resize a block of memory on the heap.
Definition memory.c:149
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition charset.c:819
#define MUTT_ICONV_NONE
No flags are set.
Definition charset.h:66
Convenience wrapper for the library headers.
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition string.c:384
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
bool mutt_str_is_ascii(const char *str, size_t len)
Is a string ASCII (7-bit)?
Definition string.c:689
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
struct Parameter * mutt_param_new(void)
Create a new Parameter.
Definition parameter.c:40
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define TAILQ_INIT(head)
Definition queue.h:822
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:866
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
bool serial_restore_stailq(struct ListHead *l, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack a STAILQ from a binary blob.
Definition serialize.c:402
unsigned char * serial_dump_body(const struct Body *b, unsigned char *d, int *off, bool convert)
Pack an Body into a binary blob.
Definition serialize.c:611
bool serial_restore_uint32_t(uint32_t *s, const unsigned char *d, int *off, size_t dlen)
Unpack an uint32_t from a binary blob.
Definition serialize.c:159
bool serial_restore_address(struct AddressList *al, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack an Address from a binary blob.
Definition serialize.c:322
unsigned char * serial_dump_tags(const struct TagList *tl, unsigned char *d, int *off)
Pack a TagList into a binary blob.
Definition serialize.c:821
unsigned char * serial_dump_uint64_t(const uint64_t s, unsigned char *d, int *off)
Pack a uint64_t into a binary blob.
Definition serialize.c:122
bool serial_restore_parameter(struct ParameterList *pl, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack a Parameter from a binary blob.
Definition serialize.c:518
static bool serial_in_bounds(int off, size_t need, size_t dlen)
Does a read stay within the serialized blob?
Definition serialize.c:61
unsigned char * serial_dump_int(const unsigned int i, unsigned char *d, int *off)
Pack an integer into a binary blob.
Definition serialize.c:90
unsigned char * serial_dump_envelope(const struct Envelope *env, unsigned char *d, int *off, bool convert)
Pack an Envelope into a binary blob.
Definition serialize.c:695
static uint32_t body_pack_flags(const struct Body *b)
Pack the Body flags into a uint32_t.
Definition serialize.c:551
unsigned char * serial_dump_buffer(const struct Buffer *buf, unsigned char *d, int *off, bool convert)
Pack a Buffer into a binary blob.
Definition serialize.c:433
unsigned char * serial_dump_address(const struct AddressList *al, unsigned char *d, int *off, bool convert)
Pack an Address into a binary blob.
Definition serialize.c:290
bool serial_restore_buffer(struct Buffer *buf, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack a Buffer from a binary blob.
Definition serialize.c:459
bool serial_restore_uint64_t(uint64_t *s, const unsigned char *d, int *off, size_t dlen)
Unpack an uint64_t from a binary blob.
Definition serialize.c:178
void lazy_realloc(void *ptr, size_t size)
Reallocate some memory.
Definition serialize.c:73
unsigned char * serial_dump_parameter(const struct ParameterList *pl, unsigned char *d, int *off, bool convert)
Pack a Parameter into a binary blob.
Definition serialize.c:487
#define SERIAL_MAX_LIST_COUNT
Max entries in a serialized list (addresses, headers, parameters, tags)
Definition serialize.c:48
bool serial_restore_tags(struct TagList *tl, const unsigned char *d, int *off, size_t dlen)
Unpack a TagList from a binary blob.
Definition serialize.c:849
unsigned char * serial_dump_uint32_t(const uint32_t s, unsigned char *d, int *off)
Pack a uint32_t into a binary blob.
Definition serialize.c:106
unsigned char * serial_dump_stailq(const struct ListHead *l, unsigned char *d, int *off, bool convert)
Pack a STAILQ into a binary blob.
Definition serialize.c:372
#define SERIAL_MAX_CHAR_SIZE
Max size for a single serialized string field (256 KiB)
Definition serialize.c:45
bool serial_restore_int(unsigned int *i, const unsigned char *d, int *off, size_t dlen)
Unpack an integer from a binary blob.
Definition serialize.c:140
unsigned char * serial_dump_char_size(const char *c, ssize_t size, unsigned char *d, int *off, bool convert)
Pack a fixed-length string into a binary blob.
Definition serialize.c:197
bool serial_restore_body(struct Body *b, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack a Body from a binary blob.
Definition serialize.c:646
static void body_unpack_flags(struct Body *b, uint32_t packed)
Unpack the Body flags from a uint32_t.
Definition serialize.c:581
bool serial_restore_envelope(struct Envelope *env, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack an Envelope from a binary blob.
Definition serialize.c:746
unsigned char * serial_dump_char(const char *c, unsigned char *d, int *off, bool convert)
Pack a variable-length string into a binary blob.
Definition serialize.c:234
bool serial_restore_char(char **c, const unsigned char *d, int *off, size_t dlen, bool convert)
Unpack a variable-length string from a binary blob.
Definition serialize.c:249
Email-object serialiser.
An email address.
Definition address.h:35
struct Buffer * personal
Real name of address.
Definition address.h:36
bool group
Group mailbox?
Definition address.h:38
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:37
The body of an email.
Definition body.h:36
char * content_id
Content-Id (RFC2392)
Definition body.h:58
char * d_filename
filename to be used for the content-disposition header If NULL, filename is used instead.
Definition body.h:56
LOFF_T offset
offset where the actual data begins
Definition body.h:52
char * xtype
content-type if x-unknown
Definition body.h:62
bool noconv
Don't do character set conversion.
Definition body.h:46
bool badsig
Bad cryptographic signature (needed to check encrypted s/mime-signatures)
Definition body.h:43
bool is_autocrypt
Flag autocrypt-decrypted messages for replying.
Definition body.h:50
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
bool use_disp
Content-Disposition uses filename= ?
Definition body.h:47
char * description
content-description
Definition body.h:55
unsigned int disposition
content-disposition, ContentDisposition
Definition body.h:42
bool force_charset
Send mode: don't adjust the character set when in send-mode.
Definition body.h:44
char * subtype
content-type subtype
Definition body.h:61
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
bool goodsig
Good cryptographic signature.
Definition body.h:45
char * form_name
Content-Disposition form-data name param.
Definition body.h:60
bool warnsig
Maybe good signature.
Definition body.h:48
unsigned int type
content-type primary type, ContentType
Definition body.h:40
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
String manipulation buffer.
Definition buffer.h:36
char * data
Pointer to data.
Definition buffer.h:37
The header of an Email.
Definition envelope.h:57
struct ListHead userhdrs
user defined headers
Definition envelope.h:85
char * supersedes
Supersedes header.
Definition envelope.h:74
char * list_subscribe
This stores a list URI, preferring mailto.
Definition envelope.h:68
struct AddressList return_path
Return path for the Email.
Definition envelope.h:58
char *const subject
Email's subject.
Definition envelope.h:70
struct AddressList to
Email's 'To' list.
Definition envelope.h:60
char * followup_to
List of 'followup-to' fields.
Definition envelope.h:80
struct AddressList reply_to
Email's 'reply-to'.
Definition envelope.h:64
char * message_id
Message ID.
Definition envelope.h:73
char * x_comment_to
List of 'X-comment-to' fields.
Definition envelope.h:81
struct AddressList mail_followup_to
Email's 'mail-followup-to'.
Definition envelope.h:65
struct AddressList cc
Email's 'Cc' list.
Definition envelope.h:61
struct AddressList sender
Email's sender.
Definition envelope.h:63
struct ListHead references
message references (in reverse order)
Definition envelope.h:83
struct Buffer spam
Spam header.
Definition envelope.h:82
struct ListHead in_reply_to
in-reply-to header content
Definition envelope.h:84
struct AddressList bcc
Email's 'Bcc' list.
Definition envelope.h:62
char * xref
List of cross-references.
Definition envelope.h:79
char * organization
Organisation header.
Definition envelope.h:77
char * x_label
X-Label.
Definition envelope.h:76
char * list_post
This stores a mailto URL, or nothing.
Definition envelope.h:67
char *const real_subj
Offset of the real subject.
Definition envelope.h:71
char * date
Sent date.
Definition envelope.h:75
char * list_unsubscribe
This stores a list URI, preferring mailto.
Definition envelope.h:69
struct AddressList from
Email's 'From' list.
Definition envelope.h:59
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Attribute associated with a MIME part.
Definition parameter.h:33
char * attribute
Parameter name.
Definition parameter.h:34
char * value
Parameter value.
Definition parameter.h:35
LinkedList Tag Element.
Definition tags.h:41
char * name
Tag name.
Definition tags.h:42
void driver_tags_add(struct TagList *tl, char *new_tag)
Add a tag to header.
Definition tags.c:105