SDL: Fixed memory leaks in KMSDRM property handling

From 9ed83e71f6cc445316e1b599aad98fa79019544d Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Sun, 22 Jun 2025 16:26:21 -0700
Subject: [PATCH] Fixed memory leaks in KMSDRM property handling

Also cleaned up the code for consistency so it's easy to see memory leaks here.
---
 src/video/kmsdrm/SDL_kmsdrmvideo.c | 233 +++++++++--------------------
 1 file changed, 72 insertions(+), 161 deletions(-)

diff --git a/src/video/kmsdrm/SDL_kmsdrmvideo.c b/src/video/kmsdrm/SDL_kmsdrmvideo.c
index adca91c9fd04f..257b35d323328 100644
--- a/src/video/kmsdrm/SDL_kmsdrmvideo.c
+++ b/src/video/kmsdrm/SDL_kmsdrmvideo.c
@@ -588,86 +588,49 @@ static void KMSDRM_DeinitDisplays(SDL_VideoDevice *_this)
     }
 }
 
-static uint32_t KMSDRM_CrtcGetPropId(uint32_t drm_fd,
-                                     drmModeObjectPropertiesPtr props,
-                                     char const *name)
+static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd, uint32_t output_id)
 {
-    uint32_t i, prop_id = 0;
-
-    for (i = 0; !prop_id && i < props->count_props; ++i) {
-        drmModePropertyPtr drm_prop =
-            KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
-
-        if (!drm_prop) {
-            continue;
-        }
+    bool found = false;
+    uint64_t prop_value = 0;
 
-        if (SDL_strcmp(drm_prop->name, name) == 0) {
-            prop_id = drm_prop->prop_id;
+    drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, output_id, DRM_MODE_OBJECT_CONNECTOR);
+    if (props) {
+        for (uint32_t i = 0; !found && i < props->count_props; ++i) {
+            drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+            if (prop) {
+                if (SDL_strcasecmp(prop->name, "VRR_CAPABLE") == 0) {
+                    prop_value = props->prop_values[i];
+                    found = true;
+                }
+                KMSDRM_drmModeFreeProperty(prop);
+            }
         }
-
-        KMSDRM_drmModeFreeProperty(drm_prop);
+        KMSDRM_drmModeFreeObjectProperties(props);
     }
-
-    return prop_id;
-}
-
-static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
-{
-    drmModeObjectPropertiesPtr drm_props;
-
-    drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
-                                                  crtc_id,
-                                                  DRM_MODE_OBJECT_CRTC);
-
-    if (!drm_props) {
-        return false;
+    if (found) {
+        return prop_value ? true : false;
     }
-
-    *vrr_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
-                                        drm_props,
-                                        "VRR_ENABLED");
-
-    KMSDRM_drmModeFreeObjectProperties(drm_props);
-
-    return true;
+    return false;
 }
 
-static bool KMSDRM_ConnectorCheckVrrCapable(uint32_t drm_fd,
-                                                uint32_t output_id,
-                                                char const *name)
+static bool KMSDRM_VrrPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *vrr_prop_id)
 {
-    uint32_t i;
     bool found = false;
-    uint64_t prop_value = 0;
-
-    drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd,
-                                                                         output_id,
-                                                                         DRM_MODE_OBJECT_CONNECTOR);
-
-    if (!props) {
-        return false;
-    }
-
-    for (i = 0; !found && i < props->count_props; ++i) {
-        drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
-
-        if (!drm_prop) {
-            continue;
-        }
-
-        if (SDL_strcasecmp(drm_prop->name, name) == 0) {
-            prop_value = props->prop_values[i];
-            found = true;
+    drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
+    if (props) {
+        for (uint32_t i = 0; !found && i < props->count_props; ++i) {
+            drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+            if (prop) {
+                if (SDL_strcmp(prop->name, "VRR_ENABLED") == 0) {
+                    *vrr_prop_id = prop->prop_id;
+                    found = true;
+                }
+                KMSDRM_drmModeFreeProperty(prop);
+            }
         }
-
-        KMSDRM_drmModeFreeProperty(drm_prop);
+        KMSDRM_drmModeFreeObjectProperties(props);
     }
-    if (found) {
-        return prop_value ? true : false;
-    }
-
-    return false;
+    return found;
 }
 
 static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
@@ -677,119 +640,67 @@ static void KMSDRM_CrtcSetVrr(uint32_t drm_fd, uint32_t crtc_id, bool enabled)
         return;
     }
 
