gst/rtsp/sdpmessage.*: Fix memory management of SDP messages. Fixes #407793.
authorjp.liu <jp_liu@astrocom.cn>
Wed, 14 Feb 2007 15:24:50 +0000 (15:24 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 14 Feb 2007 15:24:50 +0000 (15:24 +0000)
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 <jp_liu at astrocom dot cn>
Fix memory management of SDP messages. Fixes #407793.

ChangeLog
gst/rtsp/sdpmessage.c
gst/rtsp/sdpmessage.h

index 3f51933..809314c 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2007-02-14  Wim Taymans  <wim@fluendo.com>
+
+       * 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 <jp_liu at astrocom dot cn>
+       Fix memory management of SDP messages. Fixes #407793.
+
 2007-02-14  Stefan Kost  <ensonic@users.sf.net>
 
        Patch by: zhangfei gao <gaozhangfei@yahoo.com.cn>
index 1277bdc..1adc6d7 100644 (file)
@@ -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; i<field->len; 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);
 
index 97014bc..93bf080 100644 (file)
@@ -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