* Exim - an Internet mail transport agent *
*************************************************/
+/* Copyright (c) The Exim Maintainers 2020 - 2022 */
/* Copyright (c) University of Cambridge 1995 - 2018 */
-/* Copyright (c) The Exim Maintainers 2020 - 2021 */
/* See the file NOTICE for conditions of use and distribution. */
+/* SPDX-License-Identifier: GPL-2.0-or-later */
/* Miscellaneous string-handling functions. Some are not required for
utilities and tests, and are cut out by the COMPILE_UTILITY macro. */
*************************************************/
/* Convert a long integer into an ASCII base 62 string. For Cygwin the value of
-BASE_62 is actually 36. Always return exactly 6 characters plus zero, in a
-static area.
+BASE_62 is actually 36. Always return exactly 6 characters plus a NUL, in a
+static area. This is enough for a 32b input, for 62 (for 64b we would want 11+nul);
+but with 36 we lose half the input range of a 32b input.
Argument: a long integer
Returns: pointer to base 62 string
*/
uschar *
-string_base62(unsigned long int value)
+string_base62_32(unsigned long int value)
{
static uschar yield[7];
-uschar *p = yield + sizeof(yield) - 1;
+uschar * p = yield + sizeof(yield) - 1;
*p = 0;
while (p > yield)
{
- *(--p) = base62_chars[value % BASE_62];
+ *--p = base62_chars[value % BASE_62];
value /= BASE_62;
}
return yield;
}
+
+uschar *
+string_base62_64(unsigned long int value)
+{
+static uschar yield[12];
+uschar * p = yield + sizeof(yield) - 1;
+*p = '\0';
+while (p > yield)
+ if (value)
+ {
+ *--p = base62_chars[value % BASE_62];
+ value /= BASE_62;
+ }
+ else
+ *--p = '0';
+return yield;
+}
#endif /* COMPILE_UTILITY */
unsigned size = ((count + inc) & ~inc) + 1; /* round up requested count */
g = string_get_tainted(size, s);
}
+else if (!g->s) /* should not happen */
+ {
+ g->s = string_copyn(s, count);
+ g->ptr = count;
+ g->size = count; /*XXX suboptimal*/
+ return g;
+ }
else if (is_incompatible(g->s, s))
{
/* debug_printf("rebuf A\n"); */
will not be grown, and is usable in the original place after return.
The return value can be NULL to signify overflow.
+Field width: decimal digits, or *
+Precision: dot, followed by decimal digits or *
+Length modifiers: h L l ll z
+Conversion specifiers: n d o u x X p f e E g G % c s S T Y D M
+
Returns the possibly-new (if copy for growth or taint-handling was needed)
string, not nul-terminated.
*/
slen = string_datestamp_length;
goto INSERT_STRING;
+ case 'Y': /* gstring pointer */
+ {
+ gstring * zg = va_arg(ap, gstring *);
+ s = CS zg->s;
+ slen = zg->ptr;
+ goto INSERT_GSTRING;
+ }
+
case 's':
case 'S': /* Forces *lower* case */
case 'T': /* Forces *upper* case */
if (!s) s = null;
slen = Ustrlen(s);
+ INSERT_GSTRING: /* Coome to from %Y above */
+
if (!(flags & SVFMT_TAINT_NOCHK) && is_incompatible(g->s, s))
if (flags & SVFMT_REBUFFER)
{
int llflag = 0;
int n = 0;
int count;
- int countset = 0;
+ BOOL countset = FASE;
uschar format[256];
uschar outbuf[256];
uschar *s;
else if (Ustrcmp(ss, "*") == 0)
{
args[n++] = (void *)(&count);
- countset = 1;
+ countset = TRUE;
}
else