X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=src%2Fsrc%2Fstring.c;h=db54a094b789a90e2f1d721c8b06ebbe426c8c53;hb=ae20c80970d513823f3d36e73ec9657bf4b0e197;hp=e169a9f057076ff42995949f7b87f76ee2f9eff6;hpb=93a6fce2ebf117f490d7ee11f066f75280d32386;p=user%2Fhenk%2Fcode%2Fexim.git diff --git a/src/src/string.c b/src/src/string.c index e169a9f05..db54a094b 100644 --- a/src/src/string.c +++ b/src/src/string.c @@ -2,7 +2,7 @@ * Exim - an Internet mail transport agent * *************************************************/ -/* Copyright (c) University of Cambridge 1995 - 2014 */ +/* Copyright (c) University of Cambridge 1995 - 2016 */ /* See the file NOTICE for conditions of use and distribution. */ /* Miscellaneous string-handling functions. Some are not required for @@ -717,8 +717,9 @@ uschar buffer[STRING_SPRINTF_BUFFER_SIZE]; va_start(ap, format); if (!string_vformat(buffer, sizeof(buffer), format, ap)) log_write(0, LOG_MAIN|LOG_PANIC_DIE, - "string_sprintf expansion was longer than " SIZE_T_FMT " (%s)", - sizeof(buffer), format); + "string_sprintf expansion was longer than " SIZE_T_FMT + "; format string was (%s)\nexpansion started '%.32s'", + sizeof(buffer), format, buffer); va_end(ap); return string_copy(buffer); } @@ -912,7 +913,7 @@ sep_is_special = iscntrl(sep); if (buffer != NULL) { - register int p = 0; + int p = 0; for (; *s != 0; s++) { if (*s == sep && (*(++s) != sep || sep_is_special)) break; @@ -969,7 +970,7 @@ return buffer; #ifndef COMPILE_UTILITY /************************************************ -* Add element to seperated list * +* Add element to separated list * ************************************************/ /* This function is used to build a list, returning an allocated null-terminated growable string. The @@ -1085,7 +1086,9 @@ Returns: pointer to the start of the string, changed if copied for expansion. Note that a NUL is not added, though space is left for one. This is because string_cat() is often called multiple times to build up a string - there's no point adding the NUL till the end. + */ +/* coverity[+alloc] */ uschar * string_cat(uschar *string, int *size, int *ptr, const uschar *s, int count) @@ -1131,8 +1134,14 @@ if (p + count >= *size) /* Because we always specify the exact number of characters to copy, we can use memcpy(), which is likely to be more efficient than strncopy() because the -latter has to check for zero bytes. */ +latter has to check for zero bytes. + +The Coverity annotation deals with the lack of correlated variable tracking; +common use is a null string and zero size and pointer, on first use for a +string being built. The "if" above then allocates, but Coverity assume that +the "if" might not happen and whines for a null-deref done by the memcpy(). */ +/* coverity[deref_parm_field_in_call] */ memcpy(string + p, s, count); *ptr = p + count; return string; @@ -1517,6 +1526,7 @@ specified messages. If it does, the message just gets truncated, and there doesn't seem much we can do about that. */ (void)string_vformat(buffer+15, sizeof(buffer) - 15, format, ap); +va_end(ap); return (eno == EACCES)? string_sprintf("%s: %s (euid=%ld egid=%ld)", buffer, strerror(eno), @@ -1547,14 +1557,35 @@ static uschar * string_get_localpart(address_item *addr, uschar *yield, int *sizeptr, int *ptrptr) { -if (testflag(addr, af_include_affixes) && addr->prefix != NULL) - yield = string_cat(yield, sizeptr, ptrptr, addr->prefix, - Ustrlen(addr->prefix)); -yield = string_cat(yield, sizeptr, ptrptr, addr->local_part, - Ustrlen(addr->local_part)); -if (testflag(addr, af_include_affixes) && addr->suffix != NULL) - yield = string_cat(yield, sizeptr, ptrptr, addr->suffix, - Ustrlen(addr->suffix)); +uschar * s; + +s = addr->prefix; +if (testflag(addr, af_include_affixes) && s) + { +#ifdef SUPPORT_I18N + if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif + yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s)); + } + +s = addr->local_part; +#ifdef SUPPORT_I18N +if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif +yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s)); + +s = addr->suffix; +if (testflag(addr, af_include_affixes) && s) + { +#ifdef SUPPORT_I18N + if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif + yield = string_cat(yield, sizeptr, ptrptr, s, Ustrlen(s)); + } + return yield; } @@ -1615,10 +1646,15 @@ else { if (addr->local_part != NULL) { + const uschar * s; yield = string_get_localpart(addr, yield, &size, &ptr); yield = string_cat(yield, &size, &ptr, US"@", 1); - yield = string_cat(yield, &size, &ptr, addr->domain, - Ustrlen(addr->domain) ); + s = addr->domain; +#ifdef SUPPORT_I18N + if (testflag(addr, af_utf8_downcvt)) + s = string_localpart_utf8_to_alabel(s, NULL); +#endif + yield = string_cat(yield, &size, &ptr, s, Ustrlen(s) ); } else { @@ -1680,6 +1716,17 @@ return yield; #endif /* COMPILE_UTILITY */ +#ifndef COMPILE_UTILITY +/* qsort(3), currently used to sort the environment variables +for -bP environment output, needs a function to compare two pointers to string +pointers. Here it is. */ + +int +string_compare_by_pointer(const void *a, const void *b) +{ +return Ustrcmp(* CUSS a, * CUSS b); +} +#endif /* COMPILE_UTILITY */