changeset 19038:f8ab4f979e92

Removed all invocations of strtoll() and friends.
author Stephan Bosch <stephan@rename-it.nl>
date Sat, 29 Aug 2015 14:42:49 +0300
parents de73e7121676
children 8f8f768937f5
files configure.ac src/anvil/anvil-connection.c src/auth/checkpassword-reply.c src/doveadm/doveadm-penalty.c src/doveadm/doveadm-who.c src/doveadm/dsync/dsync-ibc-stream.c src/lib-dict/dict-file.c src/lib-fs/fs-posix.c src/lib-otp/otp-parse.c src/lib-settings/settings-parser.c src/lib-storage/index/dbox-common/dbox-file.c src/lib-storage/index/dbox-common/dbox-mail.c src/lib-storage/index/maildir/maildir-uidlist.c src/lib-storage/mailbox-uidvalidity.c src/lib/compat.c src/lib/compat.h src/lib/rand.c src/lib/var-expand.c src/log/log-connection.c src/login-common/sasl-server.c src/master/main.c src/plugins/quota/quota-dict.c src/plugins/quota/quota-maildir.c src/plugins/quota/quota-util.c src/util/maildirlock.c
diffstat 25 files changed, 172 insertions(+), 156 deletions(-) [+]
line wrap: on
line diff
--- a/configure.ac	Sat Aug 29 14:31:51 2015 +0300
+++ b/configure.ac	Sat Aug 29 14:42:49 2015 +0300
@@ -453,10 +453,10 @@
 AC_CHECK_FUNCS(fcntl flock lockf inet_aton sigaction getpagesize madvise \
                strcasecmp stricmp vsyslog writev pread uname unsetenv \
 	       setrlimit setproctitle seteuid setreuid setegid setresgid \
-	       strtoull strtoll strtouq strtoq getmntinfo \
-	       setpriority quotactl getmntent kqueue kevent backtrace_symbols \
-	       walkcontext dirfd clearenv malloc_usable_size glob fallocate \
-	       posix_fadvise getpeereid getpeerucred inotify_init)
+	       getmntinfo setpriority quotactl getmntent kqueue kevent \
+	       backtrace_symbols walkcontext dirfd clearenv \
+	       malloc_usable_size glob fallocate posix_fadvise \
+	       getpeereid getpeerucred inotify_init)
 
 AC_CHECK_TYPES([struct sockpeercred],,,[
 #include <sys/types.h>
@@ -482,38 +482,6 @@
   AC_DEFINE(HAVE_TYPEOF,, [Define if you have typeof()])
 fi
 
-dnl strtoimax and strtoumax are macros in HP-UX, so inttypes.h must be included
-dnl Link instead of just compiling since there's something wrong with Tru64
-AC_CACHE_CHECK([for strtoimax],i_cv_have_strtoimax,[
-  AC_TRY_LINK([
-    #include <inttypes.h>
-  ], [
-    strtoimax(0, 0, 0);
-  ], [
-    i_cv_have_strtoimax=yes
-  ], [
-    i_cv_have_strtoimax=no
-  ])
-])
-if test $i_cv_have_strtoimax = yes; then
-  AC_DEFINE(HAVE_STRTOIMAX,, [Define if you have strtoimax function])
-fi
-
-AC_CACHE_CHECK([for strtoumax],i_cv_have_strtoumax,[
-  AC_TRY_LINK([
-    #include <inttypes.h>
-  ], [
-    strtoumax(0, 0, 0);
-  ], [
-    i_cv_have_strtoumax=yes
-  ], [
-    i_cv_have_strtoumax=no
-  ])
-])
-if test $i_cv_have_strtoumax = yes; then
-  AC_DEFINE(HAVE_STRTOUMAX,, [Define if you have strtoumax function])
-fi
-
 dnl * I/O loop function
 have_ioloop=no
 
--- a/src/anvil/anvil-connection.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/anvil/anvil-connection.c	Sat Aug 29 14:42:49 2015 +0300
@@ -58,14 +58,20 @@
 			*error_r = "CONNECT: Not enough parameters";
 			return -1;
 		}
-		pid = strtol(args[0], NULL, 10);
+		if (str_to_pid(args[0], &pid) < 0) {
+			*error_r = "CONNECT: Invalid pid";
+			return -1;
+		}
 		connect_limit_connect(connect_limit, pid, args[1]);
 	} else if (strcmp(cmd, "DISCONNECT") == 0) {
 		if (args[0] == NULL || args[1] == NULL) {
 			*error_r = "DISCONNECT: Not enough parameters";
 			return -1;
 		}
-		pid = strtol(args[0], NULL, 10);
+		if (str_to_pid(args[0], &pid) < 0) {
+			*error_r = "DISCONNECT: Invalid pid";
+			return -1;
+		}
 		connect_limit_disconnect(connect_limit, pid, args[1]);
 	} else if (strcmp(cmd, "CONNECT-DUMP") == 0) {
 		connect_limit_dump(connect_limit, conn->output);
@@ -78,7 +84,10 @@
 			*error_r = "KILL sent by a non-master connection";
 			return -1;
 		}
