dovecot: str_sanitize*(): Don't crash if max_len is less than 3.

dovecot at dovecot.org dovecot at dovecot.org
Fri Dec 21 16:40:04 EET 2007


details:   http://hg.dovecot.org/dovecot/rev/f359a0a9407f
changeset: 7002:f359a0a9407f
user:      Timo Sirainen <tss at iki.fi>
date:      Fri Dec 21 16:40:00 2007 +0200
description:
str_sanitize*(): Don't crash if max_len is less than 3.
str_sanitize(): If there's nothing to sanitize, don't bother allocating
memory, just return the input string. Also allow NULL as input.

diffstat:

3 files changed, 71 insertions(+), 15 deletions(-)
src/lib/str-sanitize.c |   47 ++++++++++++++++++++++++++++++++---------------
src/lib/str-sanitize.h |    2 ++
src/tests/test-lib.c   |   37 +++++++++++++++++++++++++++++++++++++

diffs (143 lines):

diff -r 7305d675b05c -r f359a0a9407f src/lib/str-sanitize.c
--- a/src/lib/str-sanitize.c	Fri Dec 21 16:23:56 2007 +0200
+++ b/src/lib/str-sanitize.c	Fri Dec 21 16:40:00 2007 +0200
@@ -4,25 +4,33 @@
 #include "str.h"
 #include "str-sanitize.h"
 
+static size_t str_sanitize_skip_start(const char *src, size_t max_len)
+{
+	size_t i;
+
+	for (i = 0; i < max_len; i++) {
+		if (((unsigned char)src[i] & 0x7f) < 32)
+			break;
+	}
+	return i;
+}
+
 void str_sanitize_append(string_t *dest, const char *src, size_t max_len)
 {
-	const char *p;
+	size_t i;
 
-	for (p = src; *p != '\0' && max_len > 0; p++, max_len--) {
-		if (((unsigned char)*p & 0x7f) < 32)
-			break;
+	i = str_sanitize_skip_start(src, max_len);
+	str_append_n(dest, src, i);
+
+	for (; i < max_len && src[i] != '\0'; i++) {
+		if (((unsigned char)src[i] & 0x7f) < 32)
+			str_append_c(dest, '?');
+		else
+			str_append_c(dest, src[i]);
 	}
 
-	str_append_n(dest, src, (size_t)(p - src));
-	for (; *p != '\0' && max_len > 0; p++, max_len--) {
-		if (((unsigned char)*p & 0x7f) < 32)
-			str_append_c(dest, '?');
-		else
-			str_append_c(dest, *p);
-	}
-
-	if (*p != '\0') {
-		str_truncate(dest, str_len(dest)-3);
+	if (src[i] != '\0') {
+		str_truncate(dest, str_len(dest) <= 3 ? 0 : str_len(dest)-3);
 		str_append(dest, "...");
 	}
 }
@@ -30,8 +38,17 @@ const char *str_sanitize(const char *src
 const char *str_sanitize(const char *src, size_t max_len)
 {
 	string_t *str;
+	size_t i;
+
+	if (src == NULL)
+		return NULL;
+
+	i = str_sanitize_skip_start(src, max_len);
+	if (src[i] == '\0')
+		return src;
 
 	str = t_str_new(I_MIN(max_len, 256));
-	str_sanitize_append(str, src, max_len);
+	str_append_n(str, src, i);
+	str_sanitize_append(str, src + i, max_len - i);
 	return str_c(str);
 }
diff -r 7305d675b05c -r f359a0a9407f src/lib/str-sanitize.h
--- a/src/lib/str-sanitize.h	Fri Dec 21 16:23:56 2007 +0200
+++ b/src/lib/str-sanitize.h	Fri Dec 21 16:40:00 2007 +0200
@@ -4,6 +4,8 @@
 /* All control characters in src will be appended as '?'. If src is longer
    than max_len, it's truncated with "..." appended to the end. */
 void str_sanitize_append(string_t *dest, const char *src, size_t max_len);
+/* Return src sanitized. If there are no changes, src pointer is returned.
+   If src is NULL, returns NULL. */
 const char *str_sanitize(const char *src, size_t max_len);
 
 #endif
diff -r 7305d675b05c -r f359a0a9407f src/tests/test-lib.c
--- a/src/tests/test-lib.c	Fri Dec 21 16:23:56 2007 +0200
+++ b/src/tests/test-lib.c	Fri Dec 21 16:40:00 2007 +0200
@@ -6,6 +6,7 @@
 #include "base64.h"
 #include "bsearch-insert-pos.h"
 #include "seq-range-array.h"
+#include "str-sanitize.h"
 
 static void test_base64_encode(void)
 {
@@ -165,6 +166,41 @@ static void test_seq_range_array(void)
 	}
 }
 
+struct str_sanitize_input {
+	const char *str;
+	unsigned int max_len;
+};
+static void test_str_sanitize(void)
+{
+	static struct str_sanitize_input input[] = {
+		{ NULL, 2 },
+		{ "", 2 },
+		{ "a", 2 },
+		{ "ab", 2 },
+		{ "abc", 2 },
+		{ "abcd", 3 },
+		{ "abcde", 4 }
+	};
+	static const char *output[] = {
+		NULL,
+		"",
+		"a",
+		"ab",
+		"...",
+		"...",
+		"a..."
+	};
+	const char *str;
+	unsigned int i;
+	bool success;
+
+	for (i = 0; i < N_ELEMENTS(input); i++) {
+		str = str_sanitize(input[i].str, input[i].max_len);
+		success = null_strcmp(output[i], str) == 0;
+		test_out(t_strdup_printf("str_sanitize(%d)", i), success);
+	}
+}
+
 int main(void)
 {
 	test_init();
@@ -173,6 +209,7 @@ int main(void)
 	test_base64_decode();
 	test_bsearch_insert_pos();
 	test_seq_range_array();
+	test_str_sanitize();
 	test_istreams();
 	return test_deinit();
 }


More information about the dovecot-cvs mailing list