Browse Source

Add trailing path separator to SDL_GetUserFolder()

Semphris 11 months ago
parent
commit
b9d3d746a0

+ 3 - 0
include/SDL3/SDL_filesystem.h

@@ -224,6 +224,9 @@ typedef enum SDL_Folder
  * Note that the function is expensive, and should be called once at the
  * beginning of the execution and kept for as long as needed.
  *
+ * The returned path is guaranteed to end with a path separator ('\\' on
+ * Windows, '/' on most other platforms).
+ *
  * The returned value is owned by the caller and should be freed with
  * SDL_free().
  *

+ 7 - 2
src/filesystem/cocoa/SDL_sysfilesystem.m

@@ -209,11 +209,17 @@ char *SDL_GetUserFolder(SDL_Folder folder)
             return NULL;
         }
 
-        retval = SDL_strdup(base);
+        retval = SDL_malloc(SDL_strlen(base) + 2);
         if (retval == NULL) {
             return NULL;
         }
 
+        if (SDL_snprintf(retval, SDL_strlen(base) + 2, "%s/", base) < 0) {
+            SDL_SetError("Couldn't snprintf folder path for Cocoa: %s", base);
+            SDL_free(retval);
+            return NULL;
+        }
+
         for (ptr = retval + 1; *ptr; ptr++) {
             if (*ptr == '/') {
                 *ptr = '\0';
@@ -221,7 +227,6 @@ char *SDL_GetUserFolder(SDL_Folder folder)
                 *ptr = '/';
             }
         }
-        mkdir(retval, 0700);
 
         return retval;
 #endif /* SDL_PLATFORM_TVOS */

+ 12 - 1
src/filesystem/emscripten/SDL_sysfilesystem.c

@@ -97,7 +97,18 @@ char *SDL_GetUserFolder(SDL_Folder folder)
         return NULL;
     }
 
-    return SDL_strdup(home);
+    char *retval = SDL_malloc(SDL_strlen(home) + 2);
+    if (!retval) {
+        return NULL;
+    }
+
+    if (SDL_snprintf(retval, SDL_strlen(home) + 2, "%s/", home) < 0) {
+        SDL_SetError("Couldn't snprintf home path for Emscripten: %s", home);
+        SDL_free(retval);
+        return NULL;
+    }
+
+    return retval;
 }
 
 #endif /* SDL_FILESYSTEM_EMSCRIPTEN */

+ 19 - 4
src/filesystem/haiku/SDL_sysfilesystem.cc

