NeoMutt  2025-12-11-1009-ga75d9e
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
serialize.c File Reference

Email-object serialiser. More...

#include "config.h"
#include <stdbool.h>
#include <stddef.h>
#include <string.h>
#include <sys/types.h>
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "alias/lib.h"
#include "serialize.h"
Include dependency graph for serialize.c:

Go to the source code of this file.

Macros

#define SERIAL_MAX_CHAR_SIZE   (256 * 1024)
 Max size for a single serialized string field (256 KiB).
#define SERIAL_MAX_LIST_COUNT   1024
 Max entries in a serialized list (addresses, headers, parameters, tags).

Functions

static bool serial_in_bounds (int off, size_t need, size_t dlen)
 Does a read stay within the serialized blob?
void lazy_realloc (void *ptr, size_t size)
 Reallocate some memory.
unsigned char * serial_dump_int (const unsigned int i, unsigned char *d, int *off)
 Pack an integer into a binary blob.
unsigned char * serial_dump_uint32_t (const uint32_t s, unsigned char *d, int *off)
 Pack a uint32_t into a binary blob.
unsigned char * serial_dump_uint64_t (const uint64_t s, unsigned char *d, int *off)
 Pack a uint64_t into a binary blob.
bool serial_restore_int (unsigned int *i, const unsigned char *d, int *off, size_t dlen)
 Unpack an integer from a binary blob.
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.
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.
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.
unsigned char * serial_dump_char (const char *c, unsigned char *d, int *off, bool convert)
 Pack a variable-length string into a binary blob.
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.
unsigned char * serial_dump_address (const struct AddressList *al, unsigned char *d, int *off, bool convert)
 Pack an Address into a binary blob.
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.
unsigned char * serial_dump_stailq (const struct ListHead *l, unsigned char *d, int *off, bool convert)
 Pack a STAILQ into a binary blob.
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.
unsigned char * serial_dump_buffer (const struct Buffer *buf, unsigned char *d, int *off, bool convert)
 Pack a Buffer into a binary blob.
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.
unsigned char * serial_dump_parameter (const struct ParameterList *pl, unsigned char *d, int *off, bool convert)
 Pack a Parameter into a binary blob.
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.
static uint32_t body_pack_flags (const struct Body *b)
 Pack the Body flags into a uint32_t.
static void body_unpack_flags (struct Body *b, uint32_t packed)
 Unpack the Body flags from a uint32_t.
unsigned char * serial_dump_body (const struct Body *b, unsigned char *d, int *off, bool convert)
 Pack an Body into a binary blob.
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.
unsigned char * serial_dump_envelope (const struct Envelope *env, unsigned char *d, int *off, bool convert)
 Pack an Envelope into a binary blob.
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.
unsigned char * serial_dump_tags (const struct TagList *tl, unsigned char *d, int *off)
 Pack a TagList into a binary blob.
bool serial_restore_tags (struct TagList *tl, const unsigned char *d, int *off, size_t dlen)
 Unpack a TagList from a binary blob.

Detailed Description

Email-object serialiser.

Authors
  • Richard Russon
  • Pietro Cerutti
  • Anna Figueiredo Gomes

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file serialize.c.

Macro Definition Documentation

◆ SERIAL_MAX_CHAR_SIZE

#define SERIAL_MAX_CHAR_SIZE   (256 * 1024)

Max size for a single serialized string field (256 KiB).

Definition at line 45 of file serialize.c.

◆ SERIAL_MAX_LIST_COUNT

#define SERIAL_MAX_LIST_COUNT   1024

Max entries in a serialized list (addresses, headers, parameters, tags).

Definition at line 48 of file serialize.c.

Function Documentation

◆ serial_in_bounds()

bool serial_in_bounds ( int off,
size_t need,
size_t dlen )
static

Does a read stay within the serialized blob?

Parameters
offCurrent offset into the blob
needNumber of bytes about to be read
dlenTotal length of the blob
Return values
trueThe read is fully contained in the blob

The restore helpers walk a blob whose length is only known to the caller. A truncated or crafted cache entry can claim fields that extend past the end of the fetched data, so every read is checked against dlen first.

Definition at line 61 of file serialize.c.

62{
63 return (off >= 0) && (need <= dlen) && ((size_t) off <= (dlen - need));
64}
Here is the caller graph for this function:

◆ lazy_realloc()

void lazy_realloc ( void * ptr,
size_t size )

Reallocate some memory.

Parameters
[in]ptrPointer to resize
[in]sizeMinimum size

The minimum size is 4KiB to avoid repeated resizing.

Definition at line 73 of file serialize.c.

74{
75 void **p = (void **) ptr;
76
77 if (p && (size < 4096))
78 return;
79
80 mutt_mem_realloc(ptr, size);
81}
void mutt_mem_realloc(void *pptr, size_t size)
Resize a block of memory on the heap.
Definition memory.c:149
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_int()

unsigned char * serial_dump_int ( const unsigned int i,
unsigned char * d,
int * off )

