lib/hstor.c: avoid an unconditional leak in append_qparam
PATCH 1/1 lib/hstor.c: avoid an unconditional leak in append_qparam
---
I would have preferred to insert a single line right before the huri_field_escape call:
char *v = strdup(val);
[would result in a more compact, single-hunk patch] but it looks like hail uses the anachronistic (pre-C99) "declare all vars at outer scope" style, so I conformed.
lib/hstor.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)
lib/hstor.c +4 -1
@@ -676,6 +676,7 @@ static GString *append_qparam(GString *str, const char *key, const char *val, char *arg_char) {char *stmp; +char *v; str =g_string_append (str, arg_char); arg_char[0 ] ='&' ;
@@ -683,9 +684,11 @@ static GString *append_qparam(GString *str, const char *key, const char *val, str =g_string_append (str, key); str =g_string_append (str,"=" ); - stmp =huri_field_escape (strdup (val),QUERY_ESCAPE_MASK ); + v =strdup (val); + stmp =huri_field_escape (v,QUERY_ESCAPE_MASK ); str =g_string_append (str, stmp);free (stmp); +free (v);return str; }
--
1.7.3.234.g7bba3
lib/hstor.c static GString *append_qparam(GString *str, const char *key, const char *val, · line 691
Quoted 6 lines · On Mon, 27 Sep 2010 10:53:06 +0200 Jim Meyering <[email protected]> wrote:
lib/hstor.c +3
-1- stmp =huri_field_escape (strdup (val),QUERY_ESCAPE_MASK ); + v =strdup (val); + stmp =huri_field_escape (v,QUERY_ESCAPE_MASK ); str =g_string_append (str, stmp);free (stmp); +free (v);
I think you may be fooled by the ridiculous calling convention of huri_field_escape(). It takes a pointer to heap, then either returns its argument, or reallocates it, frees the argument, and returns the reallocated area. It frees with g_free, so it assumes its equivalence with free(), haha.
The end result, it either returns what strdup returned of frees it. Therefore if you free what strudup returned, you double-free it.
I honestly think this madness must stop and huri_field_escape must allocate a new buffer every time. Then we would not need the strdup there at all. It only exists to satisfy the requirement to pass a pointer to heap in case val is a const or whatnot.
-- Pete
Quoted 16 lines · Pete Zaitcev
lib/hstor.c static GString *append_qparam(GString *str, const char *key, const char *val, · line 691
Quoted 6 lines · On Mon, 27 Sep 2010 10:53:06 +0200 Jim Meyering <[email protected]> wrote:
lib/hstor.c +3
-1- stmp =huri_field_escape (strdup (val),QUERY_ESCAPE_MASK ); + v =strdup (val); + stmp =huri_field_escape (v,QUERY_ESCAPE_MASK ); str =g_string_append (str, stmp);free (stmp); +free (v);I think you may be fooled by the ridiculous calling convention of
huri_field_escape(). It takes a pointer to heap, then either returns its argument, or reallocates it, frees the argument, and returns the reallocated area. It frees withg_free, so it assumes its equivalence withfree(), haha.
Quoted 2 lines
The end result, it either returns what strdup returned of frees it. Therefore if you free what strudup returned, you double-free it.
Oh! You're right.
I missed the "g_free (signed_str);"
at the end of huri_field_escape.
Sorry about that.
Quoted 4 lines
I honestly think this madness must stop and
huri_field_escapemust allocate a new buffer every time. Then we would not need the strdup there at all. It only exists to satisfy the requirement to pass a pointer to heap in case val is a const or whatnot.
Making a function like huri_field_escape free a buffer allocated by the caller does seem to violate something fundamental.
Quoted 11 lines · Pete Zaitcev
lib/hstor.c static GString *append_qparam(GString *str, const char *key, const char *val, · line 691
Quoted 6 lines · On Mon, 27 Sep 2010 10:53:06 +0200 Jim Meyering<[email protected]> wrote:
lib/hstor.c +3
-1- stmp =huri_field_escape (strdup (val),QUERY_ESCAPE_MASK ); + v =strdup (val); + stmp =huri_field_escape (v,QUERY_ESCAPE_MASK ); str =g_string_append (str, stmp);free (stmp); +free (v);I think you may be fooled by the ridiculous calling convention
Doh, my memory and I were fooled, too.
Jeff Garzik
AppliedQuoted 29 lines · Jim Meyering
Signed-off-by Jim Meyering<[email protected]>---
I would have preferred to insert a single line right before thehuri_field_escapecall:char *v = strdup(val);[would result in a more compact, single-hunk patch] but it looks like hail uses the anachronistic (pre-C99) "declare all vars at outer scope" style, so I conformed.
lib/hstor.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-)lib/hstor.c +1
-0@@ -676,6 +676,7 @@ static GString *append_qparam(GString *str, const char *key, const char *val, char *arg_char) {char *stmp; +char *v; str =g_string_append (str, arg_char); arg_char[0 ] ='&' ;
lib/hstor.c static GString *append_qparam(GString *str, const char *key, const char *val, · line 692
Quoted 10 lines
lib/hstor.c +3
-1@@ -683,9 +684,11 @@ static GString *append_qparam(GString *str, const char *key, const char *val, str =g_string_append (str, key); str =g_string_append (str,"=" ); - stmp =huri_field_escape (strdup (val),QUERY_ESCAPE_MASK ); + v =strdup (val); + stmp =huri_field_escape (v,QUERY_ESCAPE_MASK ); str =g_string_append (str, stmp);free (stmp); +free (v);
applied
Yeah, I don't like C++ var decls; I think the code gets too disorganized, making it really easy to miss a decl when reviewing.
Jeff
Quoted 8 lines · On Mon, 27 Sep 2010 12:53:48 -0400 Jeff Garzik <[email protected]> wrote:
lib/hstor.c static GString *append_qparam(GString *str, const char *key, const char *val, · line 691
Quoted 6 lines
lib/hstor.c +3
-1- stmp =huri_field_escape (strdup (val),QUERY_ESCAPE_MASK ); + v =strdup (val); + stmp =huri_field_escape (v,QUERY_ESCAPE_MASK ); str =g_string_append (str, stmp);free (stmp); +free (v);applied
I'm going to post a patch that undoes the damage. It's in testing.
-- Pete