dovecot-2.0-pigeonhole: Restructured settings parsing and added ...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Tue Jan 25 02:07:42 EET 2011


details:   http://hg.rename-it.nl/dovecot-2.0-pigeonhole/rev/c21d4452b5eb
changeset: 1464:c21d4452b5eb
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Mon Jan 24 23:39:32 2011 +0100
description:
Restructured settings parsing and added parsing support for duration settings.

diffstat:

 src/lib-sieve/sieve-settings.c |  122 ++++++++++++++++++++++++++++++++++++----
 src/lib-sieve/sieve-settings.h |    3 +
 2 files changed, 112 insertions(+), 13 deletions(-)

diffs (188 lines):

diff -r 1a9955262f5c -r c21d4452b5eb src/lib-sieve/sieve-settings.c
--- a/src/lib-sieve/sieve-settings.c	Sun Jan 23 13:44:13 2011 +0100
+++ b/src/lib-sieve/sieve-settings.c	Mon Jan 24 23:39:32 2011 +0100
@@ -10,6 +10,44 @@
 #include <stdlib.h>
 #include <ctype.h>
 
+static bool sieve_setting_parse_uint
+(struct sieve_instance *svinst, const char *setting, const char *str_value,
+	char **endptr, unsigned long long int *value_r)
+{
+	if ( (*value_r = strtoull(str_value, endptr, 10)) == ULLONG_MAX
+		&& errno == ERANGE ) {
+		sieve_sys_warning(svinst,
+			"overflowing unsigned integer value for setting '%s': '%s'",
+			setting, str_value);
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
+static bool sieve_setting_parse_int
+(struct sieve_instance *svinst, const char *setting, const char *str_value,
+	char **endptr, long long int *value_r)
+{
+	*value_r = strtoll(str_value, endptr, 10);
+
+	if ( *value_r == LLONG_MIN && errno == ERANGE ) {
+		sieve_sys_warning(svinst,
+			"underflowing integer value for setting '%s': '%s'",
+			setting, str_value);
+		return FALSE;
+	}
+
+	if ( *value_r == LLONG_MAX && errno == ERANGE ) {
+		sieve_sys_warning(svinst,
+			"overflowing integer value for setting '%s': '%s'",
+			setting, str_value);
+		return FALSE;
+	}
+	
+	return TRUE;
+}
+
 bool sieve_setting_get_uint_value
 (struct sieve_instance *svinst, const char *setting,
 	unsigned long long int *value_r)
@@ -22,7 +60,8 @@
 	if ( str_value == NULL || *str_value == '\0' )
 		return FALSE;
 
-	*value_r = strtoull(str_value, &endp, 10);
+	if ( !sieve_setting_parse_uint(svinst, setting, str_value, &endp, value_r) )
+		return FALSE;
 
 	if ( *endp != '\0' ) {
 		sieve_sys_warning(svinst,
@@ -46,7 +85,8 @@
 	if ( str_value == NULL || *str_value == '\0' )
 		return FALSE;
 
-	*value_r = strtoll(str_value, &endp, 10);
+	if ( !sieve_setting_parse_int(svinst, setting, str_value, &endp, value_r) )
+		return FALSE;
 
 	if ( *endp != '\0' ) {
 		sieve_sys_warning(svinst, "invalid integer value for setting '%s': '%s'",
@@ -71,35 +111,41 @@
 	if ( str_value == NULL || *str_value == '\0' )
 		return FALSE;
 
-	value = strtoull(str_value, &endp, 10);
+	if ( !sieve_setting_parse_uint(svinst, setting, str_value, &endp, &value) )
+		return FALSE;
 
 	switch (i_toupper(*endp)) {
-	case '\0':
-		/* default */
-		break;
-	case 'B':
+	case '\0': /* default */
+	case 'B': /* byte (useless) */
 		multiply = 1;
 		break;
-	case 'K':	
+	case 'k': /* kilobyte */
+	case 'K':	 
 		multiply = 1024;
 		break;
-	case 'M':
+	case 'M': /* megabyte */
 		multiply = 1024*1024;
 		break;
-	case 'G':
+	case 'G': /* gigabyte */
 		multiply = 1024*1024*1024;
 		break;
-	case 'T':
+	case 'T': /* terabyte */
 		multiply = 1024ULL*1024*1024*1024;
 		break;
 	default:
 		sieve_sys_warning(svinst,
-			"invalid unsigned integer value for setting '%s': '%s'",
+			"invalid size value for setting '%s': '%s'",
 			setting, str_value);
 		return FALSE;
 	}
 
-	/* FIXME: conversion to size_t may overflow */
+	if ( value > SSIZE_T_MAX / multiply ) {
+		sieve_sys_warning(svinst,
+			"overflowing size value for setting '%s': '%s'",
+			setting, str_value);
+		return FALSE;
+	}
+
 	*value_r = (size_t) (value * multiply);
 	
 	return TRUE;
@@ -130,3 +176,53 @@
 		setting, str_value);
 	return FALSE;
 }
+
+bool sieve_setting_get_duration_value
+(struct sieve_instance *svinst, const char *setting,
+	unsigned int *value_r)
+{
+	const char *str_value;
+	unsigned long long int value, multiply = 1;
+	char *endp;
+
+	str_value = sieve_setting_get(svinst, setting);
+
+	if ( str_value == NULL || *str_value == '\0' )
+		return FALSE;
+
+	if ( !sieve_setting_parse_uint(svinst, setting, str_value, &endp, &value) )
+		return FALSE;
+
+	switch (i_toupper(*endp)) {
+	case '\0': /* default */
+	case 's': /* seconds */
+		multiply = 1;
+		break;
+	case 'm': /* minutes */	
+		multiply = 60;
+		break;
+	case 'h': /* hours */
+		multiply = 60*60;
+		break;
+	case 'd': /* days */
+		multiply = 24*60*60;
+		break;
+	default:
+		sieve_sys_warning(svinst,
+			"invalid duration value for setting '%s': '%s'",
+			setting, str_value);
+		return FALSE;
+	}
+
+	if ( value > UINT_MAX / multiply ) {
+		sieve_sys_warning(svinst,
+			"overflowing duration value for setting '%s': '%s'",
+			setting, str_value);
+		return FALSE;
+	}
+
+	*value_r = (unsigned int) (value * multiply);
+	
+	return TRUE;
+}
+
diff -r 1a9955262f5c -r c21d4452b5eb src/lib-sieve/sieve-settings.h
--- a/src/lib-sieve/sieve-settings.h	Sun Jan 23 13:44:13 2011 +0100
+++ b/src/lib-sieve/sieve-settings.h	Mon Jan 24 23:39:32 2011 +0100
@@ -33,6 +33,9 @@
 bool sieve_setting_get_bool_value
 	(struct sieve_instance *svinst, const char *setting,
 		bool *value_r);
+bool sieve_setting_get_duration_value
+	(struct sieve_instance *svinst, const char *setting,
+		unsigned int *value_r);
 
 /*
  * Home directory


More information about the dovecot-cvs mailing list