Pack an integer into a binary blob.

Parameters
[in]iInteger to save
[in]dBinary blob to add to
[in,out]offOffset into the blob
Return values
ptrEnd of the newly packed binary

Definition at line 90 of file serialize.c.

91{
92 lazy_realloc(&d, *off + sizeof(int));
93 memcpy(d + *off, &i, sizeof(int));
94 (*off) += sizeof(int);
95
96 return d;
97}
void lazy_realloc(void *ptr, size_t size)
Reallocate some memory.
Definition serialize.c:73
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_uint32_t()

unsigned char * serial_dump_uint32_t ( const uint32_t s,
unsigned char * d,
int * off )

Pack a uint32_t into a binary blob.

Parameters
[in]suint32_t to save
[in]dBinary blob to add to
[in,out]offOffset into the blob
Return values
ptrEnd of the newly packed binary

Definition at line 106 of file serialize.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_uint64_t()

unsigned char * serial_dump_uint64_t ( const uint64_t s,
unsigned char * d,
int * off )

Pack a uint64_t into a binary blob.

Parameters
[in]suint64_t to save
[in]dBinary blob to add to
[in,out]offOffset into the blob
Return values
ptrEnd of the newly packed binary

Definition at line 122 of file serialize.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_int()

bool serial_restore_int ( unsigned int * i,
const unsigned char * d,
int * off,
size_t dlen )

Unpack an integer from a binary blob.

Parameters
[in]iInteger to write to
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
Return values
trueThe integer was read
falseThe read would leave the blob

Definition at line 140 of file serialize.c.

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}
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_uint32_t()

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.

Parameters
[in]suint32_t to write to
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
Return values
trueThe uint32_t was read
falseThe read would leave the blob

Definition at line 159 of file serialize.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_uint64_t()

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.

Parameters
[in]suint64_t to write to
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
Return values
trueThe uint64_t was read
falseThe read would leave the blob

Definition at line 178 of file serialize.c.

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}
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_char_size()

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.

Parameters
[in]cString to pack
[in]dBinary blob to add to
[in]sizeSize of the string
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 197 of file serialize.c.

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}
const char * cc_charset(void)
Get the cached value of $charset.
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
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
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
Definition string.c:384
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
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_char()

unsigned char * serial_dump_char ( const char * c,
unsigned char * d,
int * off,
bool convert )

Pack a variable-length string into a binary blob.

Parameters
[in]cString to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 234 of file serialize.c.

235{
236 return serial_dump_char_size(c, mutt_str_len(c) + 1, d, off, convert);
237}
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_char()

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.

Parameters
[out]cStore the unpacked string here
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted to utf-8
Return values
trueThe string was read (an empty string yields a NULL c)
falseThe read would leave the blob

Definition at line 249 of file serialize.c.

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}
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:257
#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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_address()

unsigned char * serial_dump_address ( const struct AddressList * al,
unsigned char * d,
int * off,
bool convert )

Pack an Address into a binary blob.

Parameters
[in]alAddressList to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 290 of file serialize.c.

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}
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
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
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_address()

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.

Parameters
[out]alStore the unpacked AddressList here
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted from utf-8
Return values
trueThe AddressList was read
falseA read would leave the blob, or the count is out of range

Definition at line 322 of file serialize.c.

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}
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
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
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
#define SERIAL_MAX_LIST_COUNT
Max entries in a serialized list (addresses, headers, parameters, tags).
Definition serialize.c:48
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_stailq()

unsigned char * serial_dump_stailq ( const struct ListHead * l,
unsigned char * d,
int * off,
bool convert )

Pack a STAILQ into a binary blob.

Parameters
[in]lList to read from
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 372 of file serialize.c.

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}
#define STAILQ_FOREACH(var, head, field)
Definition queue.h:390
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
A List node for strings.
Definition list.h:37
char * data
String.
Definition list.h:38
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_stailq()

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.

Parameters
[in]lList to add to
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted from utf-8
Return values
trueThe list was read
falseA read would leave the blob, or the count is out of range

Definition at line 402 of file serialize.c.

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}
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition list.c:65
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_buffer()

unsigned char * serial_dump_buffer ( const struct Buffer * buf,
unsigned char * d,
int * off,
bool convert )

Pack a Buffer into a binary blob.

Parameters
[in]bufBuffer to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 433 of file serialize.c.

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}
char * data
Pointer to data.
Definition buffer.h:37
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_buffer()

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.

Parameters
[out]bufStore the unpacked Buffer here
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted from utf-8
Return values
trueThe Buffer was read
falseA read would leave the blob

Definition at line 459 of file serialize.c.

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}
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_parameter()

unsigned char * serial_dump_parameter ( const struct ParameterList * pl,
unsigned char * d,
int * off,
bool convert )

Pack a Parameter into a binary blob.

Parameters
[in]plParameter to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 487 of file serialize.c.

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}
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_parameter()

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.

