PATCH: Memory leak in Clickatell + Brunet HTTP SMSC

2008-07-14 Thread Donald Jackson
Hi everyone,

Attached is a diff for memory leak found in smsc_http.c for Clickatell and
Brunet specific implementations. The message ID Octstr's never get destroyed
when the dictionary gets destroyed.

Thank you!

--
Donald Jackson
http://www.ddj.co.za/
donaldjster(a)gmail.com


smsc_http.c.diff
Description: Binary data


Re: PATCH: Memory leak in Clickatell + Brunet HTTP SMSC

2008-07-14 Thread Stipe Tolj

Donald Jackson schrieb:

Hi everyone,

Attached is a diff for memory leak found in smsc_http.c for Clickatell 
and Brunet specific implementations. The message ID Octstr's never get 
destroyed when the dictionary gets destroyed.


-1 on this patch. Reason: we do a double free() on the Octstr pointers and cause 
a segfault.


The issue is:

  - octstr_split_words() malloc()s the new items in the list.
  - then we inject to Dict the pointer refrence, that's the original, not a 
copy.
  - then we gwlist_destroy() and hence all items of the list are freed, also 
the one we put into the dict.
  - later on we dict_destroy() _WITH_ the octstr_destroy() callback and hence 
we'll try to double free. Bang.


Attached is a revised patch, that takes care we duplicate the items that we put 
into the Dict hash, so we have a clean destruction later, as the 
gwlist_destroy() took care of the original ones.


Please review and vote.

Stipe

---
Kölner Landstrasse 419
40589 Düsseldorf, NRW, Germany

tolj.org system architecture  Kannel Software Foundation (KSF)
http://www.tolj.org/  http://www.kannel.org/

mailto:st_{at}_tolj.org   mailto:stolj_{at}_kannel.org
---
### Eclipse Workspace Patch 1.0
#P gateway-cvs-head
Index: gw/smsc/smsc_http.c
===
RCS file: /home/cvs/gateway/gw/smsc/smsc_http.c,v
retrieving revision 1.56
diff -u -r1.56 smsc_http.c
--- gw/smsc/smsc_http.c 14 Jul 2008 14:50:12 -  1.56
+++ gw/smsc/smsc_http.c 14 Jul 2008 15:09:12 -
@@ -726,16 +726,16 @@
 
 words = octstr_split_words(body);
 if ((len = gwlist_len(words))  1) {
-   word = gwlist_extract_first(words);
-   if (octstr_compare(word, octstr_imm(ID:)) == 0) {
-   value = gwlist_extract_first(words);
-   param = dict_create(4, NULL);
-   dict_put(param, octstr_imm(ID), value);
-   } else if (octstr_compare(word, octstr_imm(ERR:)) == 0) {
-   value = gwlist_extract_first(words);
-   param = dict_create(4, NULL);
-   dict_put(param, octstr_imm(ERR), value);
-   }
+word = gwlist_extract_first(words);
+if (octstr_compare(word, octstr_imm(ID:)) == 0) {
+value = gwlist_extract_first(words);
+param = dict_create(4, (void(*)(void *)) octstr_destroy);
+dict_put(param, octstr_imm(ID), octstr_duplicate(value));
+} else if (octstr_compare(word, octstr_imm(ERR:)) == 0) {
+value = gwlist_extract_first(words);
+param = dict_create(4, (void(*)(void *)) octstr_destroy);
+dict_put(param, octstr_imm(ERR), octstr_duplicate(value));
+}
 octstr_destroy(word);
 }
 gwlist_destroy(words, (void(*)(void *)) octstr_destroy);
