ARC initial implementation. Experimental. Bug 2162
[exim.git] / src / src / string.c
index 6b7d9a0674750a001240e5efa67d3fbd0eaad0ec..29a87c57233f832f20be1264420bb79abc3fec46 100644 (file)
@@ -2,7 +2,7 @@
 *     Exim - an Internet mail transport agent    *
 *************************************************/
 
-/* Copyright (c) University of Cambridge 1995 - 2016 */
+/* Copyright (c) University of Cambridge 1995 - 2018 */
 /* See the file NOTICE for conditions of use and distribution. */
 
 /* Miscellaneous string-handling functions. Some are not required for
@@ -914,7 +914,7 @@ sep_is_special = iscntrl(sep);
 
 /* Handle the case when a buffer is provided. */
 
-if (buffer != NULL)
+if (buffer)
   {
   int p = 0;
   for (; *s != 0; s++)
@@ -960,6 +960,7 @@ else
     }
   while (g->ptr > 0 && isspace(g->s[g->ptr-1])) g->ptr--;
   buffer = string_from_gstring(g);
+  gstring_reset_unused(g);
   }
 
 /* Update the current pointer and return the new string */
@@ -1073,11 +1074,23 @@ g->s[g->ptr] = '\0';
 return g->s;
 }
 
+void
+gstring_reset_unused(gstring * g)
+{
+store_reset(g->s + (g->size = g->ptr + 1));
+}
+
 /*************************************************
 *             Add chars to string                *
 *************************************************/
 
-void
+/* Arguments:
+  g            the grawable-string
+  p            current end of data
+  count                amount to grow by
+*/
+
+static void
 gstring_grow(gstring * g, int p, int count)
 {
 int oldsize = g->size;
@@ -1102,13 +1115,7 @@ was the last item on the dynamic memory stack. This is the case if it matches
 store_last_get. */
 
 if (!store_extend(g->s, oldsize, g->size))
-  {
-  BOOL release_ok = store_last_get[store_pool] == g->s;
-  uschar *newstring = store_get(g->size);
-  memcpy(newstring, g->s, p);
-  if (release_ok) store_release(g->s);
-  g->s = newstring;
-  }
+  g->s = store_newblock(g->s, g->size, p);
 }
 
 
@@ -1372,10 +1379,20 @@ while (*fp != 0)
     break;
 
     case 'p':
-    if (p >= last - 24) { yield = FALSE; goto END_FORMAT; }
-    strncpy(newformat, item_start, fp - item_start);
-    newformat[fp - item_start] = 0;
-    p += sprintf(CS p, newformat, va_arg(ap, void *));
+      {
+      void * ptr;
+      if (p >= last - 24) { yield = FALSE; goto END_FORMAT; }
+      /* sprintf() saying "(nil)" for a null pointer seems unreliable.
+      Handle it explicitly. */
+      if ((ptr = va_arg(ap, void *)))
+       {
+       strncpy(newformat, item_start, fp - item_start);
+       newformat[fp - item_start] = 0;
+       p += sprintf(CS p, newformat, ptr);
+       }
+      else
+       p += sprintf(CS p, "(nil)");
+      }
     break;
 
     /* %f format is inherently insecure if the numbers that it may be