Blob Blame History Raw
From f70261f80302d9f4ffd62f9dbae3d515b5778467 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= <mail@3v1n0.net>
Date: Sun, 21 Jul 2019 18:18:14 +0200
Subject: [PATCH 18/28] monitor-config-manager: Always free temporary region on
 error

During the config parsing we are allocating a temporary rectangles region
however in case that we find an error we return prematurely but in some cases
(when not using identical global scale, or when not using adjacent neighbors)
we didn't free the region list before.

Instead of caring of doing this manually everytime, let's just use an
auto-pointer to manage the region lifecycle.

https://gitlab.gnome.org/GNOME/mutter/merge_requests/682
---
 src/backends/meta-monitor-config-manager.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/src/backends/meta-monitor-config-manager.c b/src/backends/meta-monitor-config-manager.c
index cb67e11e7..59a20d449 100644
--- a/src/backends/meta-monitor-config-manager.c
+++ b/src/backends/meta-monitor-config-manager.c
@@ -1578,134 +1578,129 @@ meta_logical_monitor_configs_have_monitor (GList           *logical_monitor_conf
     {
       MetaLogicalMonitorConfig *logical_monitor_config = l->data;
       GList *k;
 
       for (k = logical_monitor_config->monitor_configs; k; k = k->next)
         {
           MetaMonitorConfig *monitor_config = k->data;
 
           if (meta_monitor_spec_equals (monitor_spec,
                                         monitor_config->monitor_spec))
             return TRUE;
         }
     }
 
   return FALSE;
 }
 
 static gboolean
 meta_monitors_config_is_monitor_enabled (MetaMonitorsConfig *config,
                                          MetaMonitorSpec    *monitor_spec)
 {
   return meta_logical_monitor_configs_have_monitor (config->logical_monitor_configs,
                                                     monitor_spec);
 }
 
 gboolean
 meta_verify_monitors_config (MetaMonitorsConfig *config,
                              MetaMonitorManager *monitor_manager,
                              GError            **error)
 {
+  g_autoptr (GList) region = NULL;
   int min_x, min_y;
   gboolean has_primary;
-  GList *region;
   GList *l;
   gboolean global_scale_required;
 
   if (!config->logical_monitor_configs)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "Monitors config incomplete");
       return FALSE;
     }
 
   global_scale_required =
     !!(meta_monitor_manager_get_capabilities (monitor_manager) &
        META_MONITOR_MANAGER_CAPABILITY_GLOBAL_SCALE_REQUIRED);
 
   min_x = INT_MAX;
   min_y = INT_MAX;
-  region = NULL;
   has_primary = FALSE;
   for (l = config->logical_monitor_configs; l; l = l->next)
     {
       MetaLogicalMonitorConfig *logical_monitor_config = l->data;
 
       if (global_scale_required)
         {
           MetaLogicalMonitorConfig *prev_logical_monitor_config =
             l->prev ? l->prev->data : NULL;
 
           if (prev_logical_monitor_config &&
               (prev_logical_monitor_config->scale !=
                logical_monitor_config->scale))
             {
               g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                            "Logical monitor scales must be identical");
               return FALSE;
             }
         }
 
       if (meta_rectangle_overlaps_with_region (region,
                                                &logical_monitor_config->layout))
         {
-          g_list_free (region);
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Logical monitors overlap");
           return FALSE;
         }
 
       if (has_primary && logical_monitor_config->is_primary)
         {
-          g_list_free (region);
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Config contains multiple primary logical monitors");
           return FALSE;
         }
       else if (logical_monitor_config->is_primary)
         {
           has_primary = TRUE;
         }
 
       if (!has_adjecent_neighbour (config, logical_monitor_config))
         {
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Logical monitors not adjecent");
           return FALSE;
         }
 
       min_x = MIN (logical_monitor_config->layout.x, min_x);
       min_y = MIN (logical_monitor_config->layout.y, min_y);
 
       region = g_list_prepend (region, &logical_monitor_config->layout);
     }
 
-  g_list_free (region);
-
   for (l = config->disabled_monitor_specs; l; l = l->next)
     {
       MetaMonitorSpec *monitor_spec = l->data;
 
       if (meta_monitors_config_is_monitor_enabled (config, monitor_spec))
         {
           g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                        "Assigned monitor explicitly disabled");
           return FALSE;
         }
     }
 
   if (min_x != 0 || min_y != 0)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "Logical monitors positions are offset");
       return FALSE;
     }
 
   if (!has_primary)
     {
       g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
                    "Config is missing primary logical");
       return FALSE;
     }
 
   return TRUE;
 }
-- 
2.26.2