From a45431fa71165d56a6775099fad1c8806c593b0a Mon Sep 17 00:00:00 2001 From: Jeremy Harris Date: Sun, 21 May 2017 14:09:43 +0100 Subject: [PATCH] Increase size of variables for check_spool_space and check_log_space --- doc/doc-txt/ChangeLog | 5 ++ src/src/functions.h | 2 +- src/src/globals.c | 4 +- src/src/globals.h | 4 +- src/src/readconf.c | 114 +++++++++++++++++------------------ src/src/receive.c | 11 ++-- test/confs/0180 | 2 +- test/paniclog/0415 | 2 +- test/scripts/0000-Basic/0415 | 4 +- test/stderr/0415 | 2 +- test/stdout/0415 | 1 + 11 files changed, 79 insertions(+), 72 deletions(-) diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 70a496259..240781223 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -146,6 +146,11 @@ JH/31 Fix a bad use of a copy function, which could be used to pointlessly copy a string over itself. The library routine is documented as not supporting overlapping copies, and on MacOS it actually raised a SIGABRT. +JH/32 For main options check_spool_space and check_inode_space, where the + platform supports 64b integers, support more than the previous 2^31 kB + (i.e. more than 2 TB). Accept E, P and T multipliers in addition to + the previous G, M, k. + Exim version 4.91 ----------------- diff --git a/src/src/functions.h b/src/src/functions.h index f37c10733..38df27aea 100644 --- a/src/src/functions.h +++ b/src/src/functions.h @@ -376,7 +376,7 @@ extern void receive_bomb_out(uschar *, uschar *); extern BOOL receive_check_fs(int); extern BOOL receive_check_set_sender(uschar *); extern BOOL receive_msg(BOOL); -extern int receive_statvfs(BOOL, int *); +extern int_eximarith_t receive_statvfs(BOOL, int *); extern void receive_swallow_smtp(void); #ifdef WITH_CONTENT_SCAN extern int regex(const uschar **); diff --git a/src/src/globals.c b/src/src/globals.c index f8a4c3c0d..8dd8191ef 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -704,9 +704,9 @@ int callout_cache_negative_expire = 2*60*60; uschar *callout_random_local_part = US"$primary_hostname-$tod_epoch-testing"; uschar *check_dns_names_pattern= US"(?i)^(?>(?(1)\\.|())[^\\W](?>[a-z0-9/_-]*[^\\W])?)+(\\.?)$"; int check_log_inodes = 100; -int check_log_space = 10*1024; /* 10K Kbyte == 10MB */ +int_eximarith_t check_log_space = 10*1024; /* 10K Kbyte == 10MB */ int check_spool_inodes = 100; -int check_spool_space = 10*1024; /* 10K Kbyte == 10MB */ +int_eximarith_t check_spool_space = 10*1024; /* 10K Kbyte == 10MB */ uschar *chunking_advertise_hosts = US"*"; unsigned chunking_datasize = 0; diff --git a/src/src/globals.h b/src/src/globals.h index d337d3b75..465266e1a 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -382,10 +382,10 @@ extern int callout_cache_negative_expire; /* Time for negative callout cache extern uschar *callout_random_local_part; /* Local part to be used to check if server called will accept any local part */ extern uschar *check_dns_names_pattern;/* Regex for syntax check */ extern int check_log_inodes; /* Minimum for message acceptance */ -extern int check_log_space; /* Minimum for message acceptance */ +extern int_eximarith_t check_log_space; /* Minimum for message acceptance */ extern BOOL check_rfc2047_length; /* Check RFC 2047 encoded string length */ extern int check_spool_inodes; /* Minimum for message acceptance */ -extern int check_spool_space; /* Minimum for message acceptance */ +extern int_eximarith_t check_spool_space; /* Minimum for message acceptance */ extern uschar *chunking_advertise_hosts; /* RFC 3030 CHUNKING */ extern unsigned chunking_datasize; extern unsigned chunking_data_left; diff --git a/src/src/readconf.c b/src/src/readconf.c index a49d6c285..9b3eef367 100644 --- a/src/src/readconf.c +++ b/src/src/readconf.c @@ -2141,80 +2141,77 @@ switch (type) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s", inttype, name); - if (errno != ERANGE) - if (tolower(*endptr) == 'k') - { - if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) errno = ERANGE; - else lvalue *= 1024; - endptr++; - } - else if (tolower(*endptr) == 'm') - { - if (lvalue > INT_MAX/(1024*1024) || lvalue < INT_MIN/(1024*1024)) - errno = ERANGE; - else lvalue *= 1024*1024; - endptr++; - } - else if (tolower(*endptr) == 'g') - { - if (lvalue > INT_MAX/(1024*1024*1024) || lvalue < INT_MIN/(1024*1024*1024)) - errno = ERANGE; - else lvalue *= 1024*1024*1024; - endptr++; - } + if (errno != ERANGE && *endptr) + { + uschar * mp = US"GgMmKk\0"; /* YyZzEePpTtGgMmKk */ + + if ((mp = Ustrchr(mp, *endptr))) + { + endptr++; + do + { + if (lvalue > INT_MAX/1024 || lvalue < INT_MIN/1024) + { + errno = ERANGE; + break; + } + lvalue *= 1024; + } + while (*(mp += 2)); + } + } if (errno == ERANGE || lvalue > INT_MAX || lvalue < INT_MIN) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "absolute value of integer \"%s\" is too large (overflow)", s); while (isspace(*endptr)) endptr++; - if (*endptr != 0) + if (*endptr) extra_chars_error(endptr, inttype, US"integer value for ", name); value = (int)lvalue; } - if (data_block == NULL) - *((int *)(ol->value)) = value; + if (data_block) + *(int *)(US data_block + (long int)ol->value) = value; else - *((int *)(US data_block + (long int)(ol->value))) = value; + *(int *)ol->value = value; break; - /* Integer held in K: again, allow octal and hex formats, and suffixes K, M - and G. */ - /*XXX consider moving to int_eximarith_t (but mind the overflow test 0415) */ + /* Integer held in K: again, allow octal and hex formats, and suffixes K, M, + G and T. */ case opt_Kint: { uschar *endptr; errno = 0; - value = strtol(CS s, CSS &endptr, intbase); + int_eximarith_t lvalue = strtol(CS s, CSS &endptr, intbase); if (endptr == s) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "%sinteger expected for %s", inttype, name); - if (errno != ERANGE) - if (tolower(*endptr) == 'g') - { - if (value > INT_MAX/(1024*1024) || value < INT_MIN/(1024*1024)) - errno = ERANGE; - else - value *= 1024*1024; - endptr++; - } - else if (tolower(*endptr) == 'm') - { - if (value > INT_MAX/1024 || value < INT_MIN/1024) - errno = ERANGE; - else - value *= 1024; - endptr++; - } - else if (tolower(*endptr) == 'k') - endptr++; + if (errno != ERANGE && *endptr) + { + uschar * mp = US"EePpTtGgMmKk\0"; /* YyZzEePpTtGgMmKk */ + + if ((mp = Ustrchr(mp, *endptr))) + { + endptr++; + do + { + if (lvalue > EXIM_ARITH_MAX/1024 || lvalue < EXIM_ARITH_MIN/1024) + { + errno = ERANGE; + break; + } + lvalue *= 1024; + } + while (*(mp += 2)); + } else - value = (value + 512)/1024; + lvalue = (lvalue + 512)/1024; + } if (errno == ERANGE) log_write(0, LOG_PANIC_DIE|LOG_CONFIG_IN, "absolute value of integer \"%s\" is too large (overflow)", s); @@ -2222,13 +2219,13 @@ switch (type) while (isspace(*endptr)) endptr++; if (*endptr != 0) extra_chars_error(endptr, inttype, US"integer value for ", name); - } - if (data_block == NULL) - *((int *)(ol->value)) = value; - else - *((int *)(US data_block + (long int)(ol->value))) = value; - break; + if (data_block) + *(int_eximarith_t *)(US data_block + (long int)ol->value) = lvalue; + else + *(int_eximarith_t *)ol->value = lvalue; + break; + } /* Fixed-point number: held to 3 decimal places. */ @@ -2485,11 +2482,12 @@ switch(ol->type & opt_mask) case opt_Kint: { - int x = *((int *)value); + int_eximarith_t x = *((int_eximarith_t *)value); if (!no_labels) printf("%s = ", name); if (x == 0) printf("0\n"); - else if ((x & 1023) == 0) printf("%dM\n", x >> 10); - else printf("%dK\n", x); + else if ((x & ((1<<20)-1)) == 0) printf(PR_EXIM_ARITH "G\n", x >> 20); + else if ((x & ((1<<10)-1)) == 0) printf(PR_EXIM_ARITH "M\n", x >> 10); + else printf(PR_EXIM_ARITH "K\n", x); } break; diff --git a/src/src/receive.c b/src/src/receive.c index cd7867d04..ab27cc373 100644 --- a/src/src/receive.c +++ b/src/src/receive.c @@ -144,7 +144,7 @@ Returns: available on-root space, in kilobytes All values are -1 if the STATFS functions are not available. */ -int +int_eximarith_t receive_statvfs(BOOL isspool, int *inodeptr) { #ifdef HAVE_STATFS @@ -223,7 +223,7 @@ if (STATVFS(CS path, &statbuf) != 0) /* Disks are getting huge. Take care with computing the size in kilobytes. */ -return (int)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0); +return (int_eximarith_t)(((double)statbuf.F_BAVAIL * (double)statbuf.F_FRSIZE)/1024.0); #else /* Unable to find partition sizes in this environment. */ @@ -258,7 +258,8 @@ Returns: FALSE if there isn't enough space, or if the information cannot BOOL receive_check_fs(int msg_size) { -int space, inodes; +int_eximarith_t space; +int inodes; if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0) { @@ -266,7 +267,7 @@ if (check_spool_space > 0 || msg_size > 0 || check_spool_inodes > 0) DEBUG(D_receive) debug_printf("spool directory space = %dK inodes = %d " - "check_space = %dK inodes = %d msg_size = %d\n", + "check_space = " PR_EXIM_ARITH "K inodes = %d msg_size = %d\n", space, inodes, check_spool_space, check_spool_inodes, msg_size); if ((space >= 0 && space < check_spool_space) || @@ -284,7 +285,7 @@ if (check_log_space > 0 || check_log_inodes > 0) DEBUG(D_receive) debug_printf("log directory space = %dK inodes = %d " - "check_space = %dK inodes = %d\n", + "check_space = " PR_EXIM_ARITH "K inodes = %d\n", space, inodes, check_log_space, check_log_inodes); if ((space >= 0 && space < check_log_space) || diff --git a/test/confs/0180 b/test/confs/0180 index c4a0bd5af..e90d54517 100644 --- a/test/confs/0180 +++ b/test/confs/0180 @@ -1,7 +1,7 @@ # Exim test configuration 0180 # Require immense amount of disk space, expecting to fail. Can unfortunately work on big filesystems. -CSS=check_spool_space=400G +CSS=check_spool_space=1024T .include DIR/aux-var/std_conf_prefix diff --git a/test/paniclog/0415 b/test/paniclog/0415 index 2ed26d3f3..e0fbdedf3 100644 --- a/test/paniclog/0415 +++ b/test/paniclog/0415 @@ -1,5 +1,5 @@ 1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config: - absolute value of integer "4000000M" is too large (overflow) + absolute value of integer "4000E" is too large (overflow) 1999-03-02 09:44:33 Exim configuration error in line 15 of TESTSUITE/test-config: extra characters follow integer value for check_spool_space 1999-03-02 09:44:33 Exim configuration error in line 16 of TESTSUITE/test-config: diff --git a/test/scripts/0000-Basic/0415 b/test/scripts/0000-Basic/0415 index 29628b87a..043258fc0 100644 --- a/test/scripts/0000-Basic/0415 +++ b/test/scripts/0000-Basic/0415 @@ -1,6 +1,8 @@ # overflow in integer options 1 -exim -DARG1=4000000M -bP check_spool_space +exim -DARG1=4000E -bP check_spool_space +**** +exim -DARG1=4000G -bP check_spool_space **** 1 exim -DARG1=40MK -bP check_spool_space diff --git a/test/stderr/0415 b/test/stderr/0415 index f2c8612e8..55cc46fd1 100644 --- a/test/stderr/0415 +++ b/test/stderr/0415 @@ -1,6 +1,6 @@ LOG: PANIC DIE Exim configuration error in line 15 of TESTSUITE/test-config: - absolute value of integer "4000000M" is too large (overflow) + absolute value of integer "4000E" is too large (overflow) LOG: PANIC DIE Exim configuration error in line 15 of TESTSUITE/test-config: extra characters follow integer value for check_spool_space diff --git a/test/stdout/0415 b/test/stdout/0415 index f1183c838..0dfbae865 100644 --- a/test/stdout/0415 +++ b/test/stdout/0415 @@ -1,3 +1,4 @@ +check_spool_space = 4096000G finduser_retries = 0 finduser_retries = 999999999 finduser_retries = 1023998976 -- 2.30.2