I discoverd and fixed several memory leaks in IMdkit. The patch is attached. Though IMdkit is very old and will be replaced by IIIMF, it's widely used in many popular CJK Input Method, like xcin, Chinput etc. So most Linux distributions, including the newest RedHat 8.0 and UL 1.0,etc., will be affected by this bug.
Regards
James Su
diff -ur IMdkit.old/FrameMgr.c IMdkit/FrameMgr.c
--- IMdkit.old/FrameMgr.c Tue Jul 2 11:55:04 2002
+++ IMdkit/FrameMgr.c Sun Nov 3 14:56:17 2002
@@ -245,6 +245,19 @@
void FrameMgrFree (FrameMgr fm)
{
+ FrameIter p, cur;
+
+ p = fm->iters;
+ cur = p;
+
+ while (p)
+ {
+ p = p->next;
+ Xfree (cur);
+ cur = p;
+ }
+ /*endwhile*/
+
FrameInstFree (fm->fi);
Xfree (fm);
}
diff -ur IMdkit.old/i18nIc.c IMdkit/i18nIc.c
--- IMdkit.old/i18nIc.c Tue Jul 2 11:55:50 2002
+++ IMdkit/i18nIc.c Sun Nov 3 14:56:17 2002
@@ -42,17 +42,15 @@
char *p,
XICAttr *ic_attr,
int value_length,
- int need_swap)
+ int need_swap,
+ void **value_buf)
{
- char *buf;
FrameMgr fm;
- if ((buf = (char *) malloc (value_length)) == NULL)
- return;
/*endif*/
if (value_length == sizeof (CARD8))
{
- memmove (buf, p, value_length);
+ memmove (*value_buf, p, value_length);
}
else if (value_length == sizeof (CARD16))
{
@@ -63,7 +61,7 @@
/* get data */
FrameMgrGetToken (fm, value);
FrameMgrFree (fm);
- memmove (buf, &value, value_length);
+ memmove (*value_buf, &value, value_length);
}
else if (value_length == sizeof(CARD32))
{
@@ -74,7 +72,7 @@
/* get data */
FrameMgrGetToken (fm, value);
FrameMgrFree (fm);
- memmove (buf, &value, value_length);
+ memmove (*value_buf, &value, value_length);
}
/*endif*/
value_ret->attribute_id = ic_attr->attribute_id;
@@ -82,16 +80,18 @@
value_ret->name_length = ic_attr->length;
value_ret->type = ic_attr->type;
value_ret->value_length = value_length;
- value_ret->value = buf;
+ value_ret->value = *value_buf;
+
+ *value_buf += value_length;
}
static void SetFontAttribute (XICAttribute *value_ret,
char *p,
XICAttr *ic_attr,
int value_length,
- int need_swap)
+ int need_swap,
+ void **value_buf)
{
- char *buf;
char *base_name;
CARD16 base_length;
FrameMgr fm;
@@ -101,35 +101,35 @@
/* get data */
FrameMgrGetToken (fm, base_length);
FrameMgrSetSize (fm, base_length);
- if ((buf = (char *) malloc (base_length + 1)) == NULL)
- return;
+
/*endif*/
FrameMgrGetToken (fm, base_name);
FrameMgrFree(fm);
- strncpy (buf, base_name, base_length);
- buf[base_length] = (char) 0;
+ strncpy ((char *) (*value_buf), base_name, base_length);
+ ((char *) *value_buf)[base_length] = (char) 0;
value_ret->attribute_id = ic_attr->attribute_id;
value_ret->name = ic_attr->name;
value_ret->name_length = ic_attr->length;
value_ret->type = ic_attr->type;
value_ret->value_length = value_length;
- value_ret->value = buf;
+ value_ret->value = *value_buf;
+
+ *value_buf += (base_length + 1);
}
static void SetPointAttribute (XICAttribute *value_ret,
char *p,
XICAttr *ic_attr,
int value_length,
- int need_swap)
+ int need_swap,
+ void **value_buf)
{
XPoint *buf;
FrameMgr fm;
extern XimFrameRec xpoint_fr[];
- if ((buf = (XPoint *) malloc (sizeof (XPoint))) == NULL)
- return;
- /*endif*/
+ buf = (XPoint *) (*value_buf);
fm = FrameMgrInit (xpoint_fr, (char *) p, need_swap);
/* get data */
@@ -147,22 +147,23 @@
value_ret->type = ic_attr->type;
value_ret->value_length = value_length;
value_ret->value = (char *) buf;
+
+ *value_buf += value_length;
}
static void SetRectAttribute (XICAttribute *value_ret,
char *p,
XICAttr *ic_attr,
int value_length,
- int need_swap)
+ int need_swap,
+ void **value_buf)
{
XRectangle *buf;
FrameMgr fm;
extern XimFrameRec xrectangle_fr[];
- if ((buf = (XRectangle *) malloc (sizeof (XRectangle))) == NULL)
- return;
- /*endif*/
-
+ buf = (XRectangle *) (*value_buf);
+
fm = FrameMgrInit (xrectangle_fr, (char *) p, need_swap);
/* get data */
FrameMgrGetToken (fm, buf->x);
@@ -178,7 +179,7 @@
value_ret->value_length = value_length;
value_ret->value = (char *) buf;
- return;
+ *value_buf += value_length;
}
#if 0
@@ -186,18 +187,16 @@
char *p,
XICAttr *ic_attr,
int value_length,
- int need_swap)
+ int need_swap,
+ void **value_buf)
{
INT32 list_number;
XIMTriggerKey *hotkeys;
memmove (&list_number, p, sizeof(INT32)); p += sizeof(INT32);
- hotkeys = (XIMTriggerKey *) malloc (list_number*sizeof (XIMTriggerKey));
- if (hotkeys == NULL)
- return;
- /*endif*/
-
+ hotkeys = (XIMTriggerKey *) (*value_buf);
+
memmove (hotkeys, p, list_number*sizeof (XIMTriggerKey));
value_ret->attribute_id = ic_attr->attribute_id;
@@ -206,6 +205,8 @@
value_ret->type = ic_attr->type;
value_ret->value_length = value_length;
value_ret->value = (char *) hotkeys;
+
+ *value_buf += value_length;
}
#endif
@@ -319,7 +320,8 @@
void *p,
XICAttribute *value_ret,
CARD16 *number_ret,
- int need_swap)
+ int need_swap,
+ void **value_buf)
{
XICAttr *ic_attr = i18n_core->address.xic_attr;
int i;
@@ -360,7 +362,8 @@
p1,
(value_ret + ic_len),
&number,
- need_swap);
+ need_swap,
+ value_buf);
ic_len++;
*number_ret += number;
p1 += attribute_length;
@@ -377,28 +380,28 @@
case XimType_CARD16:
case XimType_CARD32:
case XimType_Window:
- SetCardAttribute (value_ret, p, ic_attr, value_length, need_swap);
+ SetCardAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
*number_ret = (CARD16) 1;
return *number_ret;
case XimType_XFontSet:
- SetFontAttribute (value_ret, p, ic_attr, value_length, need_swap);
+ SetFontAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
*number_ret = (CARD16) 1;
return *number_ret;
case XimType_XRectangle:
- SetRectAttribute (value_ret, p, ic_attr, value_length, need_swap);
+ SetRectAttribute (value_ret, p, ic_attr, value_length, need_swap, value_buf);
*number_ret = (CARD16) 1;
return *number_ret;
case XimType_XPoint:
- SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap);
+ SetPointAttribute(value_ret, p, ic_attr, value_length, need_swap, value_buf);
*number_ret = (CARD16) 1;
return *number_ret;
#if 0
case XimType_XIMHotKeyTriggers:
- SetHotKeyAttribute (value_ret, p, ic_attr, value_length, need_swap);
+ SetHotKeyAttribute (value_ret, p, ic_attr, value_length, need_swap,
+value_buf);
*number_ret = (CARD16) 1;
return *number_ret;
#endif
@@ -600,6 +603,11 @@
extern XimFrameRec set_ic_values_fr[];
extern XimFrameRec set_ic_values_reply_fr[];
CARD16 input_method_ID;
+
+ void *value_buf = NULL;
+ void *value_buf_ptr;
+
+ register int total_value_length = 0;
memset (pre_attr, 0, sizeof (XICAttribute)*IC_SIZE);
memset (sts_attr, 0, sizeof (XICAttribute)*IC_SIZE);
@@ -649,9 +657,24 @@
memmove (attrib_list[attrib_num].value, value, value_length);
((char *)attrib_list[attrib_num].value)[value_length] = '\0';
attrib_num++;
+ total_value_length += (value_length + 1);
}
/*endwhile*/
+ value_buf = (void *) malloc (total_value_length);
+ value_buf_ptr = value_buf;
+
+ if (!value_buf)
+ {
+ _Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
+ for (i = 0; i < attrib_num; i++)
+ XFree (attrib_list[i].value);
+ /*endfor*/
+ XFree (attrib_list);
+ return;
+ }
+ /*endif*/
+
for (i = 0; i < attrib_num; i++)
{
CARD16 number;
@@ -667,7 +690,8 @@
attrib_list[i].value,
&pre_attr[preedit_ic_num],
&number,
- _Xi18nNeedSwap(i18n_core, connect_id));
+ _Xi18nNeedSwap(i18n_core, connect_id),
+ &value_buf_ptr);
preedit_ic_num += number;
}
else if (attrib_list[i].attribute_id == i18n_core->address.statusAttr_id)
@@ -678,7 +702,8 @@
attrib_list[i].value,
&sts_attr[status_ic_num],
&number,
- _Xi18nNeedSwap (i18n_core, connect_id));
+ _Xi18nNeedSwap (i18n_core, connect_id),
+ &value_buf_ptr);
status_ic_num += number;
}
else
@@ -695,7 +720,8 @@
attrib_list[i].value,
&ic_attr[ic_num],
&number,
- _Xi18nNeedSwap (i18n_core, connect_id));
+ _Xi18nNeedSwap (i18n_core, connect_id),
+ &value_buf_ptr);
ic_num += number;
}
/*endif*/
@@ -717,10 +743,15 @@
if (i18n_core->address.improto)
{
- if (!(i18n_core->address.improto(ims, call_data)))
+ if (!(i18n_core->address.improto(ims, call_data))) {
+ XFree (value_buf);
return;
+ }
/*endif*/
}
+
+ XFree (value_buf);
+
/*endif*/
if (create_flag == True)
{
@@ -737,6 +768,7 @@
/*endif*/
total_size = FrameMgrGetTotalSize (fm);
reply = (unsigned char *) malloc (total_size);
+
if (!reply)
{
_Xi18nSendMessage (ims, connect_id, XIM_ERROR, 0, 0, 0);
diff -ur IMdkit.old/i18nPtHdr.c IMdkit/i18nPtHdr.c
--- IMdkit.old/i18nPtHdr.c Tue Jul 2 11:56:21 2002
+++ IMdkit/i18nPtHdr.c Sun Nov 3 14:56:17 2002
@@ -622,6 +622,10 @@
/*endfor*/
memmove (buf, data, total_size);
FrameMgrFree (fm);
+
+ /* ADDED BY SUZHE */
+ free (data);
+ /* ADDED BY SUZHE */
}
/*endif*/
}
