I've included a fix for 2 memory leaks in CVS version 1.10.8 in rcs.c.  
On a 600 megabyte CVS repository with lots of tags, this patch makes a tag
operation take ~ 2.5 megabytes of RSS versus 11 megabytes without.  
Briefly, the memory leak is because the char **key and value arguments to
getdelta() are sometimes pointers to malloc()'ed areas and sometime
pointers from rcsbuf_getkey that we cant (and dont) free from callers.  If
you have any questions or comments, please email me directly, as I am not
on any CVS list. The two leaks were alloced from:

  rcs.c, line 7817
  rcs.c, line 7874


//Jesse Off
[EMAIL PROTECTED]


And now, the patch:

diff -uNr cvs-1.10.8.orig/ChangeLog cvs-1.10.8/ChangeLog
--- cvs-1.10.8.orig/ChangeLog   Mon Dec 13 13:08:19 1999
+++ cvs-1.10.8/ChangeLog        Tue Aug  1 23:47:58 2000
@@ -1,3 +1,7 @@
+2000-07-31  Jesse Off <[EMAIL PROTECTED]>
+
+       * rcs.c: Fixed a memory leak in getdelta().
+
 1999-12-09  Larry Jones  <[EMAIL PROTECTED]>
 
        * configure.in: Correctly handle systems that need both libsocket
diff -uNr cvs-1.10.8.orig/src/rcs.c cvs-1.10.8/src/rcs.c
--- cvs-1.10.8.orig/src/rcs.c   Tue Aug  1 23:15:24 2000
+++ cvs-1.10.8/src/rcs.c        Wed Aug  2 00:00:57 2000
@@ -560,6 +560,8 @@
        revision delta in KEY (the revision) and VALUE (the date key
        and its value).  This is what getdelta expects to receive.  */
 
+    key = xstrdup (key);
+    value = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL);
     while ((vnode = getdelta (&rcsbuf, rcsfile, &key, &value)) != NULL)
     {
        /* get the node */
@@ -605,6 +607,10 @@
        *pfp = fp;
        *rcsbufp = rcsbuf;
     }
+    if (key) 
+       free (key);
+    if (value) 
+       free (value);
     rdata->flags &= ~PARTIAL;
 }
 
@@ -7740,6 +7746,8 @@
     {
        if (! rcsbuf_getkey (rcsbuf, &key, &value))
            error (1, 0, "%s: unexpected EOF", rcsfile);
+        key = xstrdup (key);
+        value = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *)NULL);
     }
 
     /* Make sure that it is a revision number and not a cabbage 
@@ -7770,7 +7778,12 @@
        cp++;
 
     vnode->date = xstrdup (cp);
-
+    
+    if (key) 
+       free (key);
+    if (value) 
+       free (value);
+    key = value = NULL;
     /* Get author field.  */
     if (! rcsbuf_getkey (rcsbuf, &key, &value))
     {
@@ -7806,8 +7819,8 @@
     }
     if (STREQ (key, RCSDESC))
     {
-       *keyp = key;
-       *valp = value;
+       *keyp = xstrdup (key);
+       *valp = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *)NULL);;
        /* Probably could/should be a fatal error.  */
        error (0, 0, "warning: 'branches' keyword missing from %s", rcsfile);
        return vnode;
@@ -7827,8 +7840,8 @@
     }
     if (STREQ (key, RCSDESC))
     {
-       *keyp = key;
-       *valp = value;
+       *keyp = xstrdup (key);
+       *valp = rcsbuf_valcopy (rcsbuf, value, 0, (size_t *)NULL);
        /* Probably could/should be a fatal error.  */
        error (0, 0, "warning: 'next' keyword missing from %s", rcsfile);
        return vnode;

Reply via email to