@@ -1017,13 +1017,13 @@
 
 words = octstr_split_words(body);
 if ((len = gwlist_len(words))  0) {
-param = dict_create(4, NULL);
+param = dict_create(4, (void(*)(void *)) octstr_destroy);
 while ((word = gwlist_extract_first(words)) != NULL) {
 List *l = octstr_split(word, octstr_imm(=));
 Octstr *key = gwlist_extract_first(l);
 Octstr *value = gwlist_extract_first(l);
 if (octstr_len(key))
-dict_put(param, key, value);
+dict_put(param, key, octstr_duplicate(value));
 octstr_destroy(key);
 octstr_destroy(word);
 gwlist_destroy(l, (void(*)(void *)) octstr_destroy);


RE: PATCH: Memory leak in Clickatell + Brunet HTTP SMSC

2008-07-14 Thread Werner Coetzee

Hi Stipe

I must disagree with you (unfortunately).
If you look closely, you'll see that:
word = gwlist_extract_first(words);
and
value = gwlist_extract_first(words);
is used on the list, (i.e. 2 elements removed from the list), and when 
gwlist_destroy is called, 'word' and 'value' is not destroyed.
There is an octstr_destroy(word), but there is no octstr_destroy(value), and 
because there is no callback for the 'param' dictionary, 'value' never will be 
destroyed, resulting in a memory leak.

The patch you provided creates a copy of 'value' which will be destroyed via 
the callback when dict_destroy is called, but the original 'value' will still 
reside in memory indefinitely.  So I would go for the patch provided by Mr. 
Jackson, or you should add a octstr_destroy(value) to your patch.

Regards



--

Werner Coetzee
*   C Developer: Messaging Engine

*   T +27 21 910 7700
*   F +27 21 910 7701

[EMAIL PROTECTED]
www.clickatell.com




-Original Message-
From: Stipe Tolj [mailto:[EMAIL PROTECTED]
Sent: 14 July 2008 17:13
Cc: devel@kannel.org
Subject: Re: PATCH: Memory leak in Clickatell + Brunet HTTP SMSC

Donald Jackson schrieb:
 Hi everyone,

 Attached is a diff for memory leak found in smsc_http.c for Clickatell
 and Brunet specific implementations. The message ID Octstr's never get
 destroyed when the dictionary gets destroyed.

-1 on this patch. Reason: we do a double free() on the Octstr pointers and cause
a segfault.

The issue is:

   - octstr_split_words() malloc()s the new items in the list.
   - then we inject to Dict the pointer refrence, that's the original, not a 
copy.
   - then we gwlist_destroy() and hence all items of the list are freed, also
the one we put into the dict.
   - later on we dict_destroy() _WITH_ the octstr_destroy() callback and hence
we'll try to double free. Bang.

Attached is a revised patch, that takes care we duplicate the items that we put
into the Dict hash, so we have a clean destruction later, as the
gwlist_destroy() took care of the original ones.

Please review and vote.

Stipe

---
Kölner Landstrasse 419
40589 Düsseldorf, NRW, Germany

tolj.org system architecture  Kannel Software Foundation (KSF)
http://www.tolj.org/  http://www.kannel.org/

mailto:st_{at}_tolj.org   mailto:stolj_{at}_kannel.org
---



Re: PATCH: Memory leak in Clickatell + Brunet HTTP SMSC

2008-07-14 Thread Stipe Tolj

Werner Coetzee schrieb:

Hi Stipe

I must disagree with you (unfortunately).
If you look closely, you'll see that:
word = gwlist_extract_first(words);
and
value = gwlist_extract_first(words);
is used on the list, (i.e. 2 elements removed from the list), and when 
gwlist_destroy is called, 'word' and 'value' is not destroyed.
There is an octstr_destroy(word), but there is no octstr_destroy(value), and 
because there is no callback for the 'param' dictionary, 'value' never will be 
destroyed, resulting in a memory leak.

The patch you provided creates a copy of 'value' which will be destroyed via 
the callback when dict_destroy is called, but the original 'value' will still 
reside in memory indefinitely.  So I would go for the patch provided by Mr. 
Jackson, or you should add a octstr_destroy(value) to your patch.


yup Werner, thanks for the shot here. You're of course right. I wasn't having my 
eyes on the missing octstr_destroy(value) itself. Credits on your eyes here ;)


Stipe

---
Kölner Landstrasse 419
40589 Düsseldorf, NRW, Germany

tolj.org system architecture  Kannel Software Foundation (KSF)
http://www.tolj.org/  http://www.kannel.org/

mailto:st_{at}_tolj.org   mailto:stolj_{at}_kannel.org
---



Re: PATCH: Memory leak in Clickatell + Brunet HTTP SMSC

2008-07-14 Thread Stipe Tolj

Donald Jackson schrieb:

Hi everyone,

Attached is a diff for memory leak found in smsc_http.c for Clickatell 
and Brunet specific implementations. The message ID Octstr's never get 
destroyed when the dictionary gets destroyed.


and after Werner's correction to my mail, +1, and committed to CVS:

2008-07-15  Stipe Tolj  stolj at kannel.org
* gw/smsc/smsc_http.c: memory leak fix for Clickatell and Brunet HTTP API.
  Thanks to Donald Jackson donaldjster at gmail.com for the patch.
  [Msg-Id: [EMAIL PROTECTED]]

Stipe

---
Kölner Landstrasse 419
40589 Düsseldorf, NRW, Germany

tolj.org system architecture  Kannel Software Foundation (KSF)
http://www.tolj.org/  http://www.kannel.org/

mailto:st_{at}_tolj.org   mailto:stolj_{at}_kannel.org
---