Attached patch fixes 2 bugs with signs and X11 GUIs:

- The X11 GUI should not allocate the bitmap before calling
  XpmReadFileToImage() since XpmReadFileToImage() API
  does the memory allocation.  As a result, memory for bitmap
  is allocated twice (leak) whenever defining a sign with
  an xpm icon in the X11 GUIs (athena, neXtaw, motif).

  The following script for example which redefines the
  same sign multiple times leaks memory at every iteration
  when using GUI X11 athena, neXtaw, motif:

     :while 1
        :sign define foo text=>> texthl=Search icon=foo.xpm
     :endwhile

- The X11 GUI frees memory incorrectly for the icon using
  XFree() and vim_free() instead of calling XDestroyImage().
  Using XFree() and vim_free() may possibly do the same
  thing as XDestroyImage() but at least not when Vim is
  built with -DMEM_PROFILE in which case vim_free() frees
  an invalid pointer.

  The XPM documentation indicates that XDestroyImage() should
  be used to free the bitmap allocated by XpmReadFileToImage().
  See http://www.cs.ualberta.ca/doc/Software_manuals/xpm.ps

Patch also frees gui_argv which was never freed.

Cheers
-- Dominique

--~--~---------~--~----~------------~-------~--~----~
You received this message from the "vim_dev" maillist.
For more information, visit http://www.vim.org/maillist.php
-~----------~----~----~----~------~----~------~--~---

Index: gui_x11.c
===================================================================
RCS file: /cvsroot/vim/vim7/src/gui_x11.c,v
retrieving revision 1.20
diff -c -r1.20 gui_x11.c
*** gui_x11.c	12 Nov 2008 12:08:45 -0000	1.20
--- gui_x11.c	22 Feb 2009 09:04:30 -0000
***************
*** 1587,1592 ****
--- 1587,1594 ----
      XtCloseDisplay(gui.dpy);
      gui.dpy = NULL;
      vimShell = (Widget)0;
+     vim_free(gui_argv);
+     gui_argv = NULL;
  }
  
  /*
***************
*** 1761,1766 ****
--- 1763,1770 ----
       * says that this isn't needed when exiting, so just skip it. */
      XtCloseDisplay(gui.dpy);
  #endif
+     vim_free(gui_argv);
+     gui_argv = NULL;
  }
  
  /*
***************
*** 3439,3484 ****
      char_u	    *signfile;
  {
      XpmAttributes   attrs;
!     XImage	    *sign;
      int		    status;
  
      /*
       * Setup the color substitution table.
       */
-     sign = NULL;
      if (signfile[0] != NUL && signfile[0] != '-')
      {
! 	sign = (XImage *)alloc(sizeof(XImage));
! 	if (sign != NULL)
  	{
! 	    XpmColorSymbol color[5] =
! 	    {
! 		{"none", NULL, 0},
! 		{"iconColor1", NULL, 0},
! 		{"bottomShadowColor", NULL, 0},
! 		{"topShadowColor", NULL, 0},
! 		{"selectColor", NULL, 0}
! 	    };
! 	    attrs.valuemask = XpmColorSymbols;
! 	    attrs.numsymbols = 2;
! 	    attrs.colorsymbols = color;
! 	    attrs.colorsymbols[0].pixel = gui.back_pixel;
! 	    attrs.colorsymbols[1].pixel = gui.norm_pixel;
! 	    status = XpmReadFileToImage(gui.dpy, (char *)signfile,
! 							 &sign, NULL, &attrs);
! 
! 	    if (status == 0)
! 	    {
! 		/* Sign width is fixed at two columns now.
! 		if (sign->width > gui.sign_width)
! 		    gui.sign_width = sign->width + 8; */
! 	    }
! 	    else
! 	    {
! 		vim_free(sign);
! 		sign = NULL;
! 		EMSG(_(e_signdata));
! 	    }
  	}
      }
  
--- 3443,3480 ----
      char_u	    *signfile;
  {
      XpmAttributes   attrs;
!     XImage	    *sign = NULL;
      int		    status;
  
      /*
       * Setup the color substitution table.
       */
      if (signfile[0] != NUL && signfile[0] != '-')
      {
! 	XpmColorSymbol color[5] =
  	{
! 	    {"none", NULL, 0},
! 	    {"iconColor1", NULL, 0},
! 	    {"bottomShadowColor", NULL, 0},
! 	    {"topShadowColor", NULL, 0},
! 	    {"selectColor", NULL, 0}
! 	};
! 	attrs.valuemask = XpmColorSymbols;
! 	attrs.numsymbols = 2;
! 	attrs.colorsymbols = color;
! 	attrs.colorsymbols[0].pixel = gui.back_pixel;
! 	attrs.colorsymbols[1].pixel = gui.norm_pixel;
! 	status = XpmReadFileToImage(gui.dpy, (char *)signfile,
! 	    					 &sign, NULL, &attrs);
! 	if (status == 0)
! 	{
! 	    /* Sign width is fixed at two columns now.
! 	    if (sign->width > gui.sign_width)
! 	        gui.sign_width = sign->width + 8; */
! 	}
! 	else
! 	{
! 	    EMSG(_(e_signdata));
  	}
      }
  
***************
*** 3489,3496 ****
  gui_mch_destroy_sign(sign)
      void *sign;
  {
!     XFree(((XImage *)sign)->data);
!     vim_free(sign);
  }
  #endif
  
--- 3485,3491 ----
  gui_mch_destroy_sign(sign)
      void *sign;
  {
!     XDestroyImage((XImage*)sign);
  }
  #endif
  

Raspunde prin e-mail lui