-    KMSDRM_drmModeObjectSetProperty(drm_fd,
-                                    crtc_id,
-                                    DRM_MODE_OBJECT_CRTC,
-                                    vrr_prop_id,
-                                    enabled);
+    KMSDRM_drmModeObjectSetProperty(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC, vrr_prop_id, enabled);
 }
 
 static bool KMSDRM_CrtcGetVrr(uint32_t drm_fd, uint32_t crtc_id)
 {
-    uint32_t object_prop_id, vrr_prop_id;
-    drmModeObjectPropertiesPtr props;
-    bool object_prop_value;
-    int i;
+    uint32_t vrr_prop_id = 0;
+    bool found = false;
+    uint64_t prop_value = 0;
 
     if (!KMSDRM_VrrPropId(drm_fd, crtc_id, &vrr_prop_id)) {
         return false;
     }
 
-    props = KMSDRM_drmModeObjectGetProperties(drm_fd,
-                                              crtc_id,
-                                              DRM_MODE_OBJECT_CRTC);
-
-    if (!props) {
-        return false;
-    }
-
-    for (i = 0; i < props->count_props; ++i) {
-        drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
-
-        if (!drm_prop) {
-            continue;
-        }
-
-        object_prop_id = drm_prop->prop_id;
-        object_prop_value = props->prop_values[i] ? true : false;
-
-        KMSDRM_drmModeFreeProperty(drm_prop);
-
-        if (object_prop_id == vrr_prop_id) {
-            return object_prop_value;
+    drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CRTC);
+    if (props) {
+        for (uint32_t i = 0; !found && i < props->count_props; ++i) {
+            drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+            if (prop) {
+                if (prop->prop_id == vrr_prop_id) {
+                    prop_value = props->prop_values[i];
+                    found = true;
+                }
+                KMSDRM_drmModeFreeProperty(prop);
+            }
         }
+        KMSDRM_drmModeFreeObjectProperties(props);
     }
-    return false;
-}
-
-static bool KMSDRM_OrientationPropId(uint32_t drm_fd, uint32_t crtc_id, uint32_t *orientation_prop_id)
-{
-    drmModeObjectPropertiesPtr drm_props;
-
-    drm_props = KMSDRM_drmModeObjectGetProperties(drm_fd,
-                                                  crtc_id,
-                                                  DRM_MODE_OBJECT_CONNECTOR);
-
-    if (!drm_props) {
-        return false;
+    if (found) {
+        return prop_value ? true : false;
     }
-
-    *orientation_prop_id = KMSDRM_CrtcGetPropId(drm_fd,
-                                                drm_props,
-                                                "panel orientation");
-
-    KMSDRM_drmModeFreeObjectProperties(drm_props);
-
-    return true;
+    return false;
 }
 
 static int KMSDRM_CrtcGetOrientation(uint32_t drm_fd, uint32_t crtc_id)
 {
-    uint32_t orientation_prop_id;
-    drmModeObjectPropertiesPtr props;
-    int i;
-    bool done = false;
+    bool found = false;
     int orientation = 0;
 
-    if (!KMSDRM_OrientationPropId(drm_fd, crtc_id, &orientation_prop_id)) {
-        return orientation;
-    }
-
-    props = KMSDRM_drmModeObjectGetProperties(drm_fd,
-                                              crtc_id,
-                                              DRM_MODE_OBJECT_CONNECTOR);
-
-    if (!props) {
-        return orientation;
-    }
-
-    for (i = 0; i < props->count_props && !done; ++i) {
-        drmModePropertyPtr drm_prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
-
-        if (!drm_prop) {
-            continue;
-        }
-
-        if (drm_prop->prop_id == orientation_prop_id && (drm_prop->flags & DRM_MODE_PROP_ENUM)) {
-            if (drm_prop->count_enums) {
-                // "Normal" is the default of no rotation (0 degrees)
-                if (SDL_strcmp(drm_prop->enums[0].name, "Left Side Up") == 0) {
-                    orientation = 90;
-                } else if (SDL_strcmp(drm_prop->enums[0].name, "Upside Down") == 0) {
-                    orientation = 180;
-                } else if (SDL_strcmp(drm_prop->enums[0].name, "Right Side Up") == 0) {
-                    orientation = 270;
+    drmModeObjectPropertiesPtr props = KMSDRM_drmModeObjectGetProperties(drm_fd, crtc_id, DRM_MODE_OBJECT_CONNECTOR);
+    if (props) {
+        for (uint32_t i = 0; !found && i < props->count_props; ++i) {
+            drmModePropertyPtr prop = KMSDRM_drmModeGetProperty(drm_fd, props->props[i]);
+            if (prop) {
+                if (SDL_strcasecmp(prop->name, "panel orientation") == 0 && (prop->flags & DRM_MODE_PROP_ENUM)) {
+                    if (prop->count_enums) {
+                        // "Normal" is the default of no rotation (0 degrees)
+                        if (SDL_strcmp(prop->enums[0].name, "Left Side Up") == 0) {
+                            orientation = 90;
+                        } else if (SDL_strcmp(prop->enums[0].name, "Upside Down") == 0) {
+                            orientation = 180;
+                        } else if (SDL_strcmp(prop->enums[0].name, "Right Side Up") == 0) {
+                            orientation = 270;
+                        }
+                    }
+                    found = true;
                 }
+                KMSDRM_drmModeFreeProperty(prop);
             }
-
-            done = true;
         }
-
-        KMSDRM_drmModeFreeProperty(drm_prop);
+        KMSDRM_drmModeFreeObjectProperties(props);
     }
-
-    KMSDRM_drmModeFreeObjectProperties(props);
-
     return orientation;
 }
 
@@ -964,7 +875,7 @@ static void KMSDRM_AddDisplay(SDL_VideoDevice *_this, drmModeConnector *connecto
     // save previous vrr state
     dispdata->saved_vrr = KMSDRM_CrtcGetVrr(viddata->drm_fd, crtc->crtc_id);
     // try to enable vrr
-    if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id, "VRR_CAPABLE")) {
+    if (KMSDRM_ConnectorCheckVrrCapable(viddata->drm_fd, connector->connector_id)) {
         SDL_LogDebug(SDL_LOG_CATEGORY_VIDEO, "Enabling VRR");
         KMSDRM_CrtcSetVrr(viddata->drm_fd, crtc->crtc_id, true);
     }