Parameters
[in]plStore the unpacked Parameter here
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted from utf-8
Return values
trueThe Parameter was read
falseA read would leave the blob, or the count is out of range

Definition at line 518 of file serialize.c.

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}
struct Parameter * mutt_param_new(void)
Create a new Parameter.
Definition parameter.c:40
#define TAILQ_INSERT_TAIL(head, elm, field)
Definition queue.h:866
Here is the call graph for this function:
Here is the caller graph for this function:

◆ body_pack_flags()

uint32_t body_pack_flags ( const struct Body * b)
inlinestatic

Pack the Body flags into a uint32_t.

Parameters
bBody to pack
Return values
numuint32_t of packed flags
Note
Order of packing must match body_unpack_flags()

Definition at line 551 of file serialize.c.

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}
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
bool use_disp
Content-Disposition uses filename= ?
Definition body.h:47
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
unsigned int encoding
content-transfer-encoding, ContentEncoding
Definition body.h:41
bool goodsig
Good cryptographic signature.
Definition body.h:45
bool warnsig
Maybe good signature.
Definition body.h:48
unsigned int type
content-type primary type, ContentType
Definition body.h:40
Here is the caller graph for this function:

◆ body_unpack_flags()

void body_unpack_flags ( struct Body * b,
uint32_t packed )
inlinestatic

Unpack the Body flags from a uint32_t.

Parameters
bBody to unpack into
packedPacked flags
Note
Order of packing must match body_pack_flags()

Definition at line 581 of file serialize.c.

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}
Here is the caller graph for this function:

◆ serial_dump_body()

unsigned char * serial_dump_body ( const struct Body * b,
unsigned char * d,
int * off,
bool convert )

Pack an Body into a binary blob.

Parameters
[in]bBody to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 611 of file serialize.c.

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}
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
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_parameter(const struct ParameterList *pl, unsigned char *d, int *off, bool convert)
Pack a Parameter into a binary blob.
Definition serialize.c:487
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
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
LOFF_T length
length (in bytes) of attachment
Definition body.h:53
struct ParameterList parameter
Parameters of the content-type.
Definition body.h:63
char * description
content-description
Definition body.h:55
char * subtype
content-type subtype
Definition body.h:61
char * form_name
Content-Disposition form-data name param.
Definition body.h:60
char * filename
When sending a message, this is the file to which this structure refers.
Definition body.h:59
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_body()

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.

Parameters
[in]bStore the unpacked Body here
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted from utf-8
Return values
trueThe Body was read
falseA read would leave the blob

Definition at line 646 of file serialize.c.

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}
#define TAILQ_INIT(head)
Definition queue.h:822
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_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
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
static void body_unpack_flags(struct Body *b, uint32_t packed)
Unpack the Body flags from a uint32_t.
Definition serialize.c:581
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_envelope()

unsigned char * serial_dump_envelope ( const struct Envelope * env,
unsigned char * d,
int * off,
bool convert )

Pack an Envelope into a binary blob.

Parameters
[in]envEnvelope to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]convertIf true, the strings will be converted to utf-8
Return values
ptrEnd of the newly packed binary

Definition at line 695 of file serialize.c.

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}
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
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
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
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_envelope()

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.

Parameters
[in]envStore the unpacked Envelope here
[in]dBinary blob to read from
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
[in]convertIf true, the strings will be converted from utf-8
Return values
trueThe Envelope was read
falseA read would leave the blob

Definition at line 746 of file serialize.c.

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}
void mutt_auto_subscribe(const char *mailto)
Check if user is subscribed to mailing list.
Definition commands.c:49
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
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
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
Container for Accounts, Notifications.
Definition neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:49
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_dump_tags()

unsigned char * serial_dump_tags ( const struct TagList * tl,
unsigned char * d,
int * off )

Pack a TagList into a binary blob.

Parameters
[in]tlTagList to pack
[in]dBinary blob to add to
[in,out]offOffset into the blob
Return values
ptrEnd of the newly packed binary

Definition at line 821 of file serialize.c.

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}
LinkedList Tag Element.
Definition tags.h:41
char * name
Tag name.
Definition tags.h:42
Here is the call graph for this function:
Here is the caller graph for this function:

◆ serial_restore_tags()

bool serial_restore_tags ( struct TagList * tl,
const unsigned char * d,
int * off,
size_t dlen )

Unpack a TagList from a binary blob.

Parameters
[in]tlTagList to unpack
[in]dBinary blob to add to
[in,out]offOffset into the blob
[in]dlenLength of the binary blob
Return values
trueThe TagList was read
falseA read would leave the blob, or the count is out of range

Definition at line 849 of file serialize.c.

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;
864 driver_tags_add(tl, name);
865 counter--;
866 }
867
868 return true;
869}
void driver_tags_add(struct TagList *tl, char *new_tag)
Add a tag to header.
Definition tags.c:105
Here is the call graph for this function:
Here is the caller graph for this function: