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