diff options
Diffstat (limited to 'doc/wiki/Design.Buffers.txt')
-rw-r--r-- | doc/wiki/Design.Buffers.txt | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/doc/wiki/Design.Buffers.txt b/doc/wiki/Design.Buffers.txt new file mode 100644 index 0000000..03542dc --- /dev/null +++ b/doc/wiki/Design.Buffers.txt @@ -0,0 +1,65 @@ +Buffers +======= + +'lib/buffers.h' describes Dovecot's buffer API. Unless your code happens to be +VERY performance critical, you shouldn't handle writing to buffers/arrays +manually, but instead use the buffer API's safe functions to guarantee that +your code can't write past the buffer and cause a security hole. + +Dovecot's buffers are the basic building block for <arrays> [Design.Arrays.txt] +and <strings> [Design.Strings.txt]. Use them instead if they make more sense +than buffers. + +There are a two different ways to create buffers: statically and dynamically +allocated. + +Static buffers +-------------- + +You can create statically allocated buffers with 'buffer_create_data()'. Trying +to write past the given buffer size will panic. The code to initialize this +looks like: + +---%<------------------------------------------------------------------------- +unsigned char buf_data[1024]; +buffer_t buf; + +buffer_create_data(&buf, buf_data, sizeof(buf_data)); +---%<------------------------------------------------------------------------- + +Trying to write more than 1024 bytes to the buffer will cause an assert-crash, +so these buffers shouldn't be used unless you know exactly what the maximum +buffer size is. + +To avoid accidental buffer overflows, don't use any more complex calculations +in the size parameter of 'buffer_create_data()'. It should always be +'sizeof(data_buffer)'. + +You can also create non-writable buffers with 'buffer_create_const_data()'. +Static buffers don't need to be freed. + +Dynamic buffers +--------------- + +Dynamically growing buffers can be created with 'buffer_create_dynamic(pool, +init_size)'. Memory for buffer is allocated from the given pool. When memory +needs to be grown, it's grown exponentially (2^n), with some exceptions to +avoid growing the given memory pool unless necessary. The initial buffer size +is always a guess - try to make it large enough that buffer wouldn't be grown +most of the time, but not so large that it wastes memory. + +You should be careful with memory returned by 'buffer_get_space_unsafe()' and +'buffer_append_space_unsafe()'. This returned memory should be accessed +immediately afterwards and it must not be accessed anymore after other +'buffer_*()' calls, because they may reallocate the buffer and move it +elsewhere in memory. + +Buffers always look like they're filled with NUL bytes. If you write past the +end of buffer, all the inserted bytes are filled with NULs. If you shrink the +buffer with 'buffer_set_used_size()' and again write past the end of used size, +all the old data is again gone and filled with NULs. If you for some reason +want to just temporarily shrink the buffer size and then change it back, you +can use 'buffer_set_used_size()' to grow it back to its original size (but no +larger). + +(This file was created from the wiki on 2019-06-19 12:42) |