From 6021b924655550c1b8f185920452c64665a04cf4 Mon Sep 17 00:00:00 2001 From: "jp.liu" Date: Wed, 14 Feb 2007 15:24:50 +0000 Subject: [PATCH] gst/rtsp/sdpmessage.*: Fix memory management of SDP messages. Fixes #407793. Original commit message from CVS: * gst/rtsp/sdpmessage.c: (sdp_origin_init), (sdp_connection_init), (sdp_bandwidth_init), (sdp_time_init), (sdp_zone_init), (sdp_key_init), (sdp_attribute_init), (sdp_message_init), (sdp_message_uninit), (sdp_message_free), (sdp_media_init), (sdp_media_uninit), (sdp_media_free), (sdp_message_add_media), (sdp_parse_line): * gst/rtsp/sdpmessage.h: Based on patch by: jp.liu Fix memory management of SDP messages. Fixes #407793. --- ChangeLog | 12 +++ gst/rtsp/sdpmessage.c | 234 ++++++++++++++++++++++++++++++++++++++++++-------- gst/rtsp/sdpmessage.h | 10 ++- 3 files changed, 216 insertions(+), 40 deletions(-) diff --git a/ChangeLog b/ChangeLog index 3f51933..809314c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-02-14 Wim Taymans + + * gst/rtsp/sdpmessage.c: (sdp_origin_init), (sdp_connection_init), + (sdp_bandwidth_init), (sdp_time_init), (sdp_zone_init), + (sdp_key_init), (sdp_attribute_init), (sdp_message_init), + (sdp_message_uninit), (sdp_message_free), (sdp_media_init), + (sdp_media_uninit), (sdp_media_free), (sdp_message_add_media), + (sdp_parse_line): + * gst/rtsp/sdpmessage.h: + Based on patch by: jp.liu + Fix memory management of SDP messages. Fixes #407793. + 2007-02-14 Stefan Kost Patch by: zhangfei gao diff --git a/gst/rtsp/sdpmessage.c b/gst/rtsp/sdpmessage.c index 1277bdc..1adc6d7 100644 --- a/gst/rtsp/sdpmessage.c +++ b/gst/rtsp/sdpmessage.c @@ -57,11 +57,15 @@ G_STMT_START { \ } G_STMT_END #define REPLACE_STRING(field,val) FREE_STRING(field);field=g_strdup (val); -#define INIT_ARRAY(field,type) \ -G_STMT_START { \ - if (field) \ - g_array_set_size (field,0); \ - else \ +#define INIT_ARRAY(field,type,init_func) \ +G_STMT_START { \ + if (field) { \ + gint i; \ + for(i=0; ilen; i++) \ + init_func (&g_array_index(field, type, i)); \ + g_array_set_size (field,0); \ + } \ + else \ field = g_array_new (FALSE, TRUE, sizeof(type)); \ } G_STMT_END @@ -95,8 +99,71 @@ RTSPResult sdp_message_add_##method (SDPMessage *msg, type val) { \ return RTSP_OK; \ } +static void +sdp_origin_init (SDPOrigin * origin) +{ + FREE_STRING (origin->username); + FREE_STRING (origin->sess_id); + FREE_STRING (origin->sess_version); + FREE_STRING (origin->nettype); + FREE_STRING (origin->addrtype); + FREE_STRING (origin->addr); +} + +static void +sdp_connection_init (SDPConnection * connection) +{ + FREE_STRING (connection->nettype); + FREE_STRING (connection->addrtype); + FREE_STRING (connection->address); + connection->ttl = 0; + connection->addr_number = 0; +} + +static void +sdp_bandwidth_init (SDPBandwidth * bandwidth) +{ + FREE_STRING (bandwidth->bwtype); + bandwidth->bandwidth = 0; +} + +static void +sdp_time_init (SDPTime * time) +{ + FREE_STRING (time->start); + FREE_STRING (time->stop); + time->n_repeat = 0; +} + +static void +sdp_zone_init (SDPZone * zone) +{ + FREE_STRING (zone->time); + FREE_STRING (zone->typed_time); +} + +static void +sdp_key_init (SDPKey * key) +{ + FREE_STRING (key->type); + FREE_STRING (key->data); +} +static void +sdp_attribute_init (SDPAttribute * attr) +{ + FREE_STRING (attr->key); + FREE_STRING (attr->value); +} +/** + * sdp_message_new: + * @msg: pointer to new #SDPMessage + * + * Allocate a new SDPMessage and store the result in @msg. + * + * Returns: a #RTSPResult. + */ RTSPResult sdp_message_new (SDPMessage ** msg) { @@ -111,44 +178,56 @@ sdp_message_new (SDPMessage ** msg) return sdp_message_init (newmsg); } +/** + * sdp_message_init: + * @msg: an #SDPMessage + * + * Initialize @msg so that its contents are as if it was freshly allocated + * with sdp_message_new(). This function is mostly used to initialize a message + * allocated on the stack. sdp_message_uninit() undoes this operation. + * + * Returns: a #RTSPResult. + */ RTSPResult sdp_message_init (SDPMessage * msg) { g_return_val_if_fail (msg != NULL, RTSP_EINVAL); FREE_STRING (msg->version); - FREE_STRING (msg->origin.username); - FREE_STRING (msg->origin.sess_id); - FREE_STRING (msg->origin.sess_version); - FREE_STRING (msg->origin.nettype); - FREE_STRING (msg->origin.addrtype); - FREE_STRING (msg->origin.addr); + sdp_origin_init (&msg->origin); FREE_STRING (msg->session_name); FREE_STRING (msg->information); FREE_STRING (msg->uri); - INIT_ARRAY (msg->emails, gchar *); - INIT_ARRAY (msg->phones, gchar *); - FREE_STRING (msg->connection.nettype); - FREE_STRING (msg->connection.addrtype); - FREE_STRING (msg->connection.address); - msg->connection.ttl = 0; - msg->connection.addr_number = 0; - INIT_ARRAY (msg->bandwidths, SDPBandwidth); - INIT_ARRAY (msg->times, SDPTime); - INIT_ARRAY (msg->zones, SDPZone); - FREE_STRING (msg->key.type); - FREE_STRING (msg->key.data); - INIT_ARRAY (msg->attributes, SDPAttribute); - INIT_ARRAY (msg->medias, SDPMedia); + INIT_ARRAY (msg->emails, gchar *, g_free); + INIT_ARRAY (msg->phones, gchar *, g_free); + sdp_connection_init (&msg->connection); + INIT_ARRAY (msg->bandwidths, SDPBandwidth, sdp_bandwidth_init); + INIT_ARRAY (msg->times, SDPTime, sdp_time_init); + INIT_ARRAY (msg->zones, SDPZone, sdp_zone_init); + sdp_key_init (&msg->key); + INIT_ARRAY (msg->attributes, SDPAttribute, sdp_attribute_init); + INIT_ARRAY (msg->medias, SDPMedia, sdp_media_uninit); return RTSP_OK; } +/** + * sdp_message_uninit: + * @msg: an #SDPMessage + * + * Free all resources allocated in @msg. @msg should not be used anymore after + * this function. This function should be used when @msg was allocated on the + * stack and initialized with sdp_message_init(). + * + * Returns: a #RTSPResult. + */ RTSPResult -sdp_message_clean (SDPMessage * msg) +sdp_message_uninit (SDPMessage * msg) { g_return_val_if_fail (msg != NULL, RTSP_EINVAL); + sdp_message_init (msg); + FREE_ARRAY (msg->emails); FREE_ARRAY (msg->phones); FREE_ARRAY (msg->bandwidths); @@ -160,19 +239,35 @@ sdp_message_clean (SDPMessage * msg) return RTSP_OK; } +/** + * sdp_message_free: + * @msg: an #SDPMessage + * + * Free all resources allocated by @msg. @msg should not be used anymore after + * this function. This function should be used when @msg was dynamically + * allocated with sdp_message_new(). + * + * Returns: a #RTSPResult. + */ RTSPResult sdp_message_free (SDPMessage * msg) { g_return_val_if_fail (msg != NULL, RTSP_EINVAL); - sdp_message_clean (msg); - + sdp_message_uninit (msg); g_free (msg); return RTSP_OK; } - +/** + * sdp_media_new: + * @media: pointer to new #SDPMedia + * + * Allocate a new SDPMedia and store the result in @media. + * + * Returns: a #RTSPResult. + */ RTSPResult sdp_media_new (SDPMedia ** media) { @@ -187,6 +282,16 @@ sdp_media_new (SDPMedia ** media) return sdp_media_init (newmedia); } +/** + * sdp_media_init: + * @media: a #SDPMedia + * + * Initialize @media so that its contents are as if it was freshly allocated + * with sdp_media_new(). This function is mostly used to initialize a media + * allocated on the stack. sdp_media_uninit() undoes this operation. + * + * Returns: a #RTSPResult. + */ RTSPResult sdp_media_init (SDPMedia * media) { @@ -196,13 +301,57 @@ sdp_media_init (SDPMedia * media) media->port = 0; media->num_ports = 0; FREE_STRING (media->proto); - INIT_ARRAY (media->fmts, gchar *); + INIT_ARRAY (media->fmts, gchar *, g_free); FREE_STRING (media->information); - INIT_ARRAY (media->connections, SDPConnection); - INIT_ARRAY (media->bandwidths, SDPBandwidth); - FREE_STRING (media->key.type); - FREE_STRING (media->key.data); - INIT_ARRAY (media->attributes, SDPAttribute); + INIT_ARRAY (media->connections, SDPConnection, sdp_connection_init); + INIT_ARRAY (media->bandwidths, SDPBandwidth, sdp_bandwidth_init); + sdp_key_init (&media->key); + INIT_ARRAY (media->attributes, SDPAttribute, sdp_attribute_init); + + return RTSP_OK; +} + +/** + * sdp_media_uninit: + * @media: an #SDPMedia + * + * Free all resources allocated in @media. @media should not be used anymore after + * this function. This function should be used when @media was allocated on the + * stack and initialized with sdp_media_init(). + * + * Returns: a #RTSPResult. + */ +RTSPResult +sdp_media_uninit (SDPMedia * media) +{ + g_return_val_if_fail (media != NULL, RTSP_EINVAL); + + sdp_media_init (media); + FREE_ARRAY (media->fmts); + FREE_ARRAY (media->connections); + FREE_ARRAY (media->bandwidths); + FREE_ARRAY (media->attributes); + + return RTSP_OK; +} + +/** + * sdp_media_free: + * @media: an #SDPMedia + * + * Free all resources allocated by @media. @media should not be used anymore after + * this function. This function should be used when @media was dynamically + * allocated with sdp_media_new(). + * + * Returns: a #RTSPResult. + */ +RTSPResult +sdp_media_free (SDPMedia * media) +{ + g_return_val_if_fail (media != NULL, RTSP_EINVAL); + + sdp_media_uninit (media); + g_free (media); return RTSP_OK; } @@ -359,6 +508,18 @@ sdp_message_add_attribute (SDPMessage * msg, gchar * key, gchar * value) DEFINE_ARRAY_LEN (medias); DEFINE_ARRAY_P_GETTER (media, medias, SDPMedia); + +/** + * sdp_message_add_media: + * @msg: an #SDPMessage + * @media: an #SDPMedia to add + * + * Adds @media to the array of medias in @msg. This function takes ownership of + * the contents of @media so that @media will have to be reinitialized with + * gst_media_init() before it can be used again. + * + * Returns: an #RTSPResult. + */ RTSPResult sdp_message_add_media (SDPMessage * msg, SDPMedia * media) { @@ -370,6 +531,7 @@ sdp_message_add_media (SDPMessage * msg, SDPMedia * media) nmedia = &g_array_index (msg->medias, SDPMedia, len); memcpy (nmedia, media, sizeof (SDPMedia)); + memset (media, 0, sizeof (SDPMedia)); return RTSP_OK; } @@ -584,8 +746,6 @@ sdp_parse_line (SDPContext * c, gchar type, gchar * buffer) gchar *slash; SDPMedia nmedia; - nmedia.media = NULL; - c->state = SDP_MEDIA; sdp_media_init (&nmedia); diff --git a/gst/rtsp/sdpmessage.h b/gst/rtsp/sdpmessage.h index 97014bc..93bf080 100644 --- a/gst/rtsp/sdpmessage.h +++ b/gst/rtsp/sdpmessage.h @@ -130,7 +130,7 @@ typedef struct { /* Session descriptions */ RTSPResult sdp_message_new (SDPMessage **msg); RTSPResult sdp_message_init (SDPMessage *msg); -RTSPResult sdp_message_clean (SDPMessage *msg); +RTSPResult sdp_message_uninit (SDPMessage *msg); RTSPResult sdp_message_free (SDPMessage *msg); RTSPResult sdp_message_parse_buffer (guint8 *data, guint size, SDPMessage *msg); @@ -182,14 +182,18 @@ RTSPResult sdp_message_dump (SDPMessage *msg); /* Media descriptions */ RTSPResult sdp_media_new (SDPMedia **media); RTSPResult sdp_media_init (SDPMedia *media); -RTSPResult sdp_media_clean (SDPMedia *media); +RTSPResult sdp_media_uninit (SDPMedia *media); RTSPResult sdp_media_free (SDPMedia *media); +RTSPResult sdp_media_add_bandwidth (SDPMedia * media, gchar * bwtype, gint bandwidth); + +RTSPResult sdp_media_add_attribute (SDPMedia *media, gchar * key, gchar * value); SDPAttribute * sdp_media_get_attribute (SDPMedia *media, guint idx); gchar* sdp_media_get_attribute_val (SDPMedia *media, gchar *key); gchar* sdp_media_get_attribute_val_n (SDPMedia *media, gchar *key, guint nth); -gchar* sdp_media_get_format (SDPMedia *media, guint idx); +RTSPResult sdp_media_add_format (SDPMedia * media, gchar * format); +gchar* sdp_media_get_format (SDPMedia *media, guint idx); G_END_DECLS -- 2.7.4