diff options
-rw-r--r-- | doc/doc-txt/ChangeLog | 3 | ||||
-rw-r--r-- | src/src/macros.h | 15 | ||||
-rw-r--r-- | src/src/smtp_in.c | 27 |
3 files changed, 16 insertions, 29 deletions
diff --git a/doc/doc-txt/ChangeLog b/doc/doc-txt/ChangeLog index 162d6c5f6..201d9616d 100644 --- a/doc/doc-txt/ChangeLog +++ b/doc/doc-txt/ChangeLog @@ -98,6 +98,9 @@ PP/27 Bugzilla 1047: change the default for system_filter_user to be the Exim PP/28 Add WHITELIST_D_MACROS option to let some macros be overriden by the Exim run-time user without dropping privileges. +DW/29 Remove use of va_copy() which breaks pre-C99 systems. Duplicate the + result string, instead of calling string_vformat() twice with the same + arguments. Exim version 4.72 diff --git a/src/src/macros.h b/src/src/macros.h index ed90b2535..09bc601b9 100644 --- a/src/src/macros.h +++ b/src/src/macros.h @@ -844,19 +844,4 @@ explicit port number. */ enum { FILTER_UNSET, FILTER_FORWARD, FILTER_EXIM, FILTER_SIEVE }; -/* C99 defines va_copy() for copying a varargs ap so that it can be reused, -since on some platforms multiple iterations of va_start()/va_end() are not -supported. But va_copy() is itself not so portable. Hack around it. -See portability notes at: http://unixpapa.com/incnote/variadic.html */ - -#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L -/* va_copy exists for us or the system is broken and we need OS hacks */ -#elif defined(va_copy) -/* trust it; hope that va_copy is always a macro when defined */ -#elif !defined(va_copy) && defined(__va_copy) -#define va_copy(dest, src) __va_copy(dest, src) -#else -#define va_copy(dest, src) do { memcpy(dest, src, sizeof(va_list) } while (0) -#endif - /* End of macros.h */ diff --git a/src/src/smtp_in.c b/src/src/smtp_in.c index 9d10961c5..0fcedc821 100644 --- a/src/src/smtp_in.c +++ b/src/src/smtp_in.c @@ -387,29 +387,28 @@ va_end(ap); /* This is split off so that verify.c:respond_printf() can, in effect, call smtp_printf(), bearing in mind that in C a vararg function can't directly -call another vararg function, only a function which accepts a va_list. - -Note also that repeated calls to va_start()/va_end() pairs is claimed to be -non-portable; meanwhile, va_copy() is also non-portable in that it's C99, so -we end up needing OS support to define it for us. */ +call another vararg function, only a function which accepts a va_list. */ void smtp_vprintf(char *format, va_list ap) { -va_list ap_d; +BOOL yield; + +yield = string_vformat(big_buffer, big_buffer_size, format, ap); DEBUG(D_receive) { - uschar *cr, *end; - va_copy(ap_d, ap); - (void) string_vformat(big_buffer, big_buffer_size, format, ap_d); - end = big_buffer + Ustrlen(big_buffer); - while ((cr = Ustrchr(big_buffer, '\r')) != NULL) /* lose CRs */ - memmove(cr, cr + 1, (end--) - cr); - debug_printf("SMTP>> %s", big_buffer); + void *reset_point = store_get(0); + uschar *msg_copy, *cr, *end; + msg_copy = string_copy(big_buffer); + end = msg_copy + Ustrlen(msg_copy); + while ((cr = Ustrchr(msg_copy, '\r')) != NULL) /* lose CRs */ + memmove(cr, cr + 1, (end--) - cr); + debug_printf("SMTP>> %s", msg_copy); + store_reset(reset_point); } -if (!string_vformat(big_buffer, big_buffer_size, format, ap)) +if (!yield) { log_write(0, LOG_MAIN|LOG_PANIC, "string too large in smtp_printf()"); smtp_closedown(US"Unexpected error"); |