Commit 4ada14a267a9cfa4a917dad52e6d3c1dd7d7b47c

meyraud705 2021-07-21T13:39:10

Replace libc functions to SDL equivalent in wayland video subsystem Wayland video subsystem uses a mix of libc and SDL function. This patch switches libc functions to SDL ones and fixes a mismatch in memory allocation/dealoccation of SDL_Cursor in SDL_waylandmouse.c (calloc on line 201 and SDL_free on line 313) which caused memory corruption if custom memory allocator where provided to SDL.

diff --git a/src/video/wayland/SDL_waylanddatamanager.c b/src/video/wayland/SDL_waylanddatamanager.c
index dc444ff..c1098ab 100644
--- a/src/video/wayland/SDL_waylanddatamanager.c
+++ b/src/video/wayland/SDL_waylanddatamanager.c
@@ -157,7 +157,7 @@ Wayland_convert_mime_type(const char *mime_type)
     size_t index = 0;
 
     for (index = 0; index < MIME_LIST_SIZE; ++index) {
-        if (strcmp(mime_conversion_list[index][0], mime_type) == 0) {
+        if (SDL_strcmp(mime_conversion_list[index][0], mime_type) == 0) {
             found = mime_conversion_list[index][1];
             break;
         }
@@ -174,7 +174,7 @@ mime_data_list_find(struct wl_list* list,
 
     SDL_MimeDataList *mime_list = NULL;
     wl_list_for_each(mime_list, list, link) { 
-        if (strcmp(mime_list->mime_type, mime_type) == 0) {
+        if (SDL_strcmp(mime_list->mime_type, mime_type) == 0) {
             found = mime_list;
             break;
         }
@@ -426,7 +426,7 @@ Wayland_data_device_set_selection(SDL_WaylandDataDevice *data_device,
 
             /* TODO - Improve system for multiple mime types to same data */
             for (index = 0; index < MIME_LIST_SIZE; ++index) {
-                if (strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) {
+                if (SDL_strcmp(mime_conversion_list[index][1], mime_data->mime_type) == 0) {
                     wl_data_source_offer(source->source,
                                          mime_conversion_list[index][0]);
                }
diff --git a/src/video/wayland/SDL_waylandevents.c b/src/video/wayland/SDL_waylandevents.c
index ec288ca..d70c31c 100644
--- a/src/video/wayland/SDL_waylandevents.c
+++ b/src/video/wayland/SDL_waylandevents.c
@@ -202,7 +202,7 @@ keyboard_repeat_set(SDL_WaylandKeyboardRepeat* repeat_info,
     repeat_info->next_repeat_ms = SDL_GetTicks() + repeat_info->repeat_delay;
     repeat_info->scancode = scancode;
     if (has_text) {
-        memcpy(repeat_info->text, text, 8);
+        SDL_memcpy(repeat_info->text, text, 8);
     } else {
         repeat_info->text[0] = '\0';
     }
@@ -528,7 +528,7 @@ pointer_handle_frame(void *data, struct wl_pointer *pointer)
         y = input->pointer_curr_axis_info.y / WAYLAND_WHEEL_AXIS_UNIT;
 
     /* clear pointer_curr_axis_info for next frame */
-    memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
+    SDL_memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
 
     if(x == 0.0f && y == 0.0f)
         return;
@@ -929,7 +929,7 @@ seat_handle_capabilities(void *data, struct wl_seat *seat,
 
     if ((caps & WL_SEAT_CAPABILITY_POINTER) && !input->pointer) {
         input->pointer = wl_seat_get_pointer(seat);
-        memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
+        SDL_memset(&input->pointer_curr_axis_info, 0, sizeof input->pointer_curr_axis_info);
         input->display->pointer = input->pointer;
         wl_pointer_set_user_data(input->pointer, input);
         wl_pointer_add_listener(input->pointer, &pointer_listener,
diff --git a/src/video/wayland/SDL_waylandmouse.c b/src/video/wayland/SDL_waylandmouse.c
index bf0ede0..a9da55e 100644
--- a/src/video/wayland/SDL_waylandmouse.c
+++ b/src/video/wayland/SDL_waylandmouse.c
@@ -27,7 +27,6 @@
 #include <sys/mman.h>
 #include <fcntl.h>
 #include <unistd.h>
-#include <stdlib.h>
 #include <limits.h>
 
 #include "../SDL_sysvideo.h"
@@ -148,14 +147,14 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
 {
     SDL_Cursor *cursor;
 
-    cursor = calloc(1, sizeof (*cursor));
+    cursor = SDL_calloc(1, sizeof (*cursor));
     if (cursor) {
         SDL_VideoDevice *vd = SDL_GetVideoDevice ();
         SDL_VideoData *wd = (SDL_VideoData *) vd->driverdata;
-        Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
+        Wayland_CursorData *data = SDL_calloc (1, sizeof (Wayland_CursorData));
         if (!data) {
             SDL_OutOfMemory();
-            free(cursor);
+            SDL_free(cursor);
             return NULL;
         }
         cursor->driverdata = (void *) data;
@@ -170,8 +169,8 @@ Wayland_CreateCursor(SDL_Surface *surface, int hot_x, int hot_y)
                                     surface->h,
                                     WL_SHM_FORMAT_ARGB8888) < 0)
         {
-            free (cursor->driverdata);
-            free (cursor);
+            SDL_free (cursor->driverdata);
+            SDL_free (cursor);
             return NULL;
         }
 
@@ -198,12 +197,12 @@ CreateCursorFromWlCursor(SDL_VideoData *d, struct wl_cursor *wlcursor)
 {
     SDL_Cursor *cursor;
 
-    cursor = calloc(1, sizeof (*cursor));
+    cursor = SDL_calloc(1, sizeof (*cursor));
     if (cursor) {
-        Wayland_CursorData *data = calloc (1, sizeof (Wayland_CursorData));
+        Wayland_CursorData *data = SDL_calloc (1, sizeof (Wayland_CursorData));
         if (!data) {
             SDL_OutOfMemory();
-            free(cursor);
+            SDL_free(cursor);
             return NULL;
         }
         cursor->driverdata = (void *) data;
@@ -309,7 +308,7 @@ Wayland_FreeCursor(SDL_Cursor *cursor)
         wl_surface_destroy(d->surface);
 
     /* Not sure what's meant to happen to shm_data */
-    free (cursor->driverdata);
+    SDL_free (cursor->driverdata);
     SDL_free(cursor);
 }
 
diff --git a/src/video/wayland/SDL_waylandvideo.c b/src/video/wayland/SDL_waylandvideo.c
index 7503d81..44b2163 100644
--- a/src/video/wayland/SDL_waylandvideo.c
+++ b/src/video/wayland/SDL_waylandvideo.c
@@ -441,45 +441,45 @@ display_handle_global(void *data, struct wl_registry *registry, uint32_t id,
 
     /*printf("WAYLAND INTERFACE: %s\n", interface);*/
 
-    if (strcmp(interface, "wl_compositor") == 0) {
+    if (SDL_strcmp(interface, "wl_compositor") == 0) {
         d->compositor = wl_registry_bind(d->registry, id, &wl_compositor_interface, SDL_min(3, version));
-    } else if (strcmp(interface, "wl_output") == 0) {
+    } else if (SDL_strcmp(interface, "wl_output") == 0) {
         Wayland_add_display(d, id);
-    } else if (strcmp(interface, "wl_seat") == 0) {
+    } else if (SDL_strcmp(interface, "wl_seat") == 0) {
         Wayland_display_add_input(d, id, version);
-    } else if (strcmp(interface, "xdg_wm_base") == 0) {
+    } else if (SDL_strcmp(interface, "xdg_wm_base") == 0) {
         d->shell.xdg = wl_registry_bind(d->registry, id, &xdg_wm_base_interface, 1);
         xdg_wm_base_add_listener(d->shell.xdg, &shell_listener_xdg, NULL);
-    } else if (strcmp(interface, "zxdg_shell_v6") == 0) {
+    } else if (SDL_strcmp(interface, "zxdg_shell_v6") == 0) {
         d->shell.zxdg = wl_registry_bind(d->registry, id, &zxdg_shell_v6_interface, 1);
         zxdg_shell_v6_add_listener(d->shell.zxdg, &shell_listener_zxdg, NULL);
-    } else if (strcmp(interface, "wl_shell") == 0) {
+    } else if (SDL_strcmp(interface, "wl_shell") == 0) {
         d->shell.wl = wl_registry_bind(d->registry, id, &wl_shell_interface, 1);
-    } else if (strcmp(interface, "wl_shm") == 0) {
+    } else if (SDL_strcmp(interface, "wl_shm") == 0) {
         d->shm = wl_registry_bind(registry, id, &wl_shm_interface, 1);
         d->cursor_theme = WAYLAND_wl_cursor_theme_load(NULL, 32, d->shm);
-    } else if (strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
+    } else if (SDL_strcmp(interface, "zwp_relative_pointer_manager_v1") == 0) {
         Wayland_display_add_relative_pointer_manager(d, id);
-    } else if (strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
+    } else if (SDL_strcmp(interface, "zwp_pointer_constraints_v1") == 0) {
         Wayland_display_add_pointer_constraints(d, id);
-    } else if (strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) {
+    } else if (SDL_strcmp(interface, "zwp_keyboard_shortcuts_inhibit_manager_v1") == 0) {
         d->key_inhibitor_manager = wl_registry_bind(d->registry, id, &zwp_keyboard_shortcuts_inhibit_manager_v1_interface, 1);
-    } else if (strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
+    } else if (SDL_strcmp(interface, "zwp_idle_inhibit_manager_v1") == 0) {
         d->idle_inhibit_manager = wl_registry_bind(d->registry, id, &zwp_idle_inhibit_manager_v1_interface, 1);
-    } else if (strcmp(interface, "xdg_activation_v1") == 0) {
+    } else if (SDL_strcmp(interface, "xdg_activation_v1") == 0) {
         d->activation_manager = wl_registry_bind(d->registry, id, &xdg_activation_v1_interface, 1);
-    } else if (strcmp(interface, "wl_data_device_manager") == 0) {
+    } else if (SDL_strcmp(interface, "wl_data_device_manager") == 0) {
         Wayland_add_data_device_manager(d, id, version);
-    } else if (strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
+    } else if (SDL_strcmp(interface, "zxdg_decoration_manager_v1") == 0) {
         d->decoration_manager = wl_registry_bind(d->registry, id, &zxdg_decoration_manager_v1_interface, 1);
 
 #ifdef SDL_VIDEO_DRIVER_WAYLAND_QT_TOUCH
-    } else if (strcmp(interface, "qt_touch_extension") == 0) {
+    } else if (SDL_strcmp(interface, "qt_touch_extension") == 0) {
         Wayland_touch_create(d, id);
-    } else if (strcmp(interface, "qt_surface_extension") == 0) {
+    } else if (SDL_strcmp(interface, "qt_surface_extension") == 0) {
         d->surface_extension = wl_registry_bind(registry, id,
                 &qt_surface_extension_interface, 1);
-    } else if (strcmp(interface, "qt_windowmanager") == 0) {
+    } else if (SDL_strcmp(interface, "qt_windowmanager") == 0) {
         d->windowmanager = wl_registry_bind(registry, id,
                 &qt_windowmanager_interface, 1);
         qt_windowmanager_add_listener(d->windowmanager, &windowmanager_listener, d);
diff --git a/src/video/wayland/SDL_waylandwindow.c b/src/video/wayland/SDL_waylandwindow.c
index cf65a50..0d51b22 100644
--- a/src/video/wayland/SDL_waylandwindow.c
+++ b/src/video/wayland/SDL_waylandwindow.c
@@ -941,44 +941,44 @@ QtExtendedSurface_OnHintChanged(void *userdata, const char *name,
         return;
     }
 
-    if (strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) {
+    if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_CONTENT_ORIENTATION) == 0) {
         int32_t orientation = QT_EXTENDED_SURFACE_ORIENTATION_PRIMARYORIENTATION;
 
         if (newValue != NULL) {
-            if (strcmp(newValue, "portrait") == 0) {
+            if (SDL_strcmp(newValue, "portrait") == 0) {
                 orientation = QT_EXTENDED_SURFACE_ORIENTATION_PORTRAITORIENTATION;
-            } else if (strcmp(newValue, "landscape") == 0) {
+            } else if (SDL_strcmp(newValue, "landscape") == 0) {
                 orientation = QT_EXTENDED_SURFACE_ORIENTATION_LANDSCAPEORIENTATION;
-            } else if (strcmp(newValue, "inverted-portrait") == 0) {
+            } else if (SDL_strcmp(newValue, "inverted-portrait") == 0) {
                 orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDPORTRAITORIENTATION;
-            } else if (strcmp(newValue, "inverted-landscape") == 0) {
+            } else if (SDL_strcmp(newValue, "inverted-landscape") == 0) {
                 orientation = QT_EXTENDED_SURFACE_ORIENTATION_INVERTEDLANDSCAPEORIENTATION;
             }
         }
 
         qt_extended_surface_set_content_orientation(qt_extended_surface, orientation);
-    } else if (strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) {
+    } else if (SDL_strcmp(name, SDL_HINT_QTWAYLAND_WINDOW_FLAGS) == 0) {
         uint32_t flags = 0;
 
         if (newValue != NULL) {
-            char *tmp = strdup(newValue);
+            char *tmp = SDL_strdup(newValue);
             char *saveptr = NULL;
 
-            char *flag = strtok_r(tmp, " ", &saveptr);
+            char *flag = SDL_strtokr(tmp, " ", &saveptr);
             while (flag) {
-                if (strcmp(flag, "OverridesSystemGestures") == 0) {
+                if (SDL_strcmp(flag, "OverridesSystemGestures") == 0) {
                     flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_OVERRIDESSYSTEMGESTURES;
-                } else if (strcmp(flag, "StaysOnTop") == 0) {
+                } else if (SDL_strcmp(flag, "StaysOnTop") == 0) {
                     flags |= QT_EXTENDED_SURFACE_WINDOWFLAG_STAYSONTOP;
-                } else if (strcmp(flag, "BypassWindowManager") == 0) {
+                } else if (SDL_strcmp(flag, "BypassWindowManager") == 0) {
                     // See https://github.com/qtproject/qtwayland/commit/fb4267103d
                     flags |= 4 /* QT_EXTENDED_SURFACE_WINDOWFLAG_BYPASSWINDOWMANAGER */;
                 }
 
-                flag = strtok_r(NULL, " ", &saveptr);
+                flag = SDL_strtokr(NULL, " ", &saveptr);
             }
 
-            free(tmp);
+            SDL_free(tmp);
         }
 
         qt_extended_surface_set_window_flags(qt_extended_surface, flags);