static inline void
buffer_check_limits(struct real_buffer *buf, size_t pos, size_t data_size)
{
+ unsigned int extra;
size_t new_size;
if (unlikely((size_t)-1 - pos < data_size)) {
memset(buf->w_buffer + buf->used, 0, max - buf->used);
}
- if (new_size > buf->alloc) {
+
+ /* always keep +1 byte allocated available in case str_c() is called
+ for this buffer. this is mainly for cases where the buffer is
+ allocated from data stack, and str_c() is called in a separate stack
+ frame. */
+ extra = buf->dynamic ? 1 : 0;
+ if (new_size + extra > buf->alloc) {
if (unlikely(!buf->dynamic)) {
i_panic("Buffer full (%"PRIuSIZE_T" > %"PRIuSIZE_T", "
"pool %s)", pos + data_size, buf->alloc,
}
buffer_alloc(buf, pool_get_exp_grown_size(buf->pool, buf->alloc,
- new_size));
+ new_size + extra));
}
#if 0
else if (new_size > buf->used && buf->alloced &&
size_t len = str_len(str);
size_t alloc = buffer_get_size(str);
-#ifdef DEBUG
- buffer_verify_pool(str);
-#endif
if (len == alloc || data[len] != '\0') {
buffer_write(str, len, "", 1);
/* remove the \0 - we don't want to keep it */
void test_primes(void);
void test_priorityq(void);
void test_seq_range_array(void);
+void test_str(void);
void test_strescape(void);
void test_strfuncs(void);
void test_str_find(void);
--- /dev/null
+/* Copyright (c) 2012 Dovecot authors, see the included COPYING file */
+
+#include "test-lib.h"
+#include "str.h"
+
+static void test_str_c(void)
+{
+ string_t *str;
+ unsigned int i, j;
+
+ test_begin("str_c()");
+ for (i = 0; i < 32; i++) T_BEGIN {
+ str = t_str_new(15);
+ for (j = 0; j < i; j++)
+ str_append_c(str, 'x');
+ T_BEGIN {
+ (void)str_c(str);
+ } T_END;
+ } T_END;
+ test_end();
+}
+
+void test_str(void)
+{
+ test_str_c();
+}