Eximon: fix string-handling. Bug 2500
[exim.git] / src / src / string.c
index 288466113fe860303f72b8cdecfc31b13c2e45fb..fbdc0246d48f591f09a3952801f6b274870a9a0a 100644 (file)
@@ -223,6 +223,8 @@ interpreted in strings.
 Arguments:
   pp       points a pointer to the initiating "\" in the string;
            the pointer gets updated to point to the final character
+           If the backslash is the last character in the string, it
+           is not interpreted.
 Returns:   the value of the character escape
 */
 
@@ -235,6 +237,7 @@ const uschar *hex_digits= CUS"0123456789abcdef";
 int ch;
 const uschar *p = *pp;
 ch = *(++p);
+if (ch == '\0') return **pp;
 if (isdigit(ch) && ch != '8' && ch != '9')
   {
   ch -= '0';
@@ -408,7 +411,8 @@ return ss;
 
 
 
-#ifdef HAVE_LOCAL_SCAN
+#if (defined(HAVE_LOCAL_SCAN) || defined(EXPAND_DLFUNC)) \
+       && !defined(MACRO_PREDEF) && !defined(COMPILE_UTILITY)
 /*************************************************
 *            Copy and save string                *
 *************************************************/
@@ -429,7 +433,7 @@ As above, but explicitly specifying the result taint status
 */
 
 uschar *
-string_copy_taint(const uschar * s, BOOL tainted)
+string_copy_taint_function(const uschar * s, BOOL tainted)
 {
 int len = Ustrlen(s) + 1;
 uschar *ss = store_get(len, tainted);
@@ -661,7 +665,7 @@ return yield;
 *************************************************/
 
 /* The formatting is done by string_vformat, which checks the length of
-everything.
+everything.  Taint is taken from the worst of the arguments.
 
 Arguments:
   format    a printf() format - deliberately char * rather than uschar *
@@ -674,12 +678,20 @@ Returns:    pointer to fresh piece of store containing sprintf'ed string
 uschar *
 string_sprintf_trc(const char *format, const uschar * func, unsigned line, ...)
 {
-gstring * g;
-va_list ap;
+#ifdef COMPILE_UTILITY
+uschar buffer[STRING_SPRINTF_BUFFER_SIZE];
+gstring gs = { .size = STRING_SPRINTF_BUFFER_SIZE, .ptr = 0, .s = buffer };
+gstring * g = &gs;
+unsigned flags = 0;
+#else
+gstring * g = NULL;
+unsigned flags = SVFMT_REBUFFER|SVFMT_EXTEND;
+#endif
 
+va_list ap;
 va_start(ap, line);
-g = string_vformat_trc(NULL, func, line, STRING_SPRINTF_BUFFER_SIZE,
-       SVFMT_REBUFFER|SVFMT_EXTEND, format, ap);
+g = string_vformat_trc(g, func, line, STRING_SPRINTF_BUFFER_SIZE,
+       flags, format, ap);
 va_end(ap);
 
 if (!g)
@@ -688,8 +700,12 @@ if (!g)
     " called from %s %d\n",
     STRING_SPRINTF_BUFFER_SIZE, format, func, line);
 
+#ifdef COMPILE_UTILITY
+return string_copyn(g->s, g->ptr);
+#else
 gstring_release_unused(g);
 return string_from_gstring(g);
+#endif
 }
 
 
@@ -1138,8 +1154,8 @@ memcpy(g->s + p, s, count);
 g->ptr = p + count;
 return g;
 }
+
+
 gstring *
 string_cat(gstring *string, const uschar *s)
 {
@@ -1248,8 +1264,8 @@ If the "extend" flag is false, the string passed in may not be NULL,
 will not be grown, and is usable in the original place after return.
 The return value can be NULL to signify overflow.
 
-Returns the possibly-new (if copy for growth was needed) string,
-not nul-terminated.
+Returns the possibly-new (if copy for growth or taint-handling was needed)
+string, not nul-terminated.
 */
 
 gstring *