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