Hello,

references:

  - Described a bug (big memory leaks) in the i18n code to
    [EMAIL PROTECTED] -- 18 June 2002 11:32:11 UTC 

  - As nobody was interested by my bug report produce a first
    fix: A.1141 -- 24 June 2002 21:27:58 UTC ([EMAIL PROTECTED]) 

  - Amelioration of A.1141: A.1150 -- 29 June 2002 07:47:29 UTC
    ([EMAIL PROTECTED], CC to [EMAIL PROTECTED], i.e., try to get
    feedback)

  - ask for feedback on A.1150 to [EMAIL PROTECTED] --
    18 July 2002 02:54:09 UTC -- Get a polite answer.

Now, since four months I try to contact the X experts about
memory leaks in the i18n code. I get no feedback and my fixes
was not applied. So I try again ...

Attached to this message a patch against the current cvs
(the difference with A.1150 is that lib/X11/lcFile.c has changed
recently in the cvs, so I rewrite this part of the patch).

The patch fixes a big memory leak in lib/X11/omGeneric.c:
at some point an XFontStruct is not freed (destroy_fontdata).
Also a "break" is added in lib/X11/omGeberic.c (parse_fontdata),
as suggested in the code by O. Talyor.
I explain why this "break" should be added (Moreover, this fix a
memory leak and fix slow font loading with a base font name with
a long list of fonts). There are also others small fixes.

The patch also fixes minor memory leaks in lib/X11/lcFile.c
(_XlcLocaleDirName) that I found when I read the i18n code.

Regards, Olivier
Index: lcFile.c
===================================================================
RCS file: /cvs/xc/lib/X11/lcFile.c,v
retrieving revision 3.27
diff -u -r3.27 lcFile.c
--- lcFile.c    2002/09/04 03:09:48     3.27
+++ lcFile.c    2002/10/16 09:18:28
@@ -443,6 +443,10 @@
   xlocaledir (dir, PATH_MAX);
   n = _XlcParsePath(dir, args, 256);
   for (i = 0; i < n; ++i){
+    if (name != NULL && name != lc_name) {
+       XFree(name);
+       name = NULL;
+    }
     if ((2 + (args[i] ? strlen(args[i]) : 0) + 
         strlen(locale_alias)) < PATH_MAX) {
       sprintf (buf, "%s/%s", args[i], locale_alias);
@@ -471,15 +475,26 @@
        *p = '\0';
        break;
       }
+      XFree(target_name);
+      target_name = NULL;
     }
   }
+
+  if (name != NULL && name != lc_name) {
+      XFree(name);
+  }
+
   if (target_name == NULL) {
     /* vendor locale name == Xlocale name, no expansion of alias */
     target_dir = args[0];
     target_name = lc_name;
   }
+
   strcpy(dir_name, target_dir);
   strcat(dir_name, "/");
   strcat(dir_name, target_name);
+  if (target_name != lc_name) {
+      XFree(target_name);
+  }
   return dir_name;
 }
Index: omGeneric.c
===================================================================
RCS file: /cvs/xc/lib/X11/omGeneric.c,v
retrieving revision 3.20
diff -u -r3.20 omGeneric.c
--- omGeneric.c 2001/04/05 17:42:26     3.20
+++ omGeneric.c 2002/10/16 09:18:41
@@ -1056,6 +1056,21 @@
             *
             * Owen Taylor <[EMAIL PROTECTED]>     12 Jul 2000
             */
+           /* The reason why this routine modifies font_data and has a
+            * font_data_return is that if it is called with C_PRIMARY, then
+            * font_data_return is used by the caller and with the others classes
+            * font_data is used by the caller (font_data can be different
+            * than font_data_return if we do not break here).
+            * However, a close look at the code (e.g., the drawing funcs) shows
+            * that breaking or not here change nothing! 
+            * So we should 'break' here.
+            * Hopefully this also fix a memory leak: if we do not break here
+            * and found a match later font_data->xlfd_name is deferenced without
+            * being freed. Finally, this speed up font loading.
+            *
+            * <[EMAIL PROTECTED]>             2002-06-29
+            */
+           break;
        }
 
        switch(class) {
@@ -1126,13 +1141,21 @@
     int                ret = 0, i = 0;
 
     if(vmap_num > 0) {
-       if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list, count, C_VMAP) == 
-1)
+       if(parse_fontdata(oc, font_set, vmap, vmap_num, name_list, count,
+                         C_VMAP, &font_data_return) == -1) {
+           if(font_data_return.xlfd_name != NULL)
+                XFree(font_data_return.xlfd_name);
            return (-1);
+       }
+       if(font_data_return.xlfd_name != NULL)
+           XFree(font_data_return.xlfd_name);
     }
 
     if(vrotate_num > 0) {
        ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
                             name_list, count, C_VROTATE, &font_data_return);
+       if(font_data_return.xlfd_name != NULL)
+           XFree(font_data_return.xlfd_name);
        if(ret == -1) {
            return (-1);
        } else if(ret == False) {
@@ -1168,6 +1191,8 @@
 
            ret = parse_fontdata(oc, font_set, (FontData) vrotate, vrotate_num,
                                 name_list, count, C_VROTATE, &font_data_return);
+           if(font_data_return.xlfd_name != NULL)
+               XFree(font_data_return.xlfd_name);
            if(ret == -1)
                return (-1);
        }
@@ -1237,6 +1262,7 @@
                font_set->side = font_data_return.side;
 
                 Xfree (font_data_return.xlfd_name);
+                font_data_return.xlfd_name = NULL;
 
                if(parse_vw(oc, font_set, name_list, count) == -1)
                    goto err;
@@ -1258,6 +1284,10 @@
            ret = parse_fontdata(oc, font_set, font_set->substitute,
                                 font_set->substitute_num,
                                 name_list, count, C_SUBSTITUTE, &font_data_return);
+           if(font_data_return.xlfd_name != NULL) {
+               XFree(font_data_return.xlfd_name);
+               font_data_return.xlfd_name = NULL;
+           }
            if(ret == -1) {
                goto err;
            } else if(ret == True) {
@@ -1295,6 +1325,8 @@
     XFreeStringList(name_list);
     /* Prevent this from being freed twice */
     oc->core.base_name_list = NULL;
+    if(font_data_return.xlfd_name != NULL)
+       XFree(font_data_return.xlfd_name);
 
     return -1;
 }
@@ -1475,6 +1507,13 @@
        font_set = gen->font_set;
        font_set_num = gen->font_set_num;
        for( ; font_set_num-- ; font_set++) {
+           if(font_set->font) {
+               if(font_set->font->fid)
+                   XFreeFont(dpy,font_set->font);
+               else
+                   XFreeFontInfo(NULL, font_set->font, 1);
+               font_set->font = NULL;
+           }
            if(font_set->font_data) {
                free_fontdataOC(dpy,
                        font_set->font_data, font_set->font_data_count);

Reply via email to