-		pid = strtol(args[0], NULL, 10);
+		if (str_to_pid(args[0], &pid) < 0) {
+			*error_r = "KILL: Invalid pid";
+			return -1;
+		}
 		connect_limit_disconnect_pid(connect_limit, pid);
 	} else if (strcmp(cmd, "LOOKUP") == 0) {
 		if (args[0] == NULL) {
--- a/src/auth/checkpassword-reply.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/auth/checkpassword-reply.c	Sat Aug 29 14:42:49 2015 +0300
@@ -11,14 +11,18 @@
 int main(void)
 {
 	string_t *str;
-	const char *user, *home, *authorized, *orig_uid;
+	const char *user, *home, *authorized, *orig_uid_env;
 	const char *extra_env, *key, *value, *const *tmp;
 	bool uid_found = FALSE, gid_found = FALSE;
+	uid_t orig_uid;
 
 	lib_init();
 	str = t_str_new(1024);
 
-	orig_uid = getenv("ORIG_UID");
+	orig_uid_env = getenv("ORIG_UID");
+	if (orig_uid_env == NULL || str_to_uid(orig_uid_env, &orig_uid) < 0)
+		orig_uid = (uid_t)-1;
+
 	/* ORIG_UID should have the auth process's UID that forked us.
 	   if the checkpassword changed the UID, this could be a security hole
 	   because the UID's other processes can ptrace this process and write
@@ -30,9 +34,9 @@
 	      userdb_uid instead)
 	   */
 	if (getenv("INSECURE_SETUID") == NULL &&
-	    (orig_uid == NULL || strtoul(orig_uid, NULL, 10) != getuid()) &&
+	    (orig_uid == (uid_t)-1 || orig_uid != getuid()) &&
 	    getuid() == geteuid() && getgid() == getegid()) {
-		if (orig_uid == NULL) {
+		if (orig_uid_env == NULL) {
 			i_error("checkpassword: ORIG_UID environment was dropped by checkpassword. "
 				"Can't verify if we're safe to run. See "
 				"http://wiki2.dovecot.org/AuthDatabase/CheckPassword#Security");
--- a/src/doveadm/doveadm-penalty.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/doveadm/doveadm-penalty.c	Sat Aug 29 14:42:49 2015 +0300
@@ -36,9 +36,10 @@
 	memset(line_r, 0, sizeof(*line_r));
 
 	(void)net_addr2ip(ident, &line_r->ip);
-	line_r->penalty = strtoul(penalty_str, NULL, 10);
-	line_r->last_penalty = strtoul(last_penalty_str, NULL, 10);
-	line_r->last_update = strtoul(last_update_str, NULL, 10);
+	if (str_to_uint(penalty_str, &line_r->penalty) < 0 ||
+	    str_to_time(last_penalty_str, &line_r->last_penalty) < 0 ||
+	    str_to_time(last_update_str, &line_r->last_update) < 0)
+		i_fatal("Read invalid penalty line: %s", line);
 }
 
 static void
--- a/src/doveadm/doveadm-who.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/doveadm/doveadm-who.c	Sat Aug 29 14:42:49 2015 +0300
@@ -63,7 +63,8 @@
 	p = strchr(ident, '/');
 	if (p == NULL)
 		return -1;
-	line_r->pid = strtoul(pid_str, NULL, 10);
+	if (str_to_pid(pid_str, &line_r->pid) < 0)
+		return -1;
 	line_r->service = t_strdup_until(ident, p++);
 	line_r->username = strchr(p, '/');
 	if (line_r->username == NULL)
--- a/src/doveadm/dsync/dsync-ibc-stream.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/doveadm/dsync/dsync-ibc-stream.c	Sat Aug 29 14:42:49 2015 +0300
@@ -1593,6 +1593,7 @@
 	struct dsync_deserializer_decoder *decoder;
 	struct dsync_mail_change *change;
 	const char *value;
+	unsigned int uintval;
 	enum dsync_ibc_recv_ret ret;
 
 	p_clear(pool);
@@ -1639,12 +1640,33 @@
 		return DSYNC_IBC_RECV_RET_TRYAGAIN;
 	}
 
-	if (dsync_deserializer_decode_try(decoder, "add_flags", &value))
-		change->add_flags = strtoul(value, NULL, 16);
-	if (dsync_deserializer_decode_try(decoder, "remove_flags", &value))
-		change->remove_flags = strtoul(value, NULL, 16);
-	if (dsync_deserializer_decode_try(decoder, "final_flags", &value))
-		change->final_flags = strtoul(value, NULL, 16);
+	if (dsync_deserializer_decode_try(decoder, "add_flags", &value)) {
+		if (str_to_uint_hex(value, &uintval) < 0 ||
+		    uintval > (uint8_t)-1) {
+			dsync_ibc_input_error(ibc, decoder,
+				"Invalid add_flags: %s", value);
+			return DSYNC_IBC_RECV_RET_TRYAGAIN;
+		}
+		change->add_flags = uintval;
+	}
+	if (dsync_deserializer_decode_try(decoder, "remove_flags", &value)) {
+		if (str_to_uint_hex(value, &uintval) < 0 ||
+		    uintval > (uint8_t)-1) {
+			dsync_ibc_input_error(ibc, decoder,
+				"Invalid remove_flags: %s", value);
+			return DSYNC_IBC_RECV_RET_TRYAGAIN;
+		}
+		change->remove_flags = uintval;
+	}
+	if (dsync_deserializer_decode_try(decoder, "final_flags", &value)) {
+		if (str_to_uint_hex(value, &uintval) < 0 ||
+		    uintval > (uint8_t)-1) {
+			dsync_ibc_input_error(ibc, decoder,
+				"Invalid final_flags: %s", value);
+			return DSYNC_IBC_RECV_RET_TRYAGAIN;
+		}
+		change->final_flags = uintval;
+	}
 	if (dsync_deserializer_decode_try(decoder, "keywords_reset", &value))
 		change->keywords_reset = TRUE;
 
--- a/src/lib-dict/dict-file.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-dict/dict-file.c	Sat Aug 29 14:42:49 2015 +0300
@@ -329,8 +329,9 @@
 				*atomic_inc_not_found_r = TRUE;
 				break;
 			}
-			diff = strtoll(old_value, NULL, 10) +
-				change->value.diff;
+			if (str_to_llong(old_value, &diff) < 0)
+				i_unreached();
+			diff +=	change->value.diff;
 			tmp = t_strdup_printf("%lld", diff);
 			new_len = strlen(tmp);
 			if (old_value == NULL || new_len > strlen(old_value))
--- a/src/lib-fs/fs-posix.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-fs/fs-posix.c	Sat Aug 29 14:42:49 2015 +0300
@@ -104,7 +104,12 @@
 			else
 				fs->path_prefix = i_strdup(arg + 7);
 		} else if (strncmp(arg, "mode=", 5) == 0) {
-			fs->mode = strtoul(arg+5, NULL, 8) & 0666;
+			unsigned int mode;
+			if (str_to_uint_oct(arg+5, &mode) < 0) {
+				fs_set_error(_fs, "Invalid mode value: %s", arg+5);
+				return -1;
+			}
+			fs->mode = mode & 0666;
 			if (fs->mode == 0) {
 				fs_set_error(_fs, "Invalid mode: %s", arg+5);
 				return -1;
--- a/src/lib-otp/otp-parse.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-otp/otp-parse.c	Sat Aug 29 14:42:49 2015 +0300
@@ -148,7 +148,6 @@
 			struct otp_state *state)
 {
 	const char *p, *s;
-	char *end;
 	unsigned int i = 0;
 	int algo;
 
@@ -164,8 +163,7 @@
 	state->algo = algo;
 
 	s = p;
-	state->seq = strtol(s, &end, 10); p = end;
-	if ((p == s) || !IS_LWS(*p))
+	if (str_parse_int(s, &state->seq, &p) < 0 || !IS_LWS(*p))
 		return -3;
 	p++;
 
--- a/src/lib-settings/settings-parser.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-settings/settings-parser.c	Sat Aug 29 14:42:49 2015 +0300
@@ -338,13 +338,11 @@
 	  unsigned int *result_r)
 {
 	unsigned long long octal;
-	char *p;
 
 	if (*value != '0')
 		return get_uint(ctx, value, result_r);
 
-	octal = strtoull(value + 1, &p, 8);
-	if (*p != '\0' || octal > UINT_MAX) {
+	if (str_to_ullong_oct(value+1, &octal) < 0) {
 		ctx->error = p_strconcat(ctx->parser_pool, "Invalid number: ",
 					 value, NULL);
 	}
@@ -355,10 +353,13 @@
 int settings_get_time(const char *str, unsigned int *secs_r,
 		      const char **error_r)
 {
-	unsigned int num, multiply = 1;
-	char *p;
+	uintmax_t num, multiply = 1;
+	const char *p;
 
-	num = strtoull(str, &p, 10);
+	if (str_parse_uintmax(str, &num, &p) < 0) {
+		*error_r = t_strconcat("Invalid time interval: ", str, NULL);
+		return -1;
+	}
 	while (*p == ' ') p++;
 	switch (i_toupper(*p)) {
 	case 'S':
@@ -406,10 +407,13 @@
 int settings_get_size(const char *str, uoff_t *bytes_r,
 		      const char **error_r)
 {
-	unsigned long long num, multiply = 1;
-	char *p;
+	uintmax_t num, multiply = 1;
+	const char *p;
 
-	num = strtoull(str, &p, 10);
+	if (str_parse_uintmax(str, &num, &p) < 0) {
+		*error_r = t_strconcat("Invalid size: ", str, NULL);
+		return -1;
+	}
 	while (*p == ' ') p++;
 	switch (i_toupper(*p)) {
 	case 'B':
@@ -445,7 +449,7 @@
 		*error_r = t_strconcat("Invalid size: ", str, NULL);
 		return -1;
 	}
-	if (num > ULLONG_MAX / multiply) {
+	if (num > ((uoff_t)-1) / multiply) {
 		*error_r = t_strconcat("Size is too large: ", str, NULL);
 		return -1;
 	}
--- a/src/lib-storage/index/dbox-common/dbox-file.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-file.c	Sat Aug 29 14:42:49 2015 +0300
@@ -112,6 +112,7 @@
 	file->msg_header_size = 0;
 
 	for (tmp = t_strsplit(line, " "); *tmp != NULL; tmp++) {
+		uintmax_t time;
 		key = **tmp;
 		value = *tmp + 1;
 
@@ -119,10 +120,17 @@
 		case DBOX_HEADER_OLDV1_APPEND_OFFSET:
 			break;
 		case DBOX_HEADER_MSG_HEADER_SIZE:
-			file->msg_header_size = strtoul(value, NULL, 16);
+			if (str_to_uint_hex(value, &file->msg_header_size) < 0) {
+				dbox_file_set_corrupted(file, "Invalid message header size");
+				return -1;
+			}
 			break;
 		case DBOX_HEADER_CREATE_STAMP:
-			file->create_time = strtoul(value, NULL, 16);
+			if (str_to_uintmax_hex(value, &time) < 0) {
+				dbox_file_set_corrupted(file, "Invalid create time stamp");
+				return -1;
+			}
+			file->create_time = (time_t)time;
 			break;
 		}
 		pos += strlen(value) + 2;
@@ -735,17 +743,20 @@
 uoff_t dbox_file_get_plaintext_size(struct dbox_file *file)
 {
 	const char *value;
+	uintmax_t size;
 
 	i_assert(file->metadata_read_offset == file->cur_offset);
 
 	/* see if we have it in metadata */
 	value = dbox_file_metadata_get(file, DBOX_METADATA_PHYSICAL_SIZE);
-	if (value != NULL)
-		return strtoul(value, NULL, 16);
-	else {
+	if (value == NULL ||
+	    str_to_uintmax_hex(value, &size) < 0 ||
+	    size > (uoff_t)-1) {
 		/* no. that means we can use the size in the header */
 		return file->cur_physical_size;
 	}
+
+	return (uoff_t)size;
 }
 
 void dbox_msg_header_fill(struct dbox_message_header *dbox_msg_hdr,
--- a/src/lib-storage/index/dbox-common/dbox-mail.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-storage/index/dbox-common/dbox-mail.c	Sat Aug 29 14:42:49 2015 +0300
@@ -96,6 +96,7 @@
 	struct dbox_mail *mail = (struct dbox_mail *)_mail;
 	struct index_mail_data *data = &mail->imail.data;
 	const char *value;
+	uintmax_t size;
 
 	if (index_mail_get_cached_virtual_size(&mail->imail, size_r))
 		return 0;
@@ -106,7 +107,9 @@
 	if (value == NULL)
 		return index_mail_get_virtual_size(_mail, size_r);
 
-	data->virtual_size = strtoul(value, NULL, 16);
+	if (str_to_uintmax_hex(value, &size) < 0 || size > (uoff_t)-1)
+		return -1;
+	data->virtual_size = (uoff_t)size;
 	*size_r = data->virtual_size;
 	return 0;
 }
@@ -116,6 +119,7 @@
 	struct dbox_mail *mail = (struct dbox_mail *)_mail;
 	struct index_mail_data *data = &mail->imail.data;
 	const char *value;
+	uintmax_t time;
 
 	if (index_mail_get_received_date(_mail, date_r) == 0)
 		return 0;
@@ -124,7 +128,11 @@
 				   &value) < 0)
 		return -1;
 
-	data->received_date = value == NULL ? 0 : strtoul(value, NULL, 16);
+	time = 0;
+	if (value != NULL && str_to_uintmax_hex(value, &time) < 0)
+		return -1;
+
+	data->received_date = (time_t)time;
 	*date_r = data->received_date;
 	return 0;
 }
--- a/src/lib-storage/index/maildir/maildir-uidlist.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-storage/index/maildir/maildir-uidlist.c	Sat Aug 29 14:42:49 2015 +0300
@@ -591,10 +591,18 @@
 
 		switch (key) {
 		case MAILDIR_UIDLIST_HDR_EXT_UID_VALIDITY:
-			*uid_validity_r = strtoul(value, NULL, 10);
+			if (str_to_uint(value, uid_validity_r) < 0) {
+				maildir_uidlist_set_corrupted(uidlist,
+					"Invalid mailbox UID_VALIDITY: %s", value);
+				return -1;
+			}
 			break;
 		case MAILDIR_UIDLIST_HDR_EXT_NEXT_UID:
-			*next_uid_r = strtoul(value, NULL, 10);
+			if (str_to_uint(value, next_uid_r) < 0) {
+				maildir_uidlist_set_corrupted(uidlist,
+					"Invalid mailbox NEXT_UID: %s", value);
+				return -1;
+			}
 			break;
 		case MAILDIR_UIDLIST_HDR_EXT_GUID:
 			if (guid_128_from_string(value,
--- a/src/lib-storage/mailbox-uidvalidity.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib-storage/mailbox-uidvalidity.c	Sat Aug 29 14:42:49 2015 +0300
@@ -108,7 +108,6 @@
 	DIR *d;
 	struct dirent *dp;
 	const char *fname, *dir, *prefix, *tmp;
-	char *endp;
 	unsigned int i, prefix_len;
 	uint32_t cur_value, min_value, max_value;
 	mode_t old_mask;
@@ -145,8 +144,7 @@
 	max_value = 0; min_value = (uint32_t)-1;
 	while ((dp = readdir(d)) != NULL) {
 		if (strncmp(dp->d_name, prefix, prefix_len) == 0) {
-			cur_value = strtoul(dp->d_name + prefix_len, &endp, 16);
-			if (*endp == '\0') {
+			if (str_to_uint32_hex(dp->d_name + prefix_len, &cur_value) >= 0) {
 				if (min_value > cur_value)
 					min_value = cur_value;
 				if (max_value < cur_value)
@@ -196,7 +194,7 @@
 
 uint32_t mailbox_uidvalidity_next(struct mailbox_list *list, const char *path)
 {
-	char buf[8+1], *endp;
+	char buf[8+1];
 	uint32_t cur_value;
 	int fd, ret;
 
@@ -213,8 +211,7 @@
 		return mailbox_uidvalidity_next_rescan(list, path);
 	}
 	buf[sizeof(buf)-1] = 0;
-	cur_value = strtoul(buf, &endp, 16);
-	if (ret == 0 || endp != buf+sizeof(buf)-1) {
+	if (ret == 0 || str_to_uint32_hex(buf, &cur_value) < 0) {
 		/* broken value */
 		i_close_fd(&fd);
 		return mailbox_uidvalidity_next_rescan(list, path);
--- a/src/lib/compat.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib/compat.c	Sat Aug 29 14:42:49 2015 +0300
@@ -19,9 +19,6 @@
 #include <syslog.h>
 #include <time.h>
 #include <sys/time.h>
-#ifdef HAVE_INTTYPES_H
-#  include <inttypes.h> /* for strtoimax() and strtoumax() */
-#endif
 
 #ifndef INADDR_NONE
 #  define INADDR_NONE INADDR_BROADCAST
@@ -206,44 +203,6 @@
 }
 #endif
 
-#ifndef HAVE_STRTOULL
-unsigned long long int i_my_strtoull(const char *nptr, char **endptr, int base)
-{
-#ifdef HAVE_STRTOUMAX
-	return strtoumax(nptr, endptr, base);
-#elif defined(HAVE_STRTOUQ)
-	return strtouq(nptr, endptr, base);
-#else
-	unsigned long ret = 0;
-
-	/* we support only base-10 in our fallback implementation.. */
-	i_assert(base == 10);
-
-	for (; *nptr != '\0'; nptr++) {
-		if (*nptr < '0' || *nptr > '9')
-			break;
-		ret = ret * 10 + (*nptr - '0');
-	}
-	if (endptr != NULL)
-		*endptr = (char *)nptr;
-	return ret;
-#endif
-}
-#endif
-
-#ifndef HAVE_STRTOLL
-unsigned long long int i_my_strtoll(const char *nptr, char **endptr, int base)
-{
-#ifdef HAVE_STRTOIMAX 
-	return strtoimax(nptr, endptr, base);
-#elif defined (HAVE_STRTOQ)
-	return strtoq(nptr, endptr, base);
-#else
-	i_panic("strtoll() not implemented");
-#endif
-}
-#endif
-
 #ifdef HAVE_OLD_VSNPRINTF
 #undef vsnprintf
 int i_my_vsnprintf(char *str, size_t size, const char *format, va_list ap)
--- a/src/lib/compat.h	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib/compat.h	Sat Aug 29 14:42:49 2015 +0300
@@ -184,15 +184,6 @@
 char *i_my_basename(char *path);
 #endif
 
-#ifndef HAVE_STRTOULL
-#  define strtoull i_my_strtoull
-unsigned long long int i_my_strtoull(const char *nptr, char **endptr, int base);
-#endif
-#ifndef HAVE_STRTOLL
-#  define strtoll i_my_strtoll
-unsigned long long int i_my_strtoll(const char *nptr, char **endptr, int base);
-#endif
-
 #ifdef HAVE_OLD_VSNPRINTF
 #  include <stdio.h>
 #  define vsnprintf i_my_vsnprintf
--- a/src/lib/rand.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib/rand.c	Sat Aug 29 14:42:49 2015 +0300
@@ -21,9 +21,10 @@
 void rand_set_seed(unsigned int s)
 {
 	if (seeded == 0) {
+		unsigned int seedval;
 		env_seed = getenv("DOVECOT_SRAND");
-		if (env_seed != NULL)
-			seed = strtoul(env_seed, NULL, 0);
+		if (env_seed != NULL && str_to_uint(env_seed, &seedval) >= 0)
+			seed = seedval;
 	}
 	seeded++;
 	if (env_seed == NULL)
--- a/src/lib/var-expand.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/lib/var-expand.c	Sat Aug 29 14:42:49 2015 +0300
@@ -51,7 +51,8 @@
 {
 	unsigned long long l;
 
-	l = strtoull(str, NULL, 10);
+	if (str_to_ullong(str, &l) < 0)
+		l = 0;
 	return t_strdup_printf("%llx", l);
 }
 
--- a/src/log/log-connection.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/log/log-connection.c	Sat Aug 29 14:42:49 2015 +0300
@@ -180,7 +180,7 @@
 {
 	struct log_connection *const *logs, *log;
 	struct log_client *client;
-	const char *p, *p2, *cmd;
+	const char *p, *p2, *cmd, *pidstr;
 	unsigned int count;
 	unsigned int service_fd;
 	pid_t pid;
@@ -191,7 +191,11 @@
 		i_error("Received invalid input from master: %s", line);
 		return;
 	}
-	pid = strtol(t_strcut(p, ' '), NULL, 10);
+	pidstr = t_strcut(p, ' ');
+	if (str_to_pid(pidstr, &pid) < 0) {
+		i_error("Received invalid pid from master: %s", pidstr);
+		return;
+	}
 	cmd = p2 + 1;
 
 	logs = array_get(&logs_by_fd, &count);
--- a/src/login-common/sasl-server.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/login-common/sasl-server.c	Sat Aug 29 14:42:49 2015 +0300
@@ -163,9 +163,13 @@
 	struct client *client = req->client;
 	const struct login_settings *set = client->set;
 	const char *errmsg;
+	unsigned int conn_count;
 
-	if (reply == NULL ||
-	    strtoul(reply, NULL, 10) < set->mail_max_userip_connections)
+	conn_count = 0;
+	if (reply != NULL && str_to_uint(reply, &conn_count) < 0)
+		i_fatal("Received invalid reply from anvil: %s", reply);
+
+	if (conn_count < set->mail_max_userip_connections)
 		master_send_request(req);
 	else {
 		client->authenticating = FALSE;
--- a/src/master/main.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/master/main.c	Sat Aug 29 14:42:49 2015 +0300
@@ -143,11 +143,14 @@
 {
 	const char *path, *str;
 	va_list args2;
+	pid_t pid;
 	int fd;
-
+	
 	/* if we already forked a child process, this isn't fatal for the
 	   main process and there's no need to write the fatal file. */
-	if (getpid() == strtol(my_pid, NULL, 10)) {
+	if (str_to_pid(my_pid, &pid) < 0)
+		i_unreached();
+	if (getpid() == pid) {
 		/* write the error message to a file (we're chdired to
 		   base dir) */
 		path = t_strconcat(FATAL_FILENAME, NULL);
--- a/src/plugins/quota/quota-dict.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/plugins/quota/quota-dict.c	Sat Aug 29 14:42:49 2015 +0300
@@ -159,11 +159,12 @@
 		if (ret < 0)
 			*value_r = 0;
 		else {
-			long long tmp;
+			intmax_t tmp;
 
 			/* recalculate quota if it's negative or if it
 			   wasn't found */
-			tmp = ret == 0 ? -1 : strtoll(value, NULL, 10);
+			if (ret == 0 || str_to_intmax(value, &tmp) < 0)
+				tmp = -1;
 			if (tmp >= 0)
 				*value_r = tmp;
 			else {
--- a/src/plugins/quota/quota-maildir.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/plugins/quota/quota-maildir.c	Sat Aug 29 14:42:49 2015 +0300
@@ -417,7 +417,7 @@
 {
 	const char *const *limit;
 	unsigned long long value;
-	char *pos;
+	const char *pos;
 	bool ret = TRUE;
 
 	*bytes_r = 0;
@@ -425,7 +425,10 @@
 
 	/* 0 values mean unlimited */
 	for (limit = t_strsplit(str, ","); *limit != NULL; limit++) {
-		value = strtoull(*limit, &pos, 10);
+		if (str_parse_ullong(*limit, &value, &pos) < 0) {
+			ret = FALSE;
+			continue;
+		}
 		if (pos[0] != '\0' && pos[1] == '\0') {
 			switch (pos[0]) {
 			case 'C':
--- a/src/plugins/quota/quota-util.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/plugins/quota/quota-util.c	Sat Aug 29 14:42:49 2015 +0300
@@ -145,8 +145,7 @@
 			const char *full_rule_def,
 			bool relative_rule, const char **error_r)
 {
-	const char **args, *key, *value, *error;
-	char *p;
+	const char **args, *key, *value, *error, *p;
 	uint64_t multiply;
 	int64_t *limit;
 
@@ -179,13 +178,25 @@
 		if (strcmp(key, "storage") == 0) {
 			multiply = 1024;
 			limit = &rule->bytes_limit;
-			*limit = strtoll(value, &p, 10);
+			if (str_parse_int64(value, limit, &p) < 0) {
+				*error_r = p_strdup_printf(root_set->set->pool,
+						"Invalid storage limit: %s", value);
+				return -1;
+			}
 		} else if (strcmp(key, "bytes") == 0) {
 			limit = &rule->bytes_limit;
-			*limit = strtoll(value, &p, 10);
+			if (str_parse_int64(value, limit, &p) < 0) {
+				*error_r = p_strdup_printf(root_set->set->pool,
+						"Invalid bytes limit: %s", value);
+				return -1;
+			}
 		} else if (strcmp(key, "messages") == 0) {
 			limit = &rule->count_limit;
-			*limit = strtoll(value, &p, 10);
+			if (str_parse_int64(value, limit, &p) < 0) {
+				*error_r = p_strdup_printf(root_set->set->pool,
+						"Invalid bytes messages: %s", value);
+				return -1;
+			}
 		} else {
 			*error_r = p_strdup_printf(root_set->set->pool,
 					"Unknown rule limit name: %s", key);
@@ -348,15 +359,15 @@
 int quota_root_parse_grace(struct quota_root_settings *root_set,
 			   const char *value, const char **error_r)
 {
-	char *p;
+	const char *p;
 
 	if (value == NULL) {
 		/* default */
 		value = QUOTA_DEFAULT_GRACE;
 	}
 
-	root_set->grace_rule.bytes_limit = strtoll(value, &p, 10);
-
+	if (str_parse_int64(value, &root_set->grace_rule.bytes_limit, &p) < 0)
+		return -1;
 	if (quota_limit_parse(root_set, &root_set->grace_rule, p, 1,
 			      &root_set->grace_rule.bytes_limit, error_r) < 0)
 		return -1;
--- a/src/util/maildirlock.c	Sat Aug 29 14:31:51 2015 +0300
+++ b/src/util/maildirlock.c	Sat Aug 29 14:42:49 2015 +0300
@@ -87,7 +87,8 @@
 	if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0)
 		i_fatal("dup2() failed: %m");
 
-	timeout = strtoul(argv[2], NULL, 10);
+	if (str_to_uint(argv[2], &timeout) < 0)
+		i_fatal("Invalid timeout value: %s", argv[2]);
 	if (maildir_lock(argv[1], timeout, &dotlock) <= 0)
 		return 1;