dovecot-2.2: buffer: Always keep +1 byte available for str_c()'s...

dovecot at dovecot.org dovecot at dovecot.org
Sat Feb 16 18:57:45 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/c762a9af72c1
changeset: 15790:c762a9af72c1
user:      Timo Sirainen <tss at iki.fi>
date:      Tue Jan 15 08:30:03 2013 +0200
description:
buffer: Always keep +1 byte available for str_c()'s NUL.

diffstat:

 src/lib/Makefile.am |   1 +
 src/lib/buffer.c    |  11 +++++++++--
 src/lib/str.c       |   3 ---
 src/lib/test-lib.c  |   1 +
 src/lib/test-lib.h  |   1 +
 src/lib/test-str.c  |  26 ++++++++++++++++++++++++++
 6 files changed, 38 insertions(+), 5 deletions(-)

diffs (111 lines):

diff -r 6bee6d0c611f -r c762a9af72c1 src/lib/Makefile.am
--- a/src/lib/Makefile.am	Mon Jan 14 13:01:33 2013 +0200
+++ b/src/lib/Makefile.am	Tue Jan 15 08:30:03 2013 +0200
@@ -268,6 +268,7 @@
 	test-primes.c \
 	test-priorityq.c \
 	test-seq-range-array.c \
+	test-str.c \
 	test-strescape.c \
 	test-strfuncs.c \
 	test-str-find.c \
diff -r 6bee6d0c611f -r c762a9af72c1 src/lib/buffer.c
--- a/src/lib/buffer.c	Mon Jan 14 13:01:33 2013 +0200
+++ b/src/lib/buffer.c	Tue Jan 15 08:30:03 2013 +0200
@@ -39,6 +39,7 @@
 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)) {
@@ -53,7 +54,13 @@
 
 		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,
@@ -62,7 +69,7 @@
 		}
 
 		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 &&
diff -r 6bee6d0c611f -r c762a9af72c1 src/lib/str.c
--- a/src/lib/str.c	Mon Jan 14 13:01:33 2013 +0200
+++ b/src/lib/str.c	Tue Jan 15 08:30:03 2013 +0200
@@ -45,9 +45,6 @@
 	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 */
diff -r 6bee6d0c611f -r c762a9af72c1 src/lib/test-lib.c
--- a/src/lib/test-lib.c	Mon Jan 14 13:01:33 2013 +0200
+++ b/src/lib/test-lib.c	Tue Jan 15 08:30:03 2013 +0200
@@ -25,6 +25,7 @@
 		test_primes,
 		test_priorityq,
 		test_seq_range_array,
+		test_str,
 		test_strescape,
 		test_strfuncs,
 		test_str_find,
diff -r 6bee6d0c611f -r c762a9af72c1 src/lib/test-lib.h
--- a/src/lib/test-lib.h	Mon Jan 14 13:01:33 2013 +0200
+++ b/src/lib/test-lib.h	Tue Jan 15 08:30:03 2013 +0200
@@ -24,6 +24,7 @@
 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);
diff -r 6bee6d0c611f -r c762a9af72c1 src/lib/test-str.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/lib/test-str.c	Tue Jan 15 08:30:03 2013 +0200
@@ -0,0 +1,26 @@
+/* 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();
+}


More information about the dovecot-cvs mailing list