51b12c5e527921721213a26745483893db2c0f5a
[exim.git] / src / src / string.c
1 /*************************************************
2 *     Exim - an Internet mail transport agent    *
3 *************************************************/
4
5 /* Copyright (c) The Exim Maintainers 2020 - 2022 */
6 /* Copyright (c) University of Cambridge 1995 - 2018 */
7 /* See the file NOTICE for conditions of use and distribution. */
8 /* SPDX-License-Identifier: GPL-2.0-or-later */
9
10 /* Miscellaneous string-handling functions. Some are not required for
11 utilities and tests, and are cut out by the COMPILE_UTILITY macro. */
12
13
14 #include "exim.h"
15 #include <assert.h>
16
17
18 #ifndef COMPILE_UTILITY
19 /*************************************************
20 *            Test for IP address                 *
21 *************************************************/
22
23 /* This used just to be a regular expression, but with IPv6 things are a bit
24 more complicated. If the address contains a colon, it is assumed to be a v6
25 address (assuming HAVE_IPV6 is set). If a mask is permitted and one is present,
26 and maskptr is not NULL, its offset is placed there.
27
28 Arguments:
29   s         a string
30   maskptr   NULL if no mask is permitted to follow
31             otherwise, points to an int where the offset of '/' is placed
32             if there is no / followed by trailing digits, *maskptr is set 0
33   errp      NULL if no diagnostic information is required, and if the netmask
34             length should not be checked. Otherwise it is set pointing to a short
35             descriptive text.
36
37 Returns:    0 if the string is not a textual representation of an IP address
38             4 if it is an IPv4 address
39             6 if it is an IPv6 address
40
41 The legacy string_is_ip_address() function follows below.
42 */
43 int
44 string_is_ip_addressX(const uschar *ip_addr, int *maskptr, const uschar **errp) {
45   struct addrinfo hints;
46   struct addrinfo *res;
47
48   uschar *slash, *percent;
49
50   uschar *endp = 0;
51   long int mask = 0;
52   const uschar *addr = 0;
53
54   /* If there is a slash, but we didn't request a (optional) netmask,
55   we return failure, as we do if the mask isn't a pure numerical value,
56   or if it is negative. The actual length is checked later, once we know
57   the address family. */
58   if (slash = Ustrchr(ip_addr, '/'))
59   {
60     if (!maskptr)
61     {
62       if (errp) *errp = "netmask found, but not requested";
63       return 0;
64     }
65
66     uschar *rest;
67     mask = Ustrtol(slash+1, &rest, 10);
68     if (*rest || mask < 0)
69     {
70       if (errp) *errp = "netmask not numeric or <0";
71       return 0;
72     }
73
74     *maskptr = slash - ip_addr;     /* offset of the slash */
75     endp = slash;
76   } else if (maskptr) *maskptr = 0; /* no slash found */
77
78   /* The interface-ID suffix (%<id>) is optional (for IPv6). If it
79   exists, we check it syntactically. Later, if we know the address
80   family is IPv4, we might reject it.
81   The interface-ID is mutually exclusive with the netmask, to the
82   best of my knowledge. */
83   if (percent = Ustrchr(ip_addr, '%'))
84   {
85     if (slash)
86     {
87       if (errp) *errp = "interface-ID and netmask are mutually exclusive";
88       return 0;
89     }
90     for (uschar *p = percent+1; *p; p++)
91         if (!isalnum(*p) && !ispunct(*p))
92         {
93           if (errp) *errp = "interface-ID must match [[:alnum:][:punct:]]";
94           return 0;
95         }
96     endp = percent;
97   }
98
99   /* inet_pton() can't parse netmasks and interface IDs, so work on a shortened copy
100   allocated on the current stack */
101   if (endp) {
102     ptrdiff_t l = endp - ip_addr;
103     if (l > 255)
104     {
105       if (errp) *errp = "rudiculous long ip address string";
106       return 0;
107     }
108     addr = string_copyn(ip_addr, l);
109   } else addr = ip_addr;
110
111   int af;
112   union { /* we do not need this, but inet_pton() needs a place for storage */
113     struct in_addr sa4;
114     struct in6_addr sa6;
115   } sa;
116
117   af = Ustrchr(addr, ':') ? AF_INET6 : AF_INET;
118   if (!inet_pton(af, addr, &sa))
119   {
120     if (errp) *errp = af == AF_INET6 ? "IP address string not parsable as IPv6"
121                                      : "IP address string not parsable IPv4";
122     return 0;
123   }
124   /* we do not check the values of the mask here, as
125   this is done on the callers side (but I don't understand why), so
126   actually I'd like to do it here, but it breaks at least 0002 */
127   switch (af)
128   {
129     case AF_INET6:
130         if (errp && mask > 128)
131         {
132           *errp = "IPv6 netmask value must not be >128";
133           return 0;
134         }
135         return 6;
136     case AF_INET:
137         if (percent)
138         {
139           if (errp) *errp = "IPv4 address string must not have an interface-ID";
140           return 0;
141         }
142         if (errp && mask > 32) {
143           *errp = "IPv4 netmask value must not be >32";
144           return 0;
145         }
146         return 4;
147     default:
148         if (errp) *errp = "unknown address family (should not happen)";
149         return 0;
150  }
151 }
152
153 int
154 string_is_ip_address(const uschar *ip_addr, int *maskptr) {
155   return string_is_ip_addressX(ip_addr, maskptr, 0);
156 }
157
158 #endif  /* COMPILE_UTILITY */
159
160
161 /*************************************************
162 *              Format message size               *
163 *************************************************/
164
165 /* Convert a message size in bytes to printing form, rounding
166 according to the magnitude of the number. A value of zero causes
167 a string of spaces to be returned.
168
169 Arguments:
170   size        the message size in bytes
171   buffer      where to put the answer
172
173 Returns:      pointer to the buffer
174               a string of exactly 5 characters is normally returned
175 */
176
177 uschar *
178 string_format_size(int size, uschar *buffer)
179 {
180 if (size == 0) Ustrcpy(buffer, US"     ");
181 else if (size < 1024) sprintf(CS buffer, "%5d", size);
182 else if (size < 10*1024)
183   sprintf(CS buffer, "%4.1fK", (double)size / 1024.0);
184 else if (size < 1024*1024)
185   sprintf(CS buffer, "%4dK", (size + 512)/1024);
186 else if (size < 10*1024*1024)
187   sprintf(CS buffer, "%4.1fM", (double)size / (1024.0 * 1024.0));
188 else
189   sprintf(CS buffer, "%4dM", (size + 512 * 1024)/(1024*1024));
190 return buffer;
191 }
192
193
194
195 #ifndef COMPILE_UTILITY
196 /*************************************************
197 *       Convert a number to base 62 format       *
198 *************************************************/
199
200 /* Convert a long integer into an ASCII base 62 string. For Cygwin the value of
201 BASE_62 is actually 36. Always return exactly 6 characters plus a NUL, in a
202 static area.  This is enough for a 32b input, for 62  (for 64b we would want 11+nul);
203 but with 36 we lose half the input range of a 32b input.
204
205 Argument: a long integer
206 Returns:  pointer to base 62 string
207 */
208
209 uschar *
210 string_base62_32(unsigned long int value)
211 {
212 static uschar yield[7];
213 uschar * p = yield + sizeof(yield) - 1;
214 *p = 0;
215 while (p > yield)
216   {
217   *--p = base62_chars[value % BASE_62];
218   value /= BASE_62;
219   }
220 return yield;
221 }
222
223 uschar *
224 string_base62_64(unsigned long int value)
225 {
226 static uschar yield[12];
227 uschar * p = yield + sizeof(yield) - 1;
228 *p = '\0';
229 while (p > yield)
230   if (value)
231     {
232     *--p = base62_chars[value % BASE_62];
233     value /= BASE_62;
234     }
235   else
236     *--p = '0';
237 return yield;
238 }
239 #endif  /* COMPILE_UTILITY */
240
241
242
243 /*************************************************
244 *          Interpret escape sequence             *
245 *************************************************/
246
247 /* This function is called from several places where escape sequences are to be
248 interpreted in strings.
249
250 Arguments:
251   pp       points a pointer to the initiating "\" in the string;
252            the pointer gets updated to point to the final character
253            If the backslash is the last character in the string, it
254            is not interpreted.
255 Returns:   the value of the character escape
256 */
257
258 int
259 string_interpret_escape(const uschar **pp)
260 {
261 #ifdef COMPILE_UTILITY
262 const uschar *hex_digits= CUS"0123456789abcdef";
263 #endif
264 int ch;
265 const uschar *p = *pp;
266 ch = *(++p);
267 if (ch == '\0') return **pp;
268 if (isdigit(ch) && ch != '8' && ch != '9')
269   {
270   ch -= '0';
271   if (isdigit(p[1]) && p[1] != '8' && p[1] != '9')
272     {
273     ch = ch * 8 + *(++p) - '0';
274     if (isdigit(p[1]) && p[1] != '8' && p[1] != '9')
275       ch = ch * 8 + *(++p) - '0';
276     }
277   }
278 else switch(ch)
279   {
280   case 'b':  ch = '\b'; break;
281   case 'f':  ch = '\f'; break;
282   case 'n':  ch = '\n'; break;
283   case 'r':  ch = '\r'; break;
284   case 't':  ch = '\t'; break;
285   case 'v':  ch = '\v'; break;
286   case 'x':
287   ch = 0;
288   if (isxdigit(p[1]))
289     {
290     ch = ch * 16 +
291       Ustrchr(hex_digits, tolower(*(++p))) - hex_digits;
292     if (isxdigit(p[1])) ch = ch * 16 +
293       Ustrchr(hex_digits, tolower(*(++p))) - hex_digits;
294     }
295   break;
296   }
297 *pp = p;
298 return ch;
299 }
300
301
302
303 #ifndef COMPILE_UTILITY
304 /*************************************************
305 *          Ensure string is printable            *
306 *************************************************/
307
308 /* This function is called for critical strings. It checks for any
309 non-printing characters, and if any are found, it makes a new copy
310 of the string with suitable escape sequences. It is most often called by the
311 macro string_printing(), which sets flags to 0.
312
313 Arguments:
314   s             the input string
315   flags         Bit 0: convert tabs.  Bit 1: convert spaces.
316
317 Returns:        string with non-printers encoded as printing sequences
318 */
319
320 const uschar *
321 string_printing2(const uschar *s, int flags)
322 {
323 int nonprintcount = 0;
324 int length = 0;
325 const uschar *t = s;
326 uschar *ss, *tt;
327
328 while (*t)
329   {
330   int c = *t++;
331   if (  !mac_isprint(c)
332      || flags & SP_TAB && c == '\t'
333      || flags & SP_SPACE && c == ' '
334      ) nonprintcount++;
335   length++;
336   }
337
338 if (nonprintcount == 0) return s;
339
340 /* Get a new block of store guaranteed big enough to hold the
341 expanded string. */
342
343 tt = ss = store_get(length + nonprintcount * 3 + 1, s);
344
345 /* Copy everything, escaping non printers. */
346
347 for (t = s; *t; )
348   {
349   int c = *t;
350   if (  mac_isprint(c)
351      && (!(flags & SP_TAB) || c != '\t')
352      && (!(flags & SP_SPACE) || c != ' ')
353      )
354     *tt++ = *t++;
355   else
356     {
357     *tt++ = '\\';
358     switch (*t)
359       {
360       case '\n': *tt++ = 'n'; break;
361       case '\r': *tt++ = 'r'; break;
362       case '\b': *tt++ = 'b'; break;
363       case '\v': *tt++ = 'v'; break;
364       case '\f': *tt++ = 'f'; break;
365       case '\t': *tt++ = 't'; break;
366       default: sprintf(CS tt, "%03o", *t); tt += 3; break;
367       }
368     t++;
369     }
370   }
371 *tt = 0;
372 return ss;
373 }
374 #endif  /* COMPILE_UTILITY */
375
376 /*************************************************
377 *        Undo printing escapes in string         *
378 *************************************************/
379
380 /* This function is the reverse of string_printing2.  It searches for
381 backslash characters and if any are found, it makes a new copy of the
382 string with escape sequences parsed.  Otherwise it returns the original
383 string.
384
385 Arguments:
386   s             the input string
387
388 Returns:        string with printing escapes parsed back
389 */
390
391 uschar *
392 string_unprinting(uschar *s)
393 {
394 uschar *p, *q, *r, *ss;
395 int len, off;
396
397 p = Ustrchr(s, '\\');
398 if (!p) return s;
399
400 len = Ustrlen(s) + 1;
401 ss = store_get(len, s);
402
403 q = ss;
404 off = p - s;
405 if (off)
406   {
407   memcpy(q, s, off);
408   q += off;
409   }
410
411 while (*p)
412   {
413   if (*p == '\\')
414     {
415     *q++ = string_interpret_escape((const uschar **)&p);
416     p++;
417     }
418   else
419     {
420     r = Ustrchr(p, '\\');
421     if (!r)
422       {
423       off = Ustrlen(p);
424       memcpy(q, p, off);
425       p += off;
426       q += off;
427       break;
428       }
429     else
430       {
431       off = r - p;
432       memcpy(q, p, off);
433       q += off;
434       p = r;
435       }
436     }
437   }
438 *q = '\0';
439
440 return ss;
441 }
442
443
444
445
446 #if (defined(HAVE_LOCAL_SCAN) || defined(EXPAND_DLFUNC)) \
447         && !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
448 /*************************************************
449 *            Copy and save string                *
450 *************************************************/
451
452 /*
453 Argument: string to copy
454 Returns:  copy of string in new store with the same taint status
455 */
456
457 uschar *
458 string_copy_function(const uschar * s)
459 {
460 return string_copy_taint(s, s);
461 }
462
463 /* As above, but explicitly specifying the result taint status
464 */
465
466 uschar *
467 string_copy_taint_function(const uschar * s, const void * proto_mem)
468 {
469 return string_copy_taint(s, proto_mem);
470 }
471
472
473
474 /*************************************************
475 *       Copy and save string, given length       *
476 *************************************************/
477
478 /* It is assumed the data contains no zeros. A zero is added
479 onto the end.
480
481 Arguments:
482   s         string to copy
483   n         number of characters
484
485 Returns:    copy of string in new store
486 */
487
488 uschar *
489 string_copyn_function(const uschar * s, int n)
490 {
491 return string_copyn(s, n);
492 }
493 #endif
494
495
496 /*************************************************
497 *     Copy and save string in malloc'd store     *
498 *************************************************/
499
500 /* This function assumes that memcpy() is faster than strcpy().
501
502 Argument: string to copy
503 Returns:  copy of string in new store
504 */
505
506 uschar *
507 string_copy_malloc(const uschar * s)
508 {
509 int len = Ustrlen(s) + 1;
510 uschar * ss = store_malloc(len);
511 memcpy(ss, s, len);
512 return ss;
513 }
514
515
516
517 /*************************************************
518 *    Copy string if long, inserting newlines     *
519 *************************************************/
520
521 /* If the given string is longer than 75 characters, it is copied, and within
522 the copy, certain space characters are converted into newlines.
523
524 Argument:  pointer to the string
525 Returns:   pointer to the possibly altered string
526 */
527
528 uschar *
529 string_split_message(uschar * msg)
530 {
531 uschar *s, *ss;
532
533 if (!msg || Ustrlen(msg) <= 75) return msg;
534 s = ss = msg = string_copy(msg);
535
536 for (;;)
537   {
538   int i = 0;
539   while (i < 75 && *ss && *ss != '\n') ss++, i++;
540   if (!*ss) break;
541   if (*ss == '\n')
542     s = ++ss;
543   else
544     {
545     uschar * t = ss + 1;
546     uschar * tt = NULL;
547     while (--t > s + 35)
548       {
549       if (*t == ' ')
550         {
551         if (t[-1] == ':') { tt = t; break; }
552         if (!tt) tt = t;
553         }
554       }
555
556     if (!tt)          /* Can't split behind - try ahead */
557       {
558       t = ss + 1;
559       while (*t)
560         {
561         if (*t == ' ' || *t == '\n')
562           { tt = t; break; }
563         t++;
564         }
565       }
566
567     if (!tt) break;   /* Can't find anywhere to split */
568     *tt = '\n';
569     s = ss = tt+1;
570     }
571   }
572
573 return msg;
574 }
575
576
577
578 /*************************************************
579 *   Copy returned DNS domain name, de-escaping   *
580 *************************************************/
581
582 /* If a domain name contains top-bit characters, some resolvers return
583 the fully qualified name with those characters turned into escapes. The
584 convention is a backslash followed by _decimal_ digits. We convert these
585 back into the original binary values. This will be relevant when
586 allow_utf8_domains is set true and UTF-8 characters are used in domain
587 names. Backslash can also be used to escape other characters, though we
588 shouldn't come across them in domain names.
589
590 Argument:   the domain name string
591 Returns:    copy of string in new store, de-escaped
592 */
593
594 uschar *
595 string_copy_dnsdomain(uschar * s)
596 {
597 uschar * yield;
598 uschar * ss = yield = store_get(Ustrlen(s) + 1, GET_TAINTED);   /* always treat as tainted */
599
600 while (*s)
601   {
602   if (*s != '\\')
603     *ss++ = *s++;
604   else if (isdigit(s[1]))
605     {
606     *ss++ = (s[1] - '0')*100 + (s[2] - '0')*10 + s[3] - '0';
607     s += 4;
608     }
609   else if (*++s)
610     *ss++ = *s++;
611   }
612
613 *ss = 0;
614 return yield;
615 }
616
617
618 #ifndef COMPILE_UTILITY
619 /*************************************************
620 *     Copy space-terminated or quoted string     *
621 *************************************************/
622
623 /* This function copies from a string until its end, or until whitespace is
624 encountered, unless the string begins with a double quote, in which case the
625 terminating quote is sought, and escaping within the string is done. The length
626 of a de-quoted string can be no longer than the original, since escaping always
627 turns n characters into 1 character.
628
629 Argument:  pointer to the pointer to the first character, which gets updated
630 Returns:   the new string
631 */
632
633 uschar *
634 string_dequote(const uschar ** sptr)
635 {
636 const uschar * s = * sptr;
637 uschar * t, * yield;
638
639 /* First find the end of the string */
640
641 if (*s != '\"')
642   while (*s && !isspace(*s)) s++;
643 else
644   {
645   s++;
646   while (*s && *s != '\"')
647     {
648     if (*s == '\\') (void)string_interpret_escape(&s);
649     s++;
650     }
651   if (*s) s++;
652   }
653
654 /* Get enough store to copy into */
655
656 t = yield = store_get(s - *sptr + 1, *sptr);
657 s = *sptr;
658
659 /* Do the copy */
660
661 if (*s != '\"')
662   while (*s && !isspace(*s)) *t++ = *s++;
663 else
664   {
665   s++;
666   while (*s && *s != '\"')
667     {
668     *t++ = *s == '\\' ? string_interpret_escape(&s) : *s;
669     s++;
670     }
671   if (*s) s++;
672   }
673
674 /* Update the pointer and return the terminated copy */
675
676 *sptr = s;
677 *t = 0;
678 return yield;
679 }
680 #endif  /* COMPILE_UTILITY */
681
682
683
684 /*************************************************
685 *          Format a string and save it           *
686 *************************************************/
687
688 /* The formatting is done by string_vformat, which checks the length of
689 everything.  Taint is taken from the worst of the arguments.
690
691 Arguments:
692   format    a printf() format - deliberately char * rather than uschar *
693               because it will most usually be a literal string
694   func      caller, for debug
695   line      caller, for debug
696   ...       arguments for format
697
698 Returns:    pointer to fresh piece of store containing sprintf'ed string
699 */
700
701 uschar *
702 string_sprintf_trc(const char * format, const uschar * func, unsigned line, ...)
703 {
704 #ifdef COMPILE_UTILITY
705 uschar buffer[STRING_SPRINTF_BUFFER_SIZE];
706 gstring gs = { .size = STRING_SPRINTF_BUFFER_SIZE, .ptr = 0, .s = buffer };
707 gstring * g = &gs;
708 unsigned flags = 0;
709 #else
710 gstring * g = NULL;
711 unsigned flags = SVFMT_REBUFFER|SVFMT_EXTEND;
712 #endif
713
714 va_list ap;
715 va_start(ap, line);
716 g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
717         flags, format, ap);
718 va_end(ap);
719
720 if (!g)
721   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
722     "string_sprintf expansion was longer than %d; format string was (%s)\n"
723     " called from %s %d\n",
724     STRING_SPRINTF_BUFFER_SIZE, format, func, line);
725
726 #ifdef COMPILE_UTILITY
727 return string_copyn(g->s, g->ptr);
728 #else
729 gstring_release_unused(g);
730 return string_from_gstring(g);
731 #endif
732 }
733
734
735
736 /*************************************************
737 *         Case-independent strncmp() function    *
738 *************************************************/
739
740 /*
741 Arguments:
742   s         first string
743   t         second string
744   n         number of characters to compare
745
746 Returns:    < 0, = 0, or > 0, according to the comparison
747 */
748
749 int
750 strncmpic(const uschar * s, const uschar * t, int n)
751 {
752 while (n--)
753   {
754   int c = tolower(*s++) - tolower(*t++);
755   if (c) return c;
756   }
757 return 0;
758 }
759
760
761 /*************************************************
762 *         Case-independent strcmp() function     *
763 *************************************************/
764
765 /*
766 Arguments:
767   s         first string
768   t         second string
769
770 Returns:    < 0, = 0, or > 0, according to the comparison
771 */
772
773 int
774 strcmpic(const uschar * s, const uschar * t)
775 {
776 while (*s)
777   {
778   int c = tolower(*s++) - tolower(*t++);
779   if (c != 0) return c;
780   }
781 return *t;
782 }
783
784
785 /*************************************************
786 *         Case-independent strstr() function     *
787 *************************************************/
788
789 /* The third argument specifies whether whitespace is required
790 to follow the matched string.
791
792 Arguments:
793   s              string to search
794   t              substring to search for
795   space_follows  if TRUE, match only if whitespace follows
796
797 Returns:         pointer to substring in string, or NULL if not found
798 */
799
800 const uschar *
801 strstric_c(const uschar * s, const uschar * t, BOOL space_follows)
802 {
803 const uschar * p = t;
804 const uschar * yield = NULL;
805 int cl = tolower(*p);
806 int cu = toupper(*p);
807
808 while (*s)
809   {
810   if (*s == cl || *s == cu)
811     {
812     if (!yield) yield = s;
813     if (!*++p)
814       {
815       if (!space_follows || s[1] == ' ' || s[1] == '\n' ) return yield;
816       yield = NULL;
817       p = t;
818       }
819     cl = tolower(*p);
820     cu = toupper(*p);
821     s++;
822     }
823   else if (yield)
824     {
825     yield = NULL;
826     p = t;
827     cl = tolower(*p);
828     cu = toupper(*p);
829     }
830   else s++;
831   }
832 return NULL;
833 }
834
835 uschar *
836 strstric(uschar * s, uschar * t, BOOL space_follows)
837 {
838 return US strstric_c(s, t, space_follows);
839 }
840
841
842 #ifdef COMPILE_UTILITY
843 /* Dummy version for this function; it should never be called */
844 static void
845 gstring_grow(gstring * g, int count)
846 {
847 assert(FALSE);
848 }
849 #endif
850
851
852
853 #ifndef COMPILE_UTILITY
854 /*************************************************
855 *       Get next string from separated list      *
856 *************************************************/
857
858 /* Leading and trailing space is removed from each item. The separator in the
859 list is controlled by the int pointed to by the separator argument as follows:
860
861   If the value is > 0 it is used as the separator. This is typically used for
862   sublists such as slash-separated options. The value is always a printing
863   character.
864
865     (If the value is actually > UCHAR_MAX there is only one item in the list.
866     This is used for some cases when called via functions that sometimes
867     plough through lists, and sometimes are given single items.)
868
869   If the value is <= 0, the string is inspected for a leading <x, where x is an
870   ispunct() or an iscntrl() character. If found, x is used as the separator. If
871   not found:
872
873       (a) if separator == 0, ':' is used
874       (b) if separator <0, -separator is used
875
876   In all cases the value of the separator that is used is written back to the
877   int so that it is used on subsequent calls as we progress through the list.
878
879 A literal ispunct() separator can be represented in an item by doubling, but
880 there is no way to include an iscntrl() separator as part of the data.
881
882 Arguments:
883   listptr    points to a pointer to the current start of the list; the
884              pointer gets updated to point after the end of the next item
885   separator  a pointer to the separator character in an int (see above)
886   buffer     where to put a copy of the next string in the list; or
887                NULL if the next string is returned in new memory
888              Note that if the list is tainted then a provided buffer must be
889              also (else we trap, with a message referencing the callsite).
890              If we do the allocation, taint is handled there.
891   buflen     when buffer is not NULL, the size of buffer; otherwise ignored
892
893   func       caller, for debug
894   line       caller, for debug
895
896 Returns:     pointer to buffer, containing the next substring,
897              or NULL if no more substrings
898 */
899
900 uschar *
901 string_nextinlist_trc(const uschar ** listptr, int * separator, uschar * buffer,
902   int buflen, const uschar * func, int line)
903 {
904 int sep = *separator;
905 const uschar * s = *listptr;
906 BOOL sep_is_special;
907
908 if (!s) return NULL;
909
910 /* This allows for a fixed specified separator to be an iscntrl() character,
911 but at the time of implementation, this is never the case. However, it's best
912 to be conservative. */
913
914 while (isspace(*s) && *s != sep) s++;
915
916 /* A change of separator is permitted, so look for a leading '<' followed by an
917 allowed character. */
918
919 if (sep <= 0)
920   {
921   if (*s == '<' && (ispunct(s[1]) || iscntrl(s[1])))
922     {
923     sep = s[1];
924     if (*++s) ++s;
925     while (isspace(*s) && *s != sep) s++;
926     }
927   else
928     sep = sep ? -sep : ':';
929   *separator = sep;
930   }
931
932 /* An empty string has no list elements */
933
934 if (!*s) return NULL;
935
936 /* Note whether whether or not the separator is an iscntrl() character. */
937
938 sep_is_special = iscntrl(sep);
939
940 /* Handle the case when a buffer is provided. */
941 /*XXX need to also deal with qouted-requirements mismatch */
942
943 if (buffer)
944   {
945   int p = 0;
946   if (is_tainted(s) && !is_tainted(buffer))
947     die_tainted(US"string_nextinlist", func, line);
948   for (; *s; s++)
949     {
950     if (*s == sep && (*(++s) != sep || sep_is_special)) break;
951     if (p < buflen - 1) buffer[p++] = *s;
952     }
953   while (p > 0 && isspace(buffer[p-1])) p--;
954   buffer[p] = '\0';
955   }
956
957 /* Handle the case when a buffer is not provided. */
958
959 else
960   {
961   gstring * g = NULL;
962
963   /* We know that *s != 0 at this point. However, it might be pointing to a
964   separator, which could indicate an empty string, or (if an ispunct()
965   character) could be doubled to indicate a separator character as data at the
966   start of a string. Avoid getting working memory for an empty item. */
967
968   if (*s == sep)
969     if (*++s != sep || sep_is_special)
970       {
971       *listptr = s;
972       return string_copy(US"");
973       }
974
975   /* Not an empty string; the first character is guaranteed to be a data
976   character. */
977
978   for (;;)
979     {
980     const uschar * ss;
981     for (ss = s + 1; *ss && *ss != sep; ) ss++;
982     g = string_catn(g, s, ss-s);
983     s = ss;
984     if (!*s || *++s != sep || sep_is_special) break;
985     }
986
987   /* Trim trailing spaces from the returned string */
988
989   /* while (g->ptr > 0 && isspace(g->s[g->ptr-1])) g->ptr--; */
990   while (  g->ptr > 0 && isspace(g->s[g->ptr-1])
991         && (g->ptr == 1 || g->s[g->ptr-2] != '\\') )
992     g->ptr--;
993   buffer = string_from_gstring(g);
994   gstring_release_unused_trc(g, CCS func, line);
995   }
996
997 /* Update the current pointer and return the new string */
998
999 *listptr = s;
1000 return buffer;
1001 }
1002
1003
1004 static const uschar *
1005 Ustrnchr(const uschar * s, int c, unsigned * len)
1006 {
1007 unsigned siz = *len;
1008 while (siz)
1009   {
1010   if (!*s) return NULL;
1011   if (*s == c)
1012     {
1013     *len = siz;
1014     return s;
1015     }
1016   s++;
1017   siz--;
1018   }
1019 return NULL;
1020 }
1021
1022
1023 /************************************************
1024 *       Add element to separated list           *
1025 ************************************************/
1026 /* This function is used to build a list, returning an allocated null-terminated
1027 growable string. The given element has any embedded separator characters
1028 doubled.
1029
1030 Despite having the same growable-string interface as string_cat() the list is
1031 always returned null-terminated.
1032
1033 Arguments:
1034   list  expanding-string for the list that is being built, or NULL
1035         if this is a new list that has no contents yet
1036   sep   list separator character
1037   ele   new element to be appended to the list
1038
1039 Returns:  pointer to the start of the list, changed if copied for expansion.
1040 */
1041
1042 gstring *
1043 string_append_listele(gstring * list, uschar sep, const uschar * ele)
1044 {
1045 uschar * sp;
1046
1047 if (list && list->ptr)
1048   list = string_catn(list, &sep, 1);
1049
1050 while((sp = Ustrchr(ele, sep)))
1051   {
1052   list = string_catn(list, ele, sp-ele+1);
1053   list = string_catn(list, &sep, 1);
1054   ele = sp+1;
1055   }
1056 list = string_cat(list, ele);
1057 (void) string_from_gstring(list);
1058 return list;
1059 }
1060
1061
1062 gstring *
1063 string_append_listele_n(gstring * list, uschar sep, const uschar * ele,
1064  unsigned len)
1065 {
1066 const uschar * sp;
1067
1068 if (list && list->ptr)
1069   list = string_catn(list, &sep, 1);
1070
1071 while((sp = Ustrnchr(ele, sep, &len)))
1072   {
1073   list = string_catn(list, ele, sp-ele+1);
1074   list = string_catn(list, &sep, 1);
1075   ele = sp+1;
1076   len--;
1077   }
1078 list = string_catn(list, ele, len);
1079 (void) string_from_gstring(list);
1080 return list;
1081 }
1082
1083
1084
1085 /* A slightly-bogus listmaker utility; the separator is a string so
1086 can be multiple chars - there is no checking for the element content
1087 containing any of the separator. */
1088
1089 gstring *
1090 string_append2_listele_n(gstring * list, const uschar * sepstr,
1091  const uschar * ele, unsigned len)
1092 {
1093 if (list && list->ptr)
1094   list = string_cat(list, sepstr);
1095
1096 list = string_catn(list, ele, len);
1097 (void) string_from_gstring(list);
1098 return list;
1099 }
1100
1101
1102
1103 /************************************************/
1104 /* Add more space to a growable-string.  The caller should check
1105 first if growth is required.  The gstring struct is modified on
1106 return; specifically, the string-base-pointer may have been changed.
1107
1108 Arguments:
1109   g             the growable-string
1110   count         amount needed for g->ptr to increase by
1111 */
1112
1113 static void
1114 gstring_grow(gstring * g, int count)
1115 {
1116 int p = g->ptr;
1117 int oldsize = g->size;
1118
1119 /* Mostly, string_cat() is used to build small strings of a few hundred
1120 characters at most. There are times, however, when the strings are very much
1121 longer (for example, a lookup that returns a vast number of alias addresses).
1122 To try to keep things reasonable, we use increments whose size depends on the
1123 existing length of the string. */
1124
1125 unsigned inc = oldsize < 4096 ? 127 : 1023;
1126
1127 if (g->ptr < 0 || g->ptr > g->size || g->size >= INT_MAX/2)
1128   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1129     "internal error in gstring_grow (ptr %d size %d)", g->ptr, g->size);
1130
1131 if (count <= 0) return;
1132
1133 if (count >= INT_MAX/2 - g->ptr)
1134   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1135     "internal error in gstring_grow (ptr %d count %d)", g->ptr, count);
1136
1137 g->size = (p + count + inc + 1) & ~inc;         /* one for a NUL */
1138
1139 /* Try to extend an existing allocation. If the result of calling
1140 store_extend() is false, either there isn't room in the current memory block,
1141 or this string is not the top item on the dynamic store stack. We then have
1142 to get a new chunk of store and copy the old string. When building large
1143 strings, it is helpful to call store_release() on the old string, to release
1144 memory blocks that have become empty. (The block will be freed if the string
1145 is at its start.) However, we can do this only if we know that the old string
1146 was the last item on the dynamic memory stack. This is the case if it matches
1147 store_last_get. */
1148
1149 if (!store_extend(g->s, oldsize, g->size))
1150   g->s = store_newblock(g->s, g->size, p);
1151 }
1152
1153
1154
1155 /*************************************************
1156 *             Add chars to string                *
1157 *************************************************/
1158 /* This function is used when building up strings of unknown length. Room is
1159 always left for a terminating zero to be added to the string that is being
1160 built. This function does not require the string that is being added to be NUL
1161 terminated, because the number of characters to add is given explicitly. It is
1162 sometimes called to extract parts of other strings.
1163
1164 Arguments:
1165   g        growable-string that is being built, or NULL if not assigned yet
1166   s        points to characters to add
1167   count    count of characters to add; must not exceed the length of s, if s
1168              is a C string.
1169
1170 Returns:   growable string, changed if copied for expansion.
1171            Note that a NUL is not added, though space is left for one. This is
1172            because string_cat() is often called multiple times to build up a
1173            string - there's no point adding the NUL till the end.
1174            NULL is a possible return.
1175
1176 */
1177 /* coverity[+alloc] */
1178
1179 gstring *
1180 string_catn(gstring * g, const uschar * s, int count)
1181 {
1182 int p;
1183
1184 if (count < 0)
1185   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1186     "internal error in string_catn (count %d)", count);
1187 if (count == 0) return g;
1188
1189 /*debug_printf("string_catn '%.*s'\n", count, s);*/
1190 if (!g)
1191   {
1192   unsigned inc = count < 4096 ? 127 : 1023;
1193   unsigned size = ((count + inc) &  ~inc) + 1;  /* round up requested count */
1194   g = string_get_tainted(size, s);
1195   }
1196 else if (!g->s)                 /* should not happen */
1197   {
1198   g->s = string_copyn(s, count);
1199   g->ptr = count;
1200   g->size = count;      /*XXX suboptimal*/
1201   return g;
1202   }
1203 else if (is_incompatible(g->s, s))
1204   {
1205 /* debug_printf("rebuf A\n"); */
1206   gstring_rebuffer(g, s);
1207   }
1208
1209 if (g->ptr < 0 || g->ptr > g->size)
1210   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1211     "internal error in string_catn (ptr %d size %d)", g->ptr, g->size);
1212
1213 p = g->ptr;
1214 if (count >= g->size - p)
1215   gstring_grow(g, count);
1216
1217 /* Because we always specify the exact number of characters to copy, we can
1218 use memcpy(), which is likely to be more efficient than strncopy() because the
1219 latter has to check for zero bytes. */
1220
1221 memcpy(g->s + p, s, count);
1222 g->ptr = p + count;
1223 return g;
1224 }
1225
1226
1227 gstring *
1228 string_cat(gstring * g, const uschar * s)
1229 {
1230 return string_catn(g, s, Ustrlen(s));
1231 }
1232
1233
1234
1235 /*************************************************
1236 *        Append strings to another string        *
1237 *************************************************/
1238
1239 /* This function can be used to build a string from many other strings.
1240 It calls string_cat() to do the dirty work.
1241
1242 Arguments:
1243   g        growable-string that is being built, or NULL if not yet assigned
1244   count    the number of strings to append
1245   ...      "count" uschar* arguments, which must be valid zero-terminated
1246              C strings
1247
1248 Returns:   growable string, changed if copied for expansion.
1249            The string is not zero-terminated - see string_cat() above.
1250 */
1251
1252 __inline__ gstring *
1253 string_append(gstring * g, int count, ...)
1254 {
1255 va_list ap;
1256
1257 va_start(ap, count);
1258 while (count-- > 0)
1259   {
1260   uschar * t = va_arg(ap, uschar *);
1261   g = string_cat(g, t);
1262   }
1263 va_end(ap);
1264
1265 return g;
1266 }
1267 #endif
1268
1269
1270
1271 /*************************************************
1272 *        Format a string with length checks      *
1273 *************************************************/
1274
1275 /* This function is used to format a string with checking of the length of the
1276 output for all conversions. It protects Exim from absent-mindedness when
1277 calling functions like debug_printf and string_sprintf, and elsewhere. There
1278 are two different entry points to what is actually the same function, depending
1279 on whether the variable length list of data arguments are given explicitly or
1280 as a va_list item.
1281
1282 The formats are the usual printf() ones, with some omissions (never used) and
1283 three additions for strings: %S forces lower case, %T forces upper case, and
1284 %#s or %#S prints nothing for a NULL string. Without the # "NULL" is printed
1285 (useful in debugging). There is also the addition of %D and %M, which insert
1286 the date in the form used for datestamped log files.
1287
1288 Arguments:
1289   buffer       a buffer in which to put the formatted string
1290   buflen       the length of the buffer
1291   format       the format string - deliberately char * and not uschar *
1292   ... or ap    variable list of supplementary arguments
1293
1294 Returns:       TRUE if the result fitted in the buffer
1295 */
1296
1297 BOOL
1298 string_format_trc(uschar * buffer, int buflen,
1299   const uschar * func, unsigned line, const char * format, ...)
1300 {
1301 gstring g = { .size = buflen, .ptr = 0, .s = buffer }, * gp;
1302 va_list ap;
1303 va_start(ap, format);
1304 gp = string_vformat_trc(&g, func, line, STRING_SPRINTF_BUFFER_SIZE,
1305         0, format, ap);
1306 va_end(ap);
1307 g.s[g.ptr] = '\0';
1308 return !!gp;
1309 }
1310
1311
1312
1313
1314 /* Build or append to a growing-string, sprintf-style.
1315
1316 Arguments:
1317         g       a growable-string
1318         func    called-from function name, for debug
1319         line    called-from file line number, for debug
1320         limit   maximum string size
1321         flags   see below
1322         format  printf-like format string
1323         ap      variable-args pointer
1324
1325 Flags:
1326         SVFMT_EXTEND            buffer can be created or exteded as needed
1327         SVFMT_REBUFFER          buffer can be recopied to tainted mem as needed
1328         SVFMT_TAINT_NOCHK       do not check inputs for taint
1329
1330 If the "extend" flag is true, the string passed in can be NULL,
1331 empty, or non-empty.  Growing is subject to an overall limit given
1332 by the limit argument.
1333
1334 If the "extend" flag is false, the string passed in may not be NULL,
1335 will not be grown, and is usable in the original place after return.
1336 The return value can be NULL to signify overflow.
1337
1338 Field width:            decimal digits, or *
1339 Precision:              dot, followed by decimal digits or *
1340 Length modifiers:       h  L  l  ll  z
1341 Conversion specifiers:  n d o u x X p f e E g G % c s S T Y D M
1342
1343 Returns the possibly-new (if copy for growth or taint-handling was needed)
1344 string, not nul-terminated.
1345 */
1346
1347 gstring *
1348 string_vformat_trc(gstring * g, const uschar * func, unsigned line,
1349   unsigned size_limit, unsigned flags, const char * format, va_list ap)
1350 {
1351 enum ltypes { L_NORMAL=1, L_SHORT=2, L_LONG=3, L_LONGLONG=4, L_LONGDOUBLE=5, L_SIZE=6 };
1352
1353 int width, precision, off, lim, need;
1354 const char * fp = format;       /* Deliberately not unsigned */
1355
1356 string_datestamp_offset = -1;   /* Datestamp not inserted */
1357 string_datestamp_length = 0;    /* Datestamp not inserted */
1358 string_datestamp_type = 0;      /* Datestamp not inserted */
1359
1360 #ifdef COMPILE_UTILITY
1361 assert(!(flags & SVFMT_EXTEND));
1362 assert(g);
1363 #else
1364
1365 /* Ensure we have a string, to save on checking later */
1366 if (!g) g = string_get(16);
1367
1368 if (!(flags & SVFMT_TAINT_NOCHK) && is_incompatible(g->s, format))
1369   {
1370 #ifndef MACRO_PREDEF
1371   if (!(flags & SVFMT_REBUFFER))
1372     die_tainted(US"string_vformat", func, line);
1373 #endif
1374 /* debug_printf("rebuf B\n"); */
1375   gstring_rebuffer(g, format);
1376   }
1377 #endif  /*!COMPILE_UTILITY*/
1378
1379 lim = g->size - 1;      /* leave one for a nul */
1380 off = g->ptr;           /* remember initial offset in gstring */
1381
1382 /* Scan the format and handle the insertions */
1383
1384 while (*fp)
1385   {
1386   int length = L_NORMAL;
1387   int * nptr;
1388   int slen;
1389   const char *null = "NULL";            /* ) These variables */
1390   const char *item_start, *s;           /* ) are deliberately */
1391   char newformat[16];                   /* ) not unsigned */
1392   char * gp = CS g->s + g->ptr;         /* ) */
1393
1394   /* Non-% characters just get copied verbatim */
1395
1396   if (*fp != '%')
1397     {
1398     /* Avoid string_copyn() due to COMPILE_UTILITY */
1399     if ((need = g->ptr + 1) > lim)
1400       {
1401       if (!(flags & SVFMT_EXTEND) || need > size_limit) return NULL;
1402       gstring_grow(g, 1);
1403       lim = g->size - 1;
1404       }
1405     g->s[g->ptr++] = (uschar) *fp++;
1406     continue;
1407     }
1408
1409   /* Deal with % characters. Pick off the width and precision, for checking
1410   strings, skipping over the flag and modifier characters. */
1411
1412   item_start = fp;
1413   width = precision = -1;
1414
1415   if (strchr("-+ #0", *(++fp)) != NULL)
1416     {
1417     if (*fp == '#') null = "";
1418     fp++;
1419     }
1420
1421   if (isdigit((uschar)*fp))
1422     {
1423     width = *fp++ - '0';
1424     while (isdigit((uschar)*fp)) width = width * 10 + *fp++ - '0';
1425     }
1426   else if (*fp == '*')
1427     {
1428     width = va_arg(ap, int);
1429     fp++;
1430     }
1431
1432   if (*fp == '.')
1433     if (*(++fp) == '*')
1434       {
1435       precision = va_arg(ap, int);
1436       fp++;
1437       }
1438     else
1439       for (precision = 0; isdigit((uschar)*fp); fp++)
1440         precision = precision*10 + *fp - '0';
1441
1442   /* Skip over 'h', 'L', 'l', 'll' and 'z', remembering the item length */
1443
1444   if (*fp == 'h')
1445     { fp++; length = L_SHORT; }
1446   else if (*fp == 'L')
1447     { fp++; length = L_LONGDOUBLE; }
1448   else if (*fp == 'l')
1449     if (fp[1] == 'l')
1450       { fp += 2; length = L_LONGLONG; }
1451     else
1452       { fp++; length = L_LONG; }
1453   else if (*fp == 'z')
1454     { fp++; length = L_SIZE; }
1455
1456   /* Handle each specific format type. */
1457
1458   switch (*fp++)
1459     {
1460     case 'n':
1461       nptr = va_arg(ap, int *);
1462       *nptr = g->ptr - off;
1463       break;
1464
1465     case 'd':
1466     case 'o':
1467     case 'u':
1468     case 'x':
1469     case 'X':
1470       width = length > L_LONG ? 24 : 12;
1471       if ((need = g->ptr + width) > lim)
1472         {
1473         if (!(flags & SVFMT_EXTEND) || need >= size_limit) return NULL;
1474         gstring_grow(g, width);
1475         lim = g->size - 1;
1476         gp = CS g->s + g->ptr;
1477         }
1478       strncpy(newformat, item_start, fp - item_start);
1479       newformat[fp - item_start] = 0;
1480
1481       /* Short int is promoted to int when passing through ..., so we must use
1482       int for va_arg(). */
1483
1484       switch(length)
1485         {
1486         case L_SHORT:
1487         case L_NORMAL:
1488           g->ptr += sprintf(gp, newformat, va_arg(ap, int)); break;
1489         case L_LONG:
1490           g->ptr += sprintf(gp, newformat, va_arg(ap, long int)); break;
1491         case L_LONGLONG:
1492           g->ptr += sprintf(gp, newformat, va_arg(ap, LONGLONG_T)); break;
1493         case L_SIZE:
1494           g->ptr += sprintf(gp, newformat, va_arg(ap, size_t)); break;
1495         }
1496       break;
1497
1498     case 'p':
1499       {
1500       void * ptr;
1501       if ((need = g->ptr + 24) > lim)
1502         {
1503         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1504         gstring_grow(g, 24);
1505         lim = g->size - 1;
1506         gp = CS g->s + g->ptr;
1507         }
1508       /* sprintf() saying "(nil)" for a null pointer seems unreliable.
1509       Handle it explicitly. */
1510       if ((ptr = va_arg(ap, void *)))
1511         {
1512         strncpy(newformat, item_start, fp - item_start);
1513         newformat[fp - item_start] = 0;
1514         g->ptr += sprintf(gp, newformat, ptr);
1515         }
1516       else
1517         g->ptr += sprintf(gp, "(nil)");
1518       }
1519     break;
1520
1521     /* %f format is inherently insecure if the numbers that it may be
1522     handed are unknown (e.g. 1e300). However, in Exim, %f is used for
1523     printing load averages, and these are actually stored as integers
1524     (load average * 1000) so the size of the numbers is constrained.
1525     It is also used for formatting sending rates, where the simplicity
1526     of the format prevents overflow. */
1527
1528     case 'f':
1529     case 'e':
1530     case 'E':
1531     case 'g':
1532     case 'G':
1533       if (precision < 0) precision = 6;
1534       if ((need = g->ptr + precision + 8) > lim)
1535         {
1536         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1537         gstring_grow(g, precision+8);
1538         lim = g->size - 1;
1539         gp = CS g->s + g->ptr;
1540         }
1541       strncpy(newformat, item_start, fp - item_start);
1542       newformat[fp-item_start] = 0;
1543       if (length == L_LONGDOUBLE)
1544         g->ptr += sprintf(gp, newformat, va_arg(ap, long double));
1545       else
1546         g->ptr += sprintf(gp, newformat, va_arg(ap, double));
1547       break;
1548
1549     /* String types */
1550
1551     case '%':
1552       if ((need = g->ptr + 1) > lim)
1553         {
1554         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1555         gstring_grow(g, 1);
1556         lim = g->size - 1;
1557         }
1558       g->s[g->ptr++] = (uschar) '%';
1559       break;
1560
1561     case 'c':
1562       if ((need = g->ptr + 1) > lim)
1563         {
1564         if (!(flags & SVFMT_EXTEND || need >= size_limit)) return NULL;
1565         gstring_grow(g, 1);
1566         lim = g->size - 1;
1567         }
1568       g->s[g->ptr++] = (uschar) va_arg(ap, int);
1569       break;
1570
1571     case 'D':                   /* Insert daily datestamp for log file names */
1572       s = CS tod_stamp(tod_log_datestamp_daily);
1573       string_datestamp_offset = g->ptr;         /* Passed back via global */
1574       string_datestamp_length = Ustrlen(s);     /* Passed back via global */
1575       string_datestamp_type = tod_log_datestamp_daily;
1576       slen = string_datestamp_length;
1577       goto INSERT_STRING;
1578
1579     case 'M':                   /* Insert monthly datestamp for log file names */
1580       s = CS tod_stamp(tod_log_datestamp_monthly);
1581       string_datestamp_offset = g->ptr;         /* Passed back via global */
1582       string_datestamp_length = Ustrlen(s);     /* Passed back via global */
1583       string_datestamp_type = tod_log_datestamp_monthly;
1584       slen = string_datestamp_length;
1585       goto INSERT_STRING;
1586
1587     case 'Y':                   /* gstring pointer */
1588       {
1589       gstring * zg = va_arg(ap, gstring *);
1590       if (zg) { s = CS zg->s; slen = zg->ptr;    }
1591       else    { s = null;     slen = Ustrlen(s); }
1592       goto INSERT_GSTRING;
1593       }
1594
1595     case 's':
1596     case 'S':                   /* Forces *lower* case */
1597     case 'T':                   /* Forces *upper* case */
1598       s = va_arg(ap, char *);
1599
1600       if (!s) s = null;
1601       slen = Ustrlen(s);
1602
1603     INSERT_GSTRING:             /* Coome to from %Y above */
1604
1605       if (!(flags & SVFMT_TAINT_NOCHK) && is_incompatible(g->s, s))
1606         if (flags & SVFMT_REBUFFER)
1607           {
1608 /* debug_printf("%s %d: untainted workarea, tainted %%s :- rebuffer\n", __FUNCTION__, __LINE__); */
1609           gstring_rebuffer(g, s);
1610           gp = CS g->s + g->ptr;
1611           }
1612 #ifndef MACRO_PREDEF
1613         else
1614           die_tainted(US"string_vformat", func, line);
1615 #endif
1616
1617     INSERT_STRING:              /* Come to from %D or %M above */
1618
1619       {
1620       BOOL truncated = FALSE;
1621
1622       /* If the width is specified, check that there is a precision
1623       set; if not, set it to the width to prevent overruns of long
1624       strings. */
1625
1626       if (width >= 0)
1627         {
1628         if (precision < 0) precision = width;
1629         }
1630
1631       /* If a width is not specified and the precision is specified, set
1632       the width to the precision, or the string length if shorted. */
1633
1634       else if (precision >= 0)
1635         width = precision < slen ? precision : slen;
1636
1637       /* If neither are specified, set them both to the string length. */
1638
1639       else
1640         width = precision = slen;
1641
1642       if ((need = g->ptr + width) >= size_limit || !(flags & SVFMT_EXTEND))
1643         {
1644         if (g->ptr == lim) return NULL;
1645         if (need > lim)
1646           {
1647           truncated = TRUE;
1648           width = precision = lim - g->ptr - 1;
1649           if (width < 0) width = 0;
1650           if (precision < 0) precision = 0;
1651           }
1652         }
1653       else if (need > lim)
1654         {
1655         gstring_grow(g, width);
1656         lim = g->size - 1;
1657         gp = CS g->s + g->ptr;
1658         }
1659
1660       g->ptr += sprintf(gp, "%*.*s", width, precision, s);
1661       if (fp[-1] == 'S')
1662         while (*gp) { *gp = tolower(*gp); gp++; }
1663       else if (fp[-1] == 'T')
1664         while (*gp) { *gp = toupper(*gp); gp++; }
1665
1666       if (truncated) return NULL;
1667       break;
1668       }
1669
1670     /* Some things are never used in Exim; also catches junk. */
1671
1672     default:
1673       strncpy(newformat, item_start, fp - item_start);
1674       newformat[fp-item_start] = 0;
1675       log_write(0, LOG_MAIN|LOG_PANIC_DIE, "string_format: unsupported type "
1676         "in \"%s\" in \"%s\"", newformat, format);
1677       break;
1678     }
1679   }
1680
1681 if (g->ptr > g->size)
1682   log_write(0, LOG_MAIN|LOG_PANIC_DIE,
1683     "string_format internal error: caller %s %d", func, line);
1684 return g;
1685 }
1686
1687
1688
1689 #ifndef COMPILE_UTILITY
1690 /*************************************************
1691 *       Generate an "open failed" message        *
1692 *************************************************/
1693
1694 /* This function creates a message after failure to open a file. It includes a
1695 string supplied as data, adds the strerror() text, and if the failure was
1696 "Permission denied", reads and includes the euid and egid.
1697
1698 Arguments:
1699   format        a text format string - deliberately not uschar *
1700   func          caller, for debug
1701   line          caller, for debug
1702   ...           arguments for the format string
1703
1704 Returns:        a message, in dynamic store
1705 */
1706
1707 uschar *
1708 string_open_failed_trc(const uschar * func, unsigned line,
1709   const char * format, ...)
1710 {
1711 va_list ap;
1712 gstring * g = string_get(1024);
1713
1714 g = string_catn(g, US"failed to open ", 15);
1715
1716 /* Use the checked formatting routine to ensure that the buffer
1717 does not overflow. It should not, since this is called only for internally
1718 specified messages. If it does, the message just gets truncated, and there
1719 doesn't seem much we can do about that. */
1720
1721 va_start(ap, format);
1722 (void) string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
1723         SVFMT_REBUFFER, format, ap);
1724 va_end(ap);
1725
1726 g = string_catn(g, US": ", 2);
1727 g = string_cat(g, US strerror(errno));
1728
1729 if (errno == EACCES)
1730   {
1731   int save_errno = errno;
1732   g = string_fmt_append(g, " (euid=%ld egid=%ld)",
1733     (long int)geteuid(), (long int)getegid());
1734   errno = save_errno;
1735   }
1736 gstring_release_unused(g);
1737 return string_from_gstring(g);
1738 }
1739
1740
1741
1742
1743
1744 /* qsort(3), currently used to sort the environment variables
1745 for -bP environment output, needs a function to compare two pointers to string
1746 pointers. Here it is. */
1747
1748 int
1749 string_compare_by_pointer(const void *a, const void *b)
1750 {
1751 return Ustrcmp(* CUSS a, * CUSS b);
1752 }
1753 #endif /* COMPILE_UTILITY */
1754
1755
1756
1757
1758 /*************************************************
1759 **************************************************
1760 *             Stand-alone test program           *
1761 **************************************************
1762 *************************************************/
1763
1764 #ifdef STAND_ALONE
1765 int main(void)
1766 {
1767 uschar buffer[256];
1768
1769 printf("Testing is_ip_address\n");
1770 store_init();
1771
1772 while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
1773   {
1774   int offset;
1775   buffer[Ustrlen(buffer) - 1] = 0;
1776   printf("%d\n", string_is_ip_address(buffer, NULL));
1777   printf("%d %d %s\n", string_is_ip_address(buffer, &offset), offset, buffer);
1778   }
1779
1780 printf("Testing string_nextinlist\n");
1781
1782 while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
1783   {
1784   uschar *list = buffer;
1785   uschar *lp1, *lp2;
1786   uschar item[256];
1787   int sep1 = 0;
1788   int sep2 = 0;
1789
1790   if (*list == '<')
1791     {
1792     sep1 = sep2 = list[1];
1793     list += 2;
1794     }
1795
1796   lp1 = lp2 = list;
1797   for (;;)
1798     {
1799     uschar *item1 = string_nextinlist(&lp1, &sep1, item, sizeof(item));
1800     uschar *item2 = string_nextinlist(&lp2, &sep2, NULL, 0);
1801
1802     if (item1 == NULL && item2 == NULL) break;
1803     if (item == NULL || item2 == NULL || Ustrcmp(item1, item2) != 0)
1804       {
1805       printf("***ERROR\nitem1=\"%s\"\nitem2=\"%s\"\n",
1806         (item1 == NULL)? "NULL" : CS item1,
1807         (item2 == NULL)? "NULL" : CS item2);
1808       break;
1809       }
1810     else printf("  \"%s\"\n", CS item1);
1811     }
1812   }
1813
1814 /* This is a horrible lash-up, but it serves its purpose. */
1815
1816 printf("Testing string_format\n");
1817
1818 while (fgets(CS buffer, sizeof(buffer), stdin) != NULL)
1819   {
1820   void *args[3];
1821   long long llargs[3];
1822   double dargs[3];
1823   int dflag = 0;
1824   int llflag = 0;
1825   int n = 0;
1826   int count;
1827   BOOL countset = FASE;
1828   uschar format[256];
1829   uschar outbuf[256];
1830   uschar *s;
1831   buffer[Ustrlen(buffer) - 1] = 0;
1832
1833   s = Ustrchr(buffer, ',');
1834   if (s == NULL) s = buffer + Ustrlen(buffer);
1835
1836   Ustrncpy(format, buffer, s - buffer);
1837   format[s-buffer] = 0;
1838
1839   if (*s == ',') s++;
1840
1841   while (*s != 0)
1842     {
1843     uschar *ss = s;
1844     s = Ustrchr(ss, ',');
1845     if (s == NULL) s = ss + Ustrlen(ss);
1846
1847     if (isdigit(*ss))
1848       {
1849       Ustrncpy(outbuf, ss, s-ss);
1850       if (Ustrchr(outbuf, '.') != NULL)
1851         {
1852         dflag = 1;
1853         dargs[n++] = Ustrtod(outbuf, NULL);
1854         }
1855       else if (Ustrstr(outbuf, "ll") != NULL)
1856         {
1857         llflag = 1;
1858         llargs[n++] = strtoull(CS outbuf, NULL, 10);
1859         }
1860       else
1861         {
1862         args[n++] = (void *)Uatoi(outbuf);
1863         }
1864       }
1865
1866     else if (Ustrcmp(ss, "*") == 0)
1867       {
1868       args[n++] = (void *)(&count);
1869       countset = TRUE;
1870       }
1871
1872     else
1873       {
1874       uschar *sss = malloc(s - ss + 1);
1875       Ustrncpy(sss, ss, s-ss);
1876       args[n++] = sss;
1877       }
1878
1879     if (*s == ',') s++;
1880     }
1881
1882   if (!dflag && !llflag)
1883     printf("%s\n", string_format(outbuf, sizeof(outbuf), CS format,
1884       args[0], args[1], args[2])? "True" : "False");
1885
1886   else if (dflag)
1887     printf("%s\n", string_format(outbuf, sizeof(outbuf), CS format,
1888       dargs[0], dargs[1], dargs[2])? "True" : "False");
1889
1890   else printf("%s\n", string_format(outbuf, sizeof(outbuf), CS format,
1891     llargs[0], llargs[1], llargs[2])? "True" : "False");
1892
1893   printf("%s\n", CS outbuf);
1894   if (countset) printf("count=%d\n", count);
1895   }
1896
1897 return 0;
1898 }
1899 #endif
1900
1901 /* End of string.c */