[exim-cvs] cvs commit: exim/exim-src/src expand.c

Top Page
Delete this message
Reply to this message
Author: Tony Finch
Date:  
To: exim-cvs
Subject: [exim-cvs] cvs commit: exim/exim-src/src expand.c
fanf2 2008/05/22 11:56:27 BST

  Modified files:
    exim-src/src         expand.c 
  Log:
  If a ${dlfunc module has side-effects that cause store allocation, this
  can conflict with the string expansion storage management logic - in
  particular, the expansion code resets the store to reclaim working
  space. In order to avoid destroying store allocated by ${dlfunc the
  expansion code now leaks a bit if ${dlfunc is used.


Fixes: bug #713

  Revision  Changes    Path
  1.95      +13 -4     exim/exim-src/src/expand.c


  Index: expand.c
  ===================================================================
  RCS file: /home/cvs/exim/exim-src/src/expand.c,v
  retrieving revision 1.94
  retrieving revision 1.95
  diff -u -r1.94 -r1.95
  --- expand.c    24 Apr 2008 18:30:02 -0000    1.94
  +++ expand.c    22 May 2008 10:56:27 -0000    1.95
  @@ -1,4 +1,4 @@
  -/* $Cambridge: exim/exim-src/src/expand.c,v 1.94 2008/04/24 18:30:02 tom Exp $ */
  +/* $Cambridge: exim/exim-src/src/expand.c,v 1.95 2008/05/22 10:56:27 fanf2 Exp $ */


   /*************************************************
   *     Exim - an Internet mail transport agent    *
  @@ -3136,6 +3136,12 @@
   use that without copying. This is helpful for expanding strings like
   $message_headers which can get very long.


  +There's a problem if a ${dlfunc item has side-effects that cause allocation,
  +since resetting the store at the end of the expansion will free store that was
  +allocated by the plugin code as well as the slop after the expanded string. So
  +we skip any resets if ${dlfunc has been used. This is an unfortunate
  +consequence of string expansion becoming too powerful.
  +
   Arguments:
     string         the string to be expanded
     ket_ends       true if expansion is to stop at }
  @@ -3161,6 +3167,7 @@
   uschar *s = string;
   uschar *save_expand_nstring[EXPAND_MAXN+1];
   int save_expand_nlength[EXPAND_MAXN+1];
  +BOOL resetok = TRUE;


expand_string_forcedfail = FALSE;
expand_string_message = US"";
@@ -3233,7 +3240,7 @@

       if (ptr == 0 && yield != NULL)
         {
  -      store_reset(yield);
  +      if (resetok) store_reset(yield);
         yield = NULL;
         size = 0;
         }
  @@ -4963,8 +4970,10 @@
         returns OK, we have a replacement string; if it returns DEFER then
         expansion has failed in a non-forced manner; if it returns FAIL then
         failure was forced; if it returns ERROR or any other value there's a
  -      problem, so panic slightly. */
  +      problem, so panic slightly. In any case, assume that the function has
  +      side-effects on the store that must be preserved. */


  +      resetok = FALSE;
         result = NULL;
         for (argc = 0; argv[argc] != NULL; argc++);
         status = func(&result, argc - 2, &argv[2]);
  @@ -5702,7 +5711,7 @@
       int newsize = 0;
       if (ptr == 0)
         {
  -      store_reset(yield);
  +      if (resetok) store_reset(yield);
         yield = NULL;
         size = 0;
         }
  @@ -5757,7 +5766,7 @@
   In many cases the final string will be the first one that was got and so there
   will be optimal store usage. */


  -store_reset(yield + ptr + 1);
  +if (resetok) store_reset(yield + ptr + 1);
   DEBUG(D_expand)
     {
     debug_printf("expanding: %.*s\n   result: %s\n", (int)(s - string), string,