@@ -107,15 +107,30 @@ char *SDL_GetUserFolder(SDL_Folder folder)
 
     switch (folder) {
     case SDL_FOLDER_HOME:
-        return SDL_strdup(home);
+        retval = (char *) SDL_malloc(SDL_strlen(home) + 2);
+        if (!retval) {
+            return NULL;
+        }
+
+        if (SDL_snprintf(retval, SDL_strlen(home) + 2, "%s/", home) < 0) {
+            SDL_SetError("Couldn't snprintf home path for Haiku: %s", home);
+            SDL_free(retval);
+            return NULL;
+        }
+
+        return retval;
 
         /* TODO: Is Haiku's desktop folder always ~/Desktop/ ? */
     case SDL_FOLDER_DESKTOP:
         retval = (char *) SDL_malloc(SDL_strlen(home) + 10);
+        if (!retval) {
+            return NULL;
+        }
 
-        if (retval) {
-            SDL_strlcpy(retval, home, SDL_strlen(home) + 10);
-            SDL_strlcat(retval, "/Desktop/", SDL_strlen(home) + 10);
+        if (SDL_snprintf(retval, SDL_strlen(home) + 10, "%s/Desktop/", home) < 0) {
+            SDL_SetError("Couldn't snprintf desktop path for Haiku: %s/Desktop/", home);
+            SDL_free(retval);
+            return NULL;
         }
 
         return retval;

+ 11 - 0
src/filesystem/unix/SDL_sysfilesystem.c

@@ -514,6 +514,7 @@ char *SDL_GetUserFolder(SDL_Folder folder)
 {
     const char *param = NULL;
     char *retval;
+    char *newretval;
 
     /* According to `man xdg-user-dir`, the possible values are:
         DESKTOP
@@ -594,6 +595,16 @@ char *SDL_GetUserFolder(SDL_Folder folder)
         return NULL;
     }
 
+    newretval = (char *) SDL_realloc(retval, SDL_strlen(retval) + 2);
+
+    if (!newretval) {
+        SDL_free(retval);
+        return NULL;
+    }
+
+    retval = newretval;
+    SDL_strlcat(retval, "/", SDL_strlen(retval) + 2);
+
     return retval;
 }
 

+ 13 - 0
src/filesystem/windows/SDL_sysfilesystem.c

@@ -322,6 +322,19 @@ char *SDL_GetUserFolder(SDL_Folder folder)
         }
     }
 
+    if (retval) {
+        char *newretval = (char *) SDL_realloc(retval, SDL_strlen(retval) + 2);
+
+        if (!newretval) {
+            SDL_free(retval);
+            retval = NULL; /* will be returned */
+            goto done;
+        }
+
+        retval = newretval;
+        SDL_strlcat(retval, "\\", SDL_strlen(retval) + 2);
+    }
+
 done:
     if (lib) {
         FreeLibrary(lib);

+ 2 - 0
src/filesystem/winrt/SDL_sysfilesystem.cpp

@@ -250,6 +250,8 @@ char *SDL_GetUserFolder(SDL_Folder folder)
             return NULL;
     };
 
+    wpath += L"\\";
+
     return WIN_StringToUTF8(wpath.c_str());
 }
 

+ 7 - 8
test/testdialog.c

@@ -54,7 +54,6 @@ int main(int argc, char *argv[]) {
     const SDL_FRect open_folder_rect = { 370, 50, 220, 140 };
     int i;
     char *initial_path = NULL;
-    char path_with_trailing_slash[2048];
 
     /* Initialize test framework */
     state = SDLTest_CommonCreateState(argv, 0);
@@ -94,10 +93,6 @@ int main(int argc, char *argv[]) {
 
     if (!initial_path) {
         SDL_Log("Will not use an initial path, couldn't get the home directory path: %s\n", SDL_GetError());
-        path_with_trailing_slash[0] = '\0';
-    } else {
-        SDL_snprintf(path_with_trailing_slash, sizeof(path_with_trailing_slash), "%s/", initial_path);
-        SDL_free(initial_path);
     }
 
     while (1) {
@@ -119,11 +114,11 @@ int main(int argc, char *argv[]) {
                  * - Nonzero if the user is allowed to choose multiple entries (not for SDL_ShowSaveFileDialog)
                  */
                 if (SDL_PointInRectFloat(&p, &open_file_rect)) {
-                    SDL_ShowOpenFileDialog(callback, NULL, w, filters, path_with_trailing_slash, 1);
+                    SDL_ShowOpenFileDialog(callback, NULL, w, filters, initial_path, 1);
                 } else if (SDL_PointInRectFloat(&p, &open_folder_rect)) {
-                    SDL_ShowOpenFolderDialog(callback, NULL, w, path_with_trailing_slash, 1);
+                    SDL_ShowOpenFolderDialog(callback, NULL, w, initial_path, 1);
                 } else if (SDL_PointInRectFloat(&p, &save_file_rect)) {
-                    SDL_ShowSaveFileDialog(callback, NULL, w, filters, path_with_trailing_slash);
+                    SDL_ShowSaveFileDialog(callback, NULL, w, filters, initial_path);
                 }
             }
         }
@@ -152,6 +147,10 @@ int main(int argc, char *argv[]) {
         SDL_RenderPresent(r);
     }
 
+    if (initial_path) {
+        SDL_free(initial_path);
+    }
+
     SDLTest_CleanupTextDrawing();
     SDL_DestroyRenderer(r);
     SDL_DestroyWindow(w);