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