avcfg: Don't leak the support GArray when registering flag/enums
authorEdward Hervey <edward@centricular.com>
Sat, 12 Nov 2022 08:53:14 +0000 (09:53 +0100)
committerEdward Hervey <bilboed@bilboed.com>
Sun, 13 Nov 2022 05:59:11 +0000 (06:59 +0100)
* Only create it if we are attempting to put values in it
* If we sucessfully registered the values, only free the GArray
* IF we didn't, also free the backing memory

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/3390>

subprojects/gst-libav/ext/libav/gstavcfg.c

index fc8c19c..d3deb12 100644 (file)
@@ -89,7 +89,7 @@ register_enum (const AVClass ** obj, const AVOption * top_opt)
 {
   const AVOption *opt = NULL;
   GType res = 0;
-  GArray *values = g_array_new (TRUE, TRUE, sizeof (GEnumValue));
+  GArray *values;
   gchar *lower_obj_name = g_ascii_strdown ((*obj)->class_name, -1);
   gchar *enum_name = g_strdup_printf ("%s-%s", lower_obj_name, top_opt->unit);
   gboolean none_default = TRUE;
@@ -108,6 +108,8 @@ register_enum (const AVClass ** obj, const AVOption * top_opt)
   if ((res = g_type_from_name (enum_name_strip)))
     goto done;
 
+  values = g_array_new (TRUE, TRUE, sizeof (GEnumValue));
+
   while ((opt = av_opt_next (obj, opt))) {
     if (opt->type == AV_OPT_TYPE_CONST && !g_strcmp0 (top_opt->unit, opt->unit)) {
       GEnumValue val;
@@ -169,6 +171,10 @@ register_enum (const AVClass ** obj, const AVOption * top_opt)
         &g_array_index (values, GEnumValue, 0));
 
     gst_type_mark_as_plugin_api (res, 0);
+
+    g_array_free (values, FALSE);
+  } else {
+    g_array_free (values, TRUE);
   }
 
 done:
@@ -190,7 +196,7 @@ register_flags (const AVClass ** obj, const AVOption * top_opt)
 {
   const AVOption *opt = NULL;
   GType res = 0;
-  GArray *values = g_array_new (TRUE, TRUE, sizeof (GEnumValue));
+  GArray *values;
   gchar *lower_obj_name = g_ascii_strdown ((*obj)->class_name, -1);
   gchar *flags_name = g_strdup_printf ("%s-%s", lower_obj_name, top_opt->unit);
   const gchar *flags_name_strip;
@@ -208,6 +214,8 @@ register_flags (const AVClass ** obj, const AVOption * top_opt)
   if ((res = g_type_from_name (flags_name_strip)))
     goto done;
 
+  values = g_array_new (TRUE, TRUE, sizeof (GFlagsValue));
+
   while ((opt = av_opt_next (obj, opt))) {
     if (opt->type == AV_OPT_TYPE_CONST && !g_strcmp0 (top_opt->unit, opt->unit)) {
       GFlagsValue val;
@@ -240,7 +248,9 @@ register_flags (const AVClass ** obj, const AVOption * top_opt)
             GFlagsValue, 0));
 
     gst_type_mark_as_plugin_api (res, 0);
-  }
+    g_array_free (values, FALSE);
+  } else
+    g_array_free (values, TRUE);
 
 done:
   g_free (lower_obj_name);